Fallen
Fallen

Reputation: 37

Fill shape data field from external data

I'm trying to link shape data field from external data like excel. As @JohnGoldsmith suggested I used DropLinked but "I'm getting object name not found" error. My main agenda is drop multiple shapes on drawing with shape data field "Name", then fill all the shape data field using external data in order. I also used spatial search for dropping shapes on drawing(Thanks to @Surrogate). By the way I'm using Visio Professional 2019. enter image description here

Upvotes: 0

Views: 323

Answers (1)

JohnGoldsmith
JohnGoldsmith

Reputation: 2698

It's often a good plan to separate chained members so you can identify whether (as @Paul points out) you're having a problem getting to the stencil or the master.

Following is a modified example of link shapes to data. I've ditched all of the spatial search stuff as I think that's a separate issue. If you still have trouble with that I would ask another question and narrow your sample code to not include the data linking part - ie just drop shapes and try and change their position. Bear in mind there's also Page.Layout and Selection.Layout

I think you've got the adding the DataRecordsets in the other linked question, so this example makes the following assumptions:

  • You have a drawing document open
  • You have the "Basic Shapes" stencil open (note my version is metric "_M")
  • You have a DataRecordset applied to the document named "AllNames"
  • The above record set has a column named "Name" that contains the data you want to link

Names DataRecordset

Public Sub ModifiedDropLinked_Example()
    
    Const RECORDSET_NAME = "AllNames"
    Const COL_NAME = "Name"
    Const STENCIL_NAME = "BASIC_M.vssx"
    Const MASTER_NAME = "Rectangle"
    
    Dim vDoc As Visio.Document
    Set vDoc = Application.ActiveDocument
    
    
    Dim vPag As Visio.Page
    Set vPag = Application.ActivePage
    
    Dim vShp As Visio.Shape
    Dim vMst As Visio.Master
    Dim x As Double
    Dim y As Double
    Dim xOffset As Double
    Dim dataRowIDs() As Long
    Dim row As Long
    Dim col As Long
    Dim rowData As Variant
    Dim recordset As Visio.DataRecordset
    Dim recordsetCount As Integer
         
    For Each recordset In vDoc.DataRecordsets
        If recordset.Name = RECORDSET_NAME Then
            dataRowIDs = recordset.GetDataRowIDs("")
            
            xOffset = 2
            x = 0
            y = 2
            
            Dim vStencil As Visio.Document
            Set vStencil = TryFindDocument(STENCIL_NAME)
            If Not vStencil Is Nothing Then
                Set vMst = TryFindMaster(vStencil, MASTER_NAME)
                If Not vMst Is Nothing Then
                    For row = LBound(dataRowIDs) + 1 To UBound(dataRowIDs) + 1
                        rowData = recordset.GetRowData(row)
            
                        For col = LBound(rowData) To UBound(rowData)
                            Set vShp = vPag.DropLinked(vMst, x + (xOffset * row), y, recordset.ID, row, False)
                            Debug.Print "Linked shape ID " & vShp.ID & " to row " & row & " (" & rowData(col) & ")"
                        Next col
                    Next row
                Else
                    Debug.Print "Unable to find master '" & MASTER_NAME & "'"
                End If
            Else
                Debug.Print "Unable to find stencil '" & STENCIL_NAME & "'"
            End If
        Else
            Debug.Print "Unable to find DataRecordset '" & RECORDSET_NAME & "'"
        End If
    Next
         
    End Sub
    
    Private Function TryFindDocument(docName As String) As Visio.Document
        Dim vDoc As Visio.Document
        For Each vDoc In Application.Documents
            If StrComp(vDoc.Name, docName, vbTextCompare) = 0 Then
                Set TryFindDocument = vDoc
                Exit Function
            End If
        Next
        Set TryFindDocument = Nothing
    End Function
    
    Private Function TryFindMaster(ByRef vDoc As Visio.Document, mstNameU As String) As Visio.Master
        Dim vMst As Visio.Master
        For Each vMst In vDoc.Masters
            If StrComp(vMst.NameU, mstNameU, vbTextCompare) = 0 Then
                Set TryFindMaster = vMst
                Exit Function
            End If
        Next
        Set TryFindMaster = Nothing
    End Function 

The above code drops six shapes onto the page and adds a Shape Data row (Prop._VisDM_Name) with the corresponding data value. If you want the name text to appear in the shape then you would normally modify the master with an inserted field in the shape's text. (If you get stuck with this part then ask another question.)

One last point is that this example loops through the DataRecordset rows dropping a shape for each one, but there is also a Page.DropManyLinkedU method that allows you to this en masse.

Upvotes: 1

Related Questions