Access Topic Custom Properties programatically

eamonnedwardo shared this question 8 months ago
Discussion Open

Hi fellow Mindjetters,

I've imported a spreadsheet and added a custom property called 'Keywords' that contains a comma seperated list of Keywords.

I'm now trying to get a Macro to traverse the Map and add the 'Keywords' as Map Markers. I have everything in place except extracting from the Custom Property. Could anyone point me to the correct syntax?

Thanks!

If m_Topic.CustomProperties.Exists("Keywords") Then Keywords = Split(m_Topic.CustomProperties.Item("Keywords").Value, ",") For Each Keyword In Keywords Keyword = Trim(Keyword) If Not IsKeywordAdded(Keyword, mMarkerGrps) Then mMarkerGrps.AddTextLabelMarkerGroup(Keyword) End If Next End If

Best Answer
photo

Hello

As far as I know, the custom property collection does not support access to items by name. You need to find properties by iterating. Sorry, the message board does not paste macro code directly, and strips indentation :(

'#Language "WWB-COM"

Option Explicit

Sub Main
Dim m_Topic As Topic
Dim m_Property As CustomProperty

Set m_Topic = ActiveDocument.Selection.PrimaryTopic
If TopicFindCustomProperty(m_Topic, "Fruit", m_Property) Then
MsgBox(CStr(m_Property.DisplayValue))
End If
End Sub

Function TopicFindCustomProperty(ByVal m_Topic As Topic, ByVal s_Name As String, ByRef m_Property As CustomProperty) As Boolean
Dim m_CP As CustomProperty

TopicFindCustomProperty = False
If m_Topic.DataContainer.DataContainerType = mmDataContainerTypeCustomProperties Then
For Each m_CP In m_Topic.DataContainer.CustomProperties.CustomPropertyCollection
If m_CP.CustomPropertyName = s_Name Then
Set m_Property = m_CP
Return True
End If
Next
End If

End Function

Replies (2)

photo
2

Hello

As far as I know, the custom property collection does not support access to items by name. You need to find properties by iterating. Sorry, the message board does not paste macro code directly, and strips indentation :(

'#Language "WWB-COM"

Option Explicit

Sub Main
Dim m_Topic As Topic
Dim m_Property As CustomProperty

Set m_Topic = ActiveDocument.Selection.PrimaryTopic
If TopicFindCustomProperty(m_Topic, "Fruit", m_Property) Then
MsgBox(CStr(m_Property.DisplayValue))
End If
End Sub

Function TopicFindCustomProperty(ByVal m_Topic As Topic, ByVal s_Name As String, ByRef m_Property As CustomProperty) As Boolean
Dim m_CP As CustomProperty

TopicFindCustomProperty = False
If m_Topic.DataContainer.DataContainerType = mmDataContainerTypeCustomProperties Then
For Each m_CP In m_Topic.DataContainer.CustomProperties.CustomPropertyCollection
If m_CP.CustomPropertyName = s_Name Then
Set m_Property = m_CP
Return True
End If
Next
End If

End Function

photo
2

Thank you very very much Nick. I'd be still looking for it!

Warm regards

/Eamonn

I'll leave the completed Macro here should anyone find it useful. The original Excel table had 5 columns for Keywords, that were consolidated to a single column using the Excel function '=TEXTJOIN(", ", TRUE, A2, B2, C2, D2, E2)' to create a comma separated list that was imported as a Topic Property. Then the following can be executed.

<pre>'#Language "WWB-COM"

' Title: Add Keywords as Topic Markers and Child Topics in 'Extracted Keywords' Map Group

Global mExtractedKeywordsGroup As MapMarkerGroup

Sub Main
    Dim m_Topic As Topic

    If Not (ActiveDocument Is Nothing) Then
        ' Ensure or create the 'Extracted Keywords' group first
        EnsureMapGroupExists()
        ' Process topics
        If ActiveDocument.Selection.HasTopic Then
            For Each m_Topic In ActiveDocument.Selection
                AddKeywordsAsMarkersAndIndex(m_Topic)
            Next
        Else
            Set m_Topic = ActiveDocument.CentralTopic
            AddKeywordsAsMarkersAndIndex(m_Topic)
        End If
    End If
End Sub

Sub AddKeywordsAsMarkersAndIndex(ByVal m_Topic As Topic)
    Dim m_SubTopic As Topic
    Dim m_Property As CustomProperty
    Dim Keywords() As String
    Dim Keyword As Variant

    ' Check and process the 'Keywords' custom property for the current topic
    If TopicFindCustomProperty(m_Topic, "Keywords", m_Property) Then
        Keywords = Split(m_Property.DisplayValue, ",")
        For Each Keyword In Keywords
            Keyword = Trim(Keyword)
            ' Add marker or label based on Keyword
            m_Topic.TextLabels.AddTextLabel(Keyword, False)
            ' Add keyword as child to 'Extracted Keywords' group
            AddKeywordToExtractedKeywordsGroup(Keyword)
        Next
    End If

    ' Recursively process subtopics
    For Each m_SubTopic In m_Topic.SubTopics
        AddKeywordsAsMarkersAndIndex(m_SubTopic)
    Next
End Sub

Sub EnsureMapGroupExists()
    Dim mMarkerGrps As MapMarkerGroups
    Dim GroupExists As Boolean
    GroupExists = False

    Set mMarkerGrps = ActiveDocument.MapMarkerGroups
    ' Check if the 'Extracted Keywords' group already exists
    For Each mMarkerGrp In mMarkerGrps
        If mMarkerGrp.Name = "Extracted Keywords" Then
            Set mExtractedKeywordsGroup = mMarkerGrp ' Correctly assign the existing group to the global variable
            GroupExists = True
            Exit For
        End If
    Next
    ' If the group doesn't exist, create it and assign it to the global variable
    If Not GroupExists Then
        Set mExtractedKeywordsGroup = mMarkerGrps.AddTextLabelMarkerGroup("Extracted Keywords")
    End If
End Sub

Sub AddKeywordToExtractedKeywordsGroup(ByVal Keyword As String)
    ' This subroutine attempts to add each keyword as a child marker to the 'Extracted Keywords' group
    ' and gracefully handles any errors, assuming they may be due to duplicates.
    On Error Resume Next ' Ignore errors and continue execution
    If Not mExtractedKeywordsGroup Is Nothing Then
        mExtractedKeywordsGroup.AddTextLabelMarker(Keyword)
    End If
    On Error GoTo 0 ' Turn back on normal error handling
End Sub



Function TopicFindCustomProperty(ByVal m_Topic As Topic, ByVal s_Name As String, ByRef m_Property As CustomProperty) As Boolean
    Dim m_CP As CustomProperty

    TopicFindCustomProperty = False
    If m_Topic.DataContainer.DataContainerType = mmDataContainerTypeCustomProperties Then
        For Each m_CP In m_Topic.DataContainer.CustomProperties.CustomPropertyCollection
            If m_CP.CustomPropertyName = s_Name Then
                Set m_Property = m_CP
                TopicFindCustomProperty = True
                Exit Function
            End If
        Next
    End If
End Function
</pre>

photo
1

Well done Eamonn. Nice clear coding :-)

photo
2

This looks great, but for the poor macro writers among us (ie, me), you can do this fairly easily using SmartRules rather than a macro.

First, create the tag group, then set up the SmartRules. Each of these will use the relevant keyword as a trigger to add the appropriate marker to each topic.

photo
1

Hello Alex - as far as I know, Topic Properties are not included in the SmartRules triggers. The macro is reading custom properties, creating tags then assigning them. I don't think SmartRules can use properties this way.

photo
2

Hi Nick, actually they are, though they appear as a trigger only if there are any topic properties in the map. SmartRules can read both numeric and non-numeric properties, as shown in the following example:

1774d686fdbd7e1b8d95f5c77a8e03e5

The following shows the text tags applied when this and two other SmartRules using the other topic property keywords are added:

7f80d5560d644fbf5bc8f2adc52b0f25

photo
1

Thanks Alex, I stand corrected! So in some cases you can't create a SmartRule in advance unless the conditions for it already exist.

This is similar to the Power Filter where you can only create a filter if the markers of interest are already present in the map. I expect the intention was to simplify things, but it creates confusion instead :-)

photo
2

Hi Nick,

Yes, the same thing applies to Properties as an Effect - they only appear as an Effect option if there are already topic properties in the map.

On the trigger side, the only other topic attribute treated this way appears to be Topic Style, but at least this is documented in the online help. The role of topic properties both as a Trigger and an Effect is completely undocumented, so it's hardly surprising that people aren't aware of this facility. Of course there's no way of knowing if there are other triggers or effects (beyond the default set which appear in SmartRules) that behave this way without experimenting with the full range of topic attributes.

I will raise the need for the role of topic properties in SmartRules to be properly documented in the online help as an idea on this forum.

---