Problems accessing notes or attributes of blocks or block instances in VBA

Hello, I'm looking to read and edit notes or attributes in VBA blocks or instances of blocks in SolidWorks drawings.
I can retrieve the block objects or block instances, but after the following functions I create errors:
swBlockDef.GetNotes
swBlockDef.GetNoteCount
with swBlockDef as SldWorks.BlockDefinition
or
swlockInst.GetAnnotation
swlockInst.GetAttributes
swlockInst.GetAttributeCount
swlockInst.GetAttributeValue
swlockInst.SetAttributeValue
with swlockInst as SldWorks.BlockInstance

In the past, I have already used swBlockDef.GetNotes successfully, but now, it doesn't work anymore.
Does anyone have a solution for me?
Thanks in advance

Hello and welcome;

It would be easier if you posted (between tags) your entire macro...

It seems that SldWorks.BlockDefinition is deprecated since the 2007 version:
image

https://help.solidworks.com/2022/english/api/sldworksapi/get_block_information_example_vb.htm?verRedirect=1

extract:

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' OLD BLOCKS: Obsolete and not supported block
    '             interfaces as of SOLIDWORKS 2007
    'Dim swBlockDef                  As SldWorks.BlockDefinition
    'Dim swBlockInst                 As SldWorks.BlockInstance
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' NEW BLOCKS: New block interfaces as of SOLIDWORKS 2007
    Dim swBlockDef                  As SldWorks.SketchBlockDefinition
    Dim swBlockInst                 As SldWorks.SketchBlockInstance
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

It seems necessary to replace it with:
SldWorks.SketchBlockDefinition

with the attributes:
https://help.solidworks.com/2022/english/api/sldworksapiprogguide/Overview/Block_Definitions_and_Block_Instances.htm

Kind regards.

Hello

I use SldWorks.SketchBlockDefinition and SldWorks.SketchBlockInstance
I can get the block and Blockinstance objects.
It's after that that I have problems...

Hello

You have to look at this API example: Get Block Information Example (VBA) - 2024 - SOLIDWORKS API Help
The notes contained in a block are accessed in a variable of type variant.

You should try this code that has been around for a very long time.
On my side, it doesn't work anymore.

This doesn't mean much " it doesn't work anymore ":

  • Have error messages? If yes, which ones + screenshot.
  • What changes have been made between " it works " and " it doesn't work anymore ".
  • You did not specify the current version of Solidworks.

The macro I proposed to you (which is the same as the one in @Cyril_f ( ... nasty copier VAS :grin:) works on my Solidworks 2022 sp4:

Here is the result...

File = XXXXXXctif_Brosses.SLDDRW
      Block definition linked to file? Faux
         File name: 

  Name of block instance: Orientation-3
    Block instance(0):
      Angle            = 0 deg
      Scale            = 0,7
      TextDisplay      = 3
  ------------------------------------
      Block definition linked to file? Faux
         File name: 

  Name of block instance: logo revtech-3
    Block instance(0):
      Angle            = 0 deg
      Scale            = 0,7
      TextDisplay      = 3
  ------------------------------------
1 Like

Oops, sorry. Exhausted at the moment, I didn't pay attention to the link in your reply.

1 Like

Hello
Below is the code I use for my tests
When vNote is vNote() as sldworks.note, then runtime error code 13 type mismatch
When vNote as variant, the line vNote = swBlockDef.GetNotes gives vNote equals empty
And, the line vNote = swlockInst.GetAttributes, then error code ‹ - 670099352 (d80f1868) ›: Error Automation

Sub main()
    Dim swApp                       As SldWorks.SldWorks
    Dim swModel                     As SldWorks.ModelDoc2
    Dim SwSketchMgr                 As SldWorks.SketchManager
    Dim vBlockDef()                 As SldWorks.BlockDefinition
    Dim swBlockDef                  As SldWorks.BlockDefinition
    Dim vBlockInst()                As SldWorks.BlockInstance
    Dim swlockInst                  As SldWorks.BlockInstance
    Dim vNote                       As Variant
    'Dim vNote()                     As SldWorks.Note
    Dim swNote                      As SldWorks.Note
    Dim i                           As Long
    Dim j                           As Long
    Dim k                           As Long
    Dim Text                        As String
    
    Set swApp = CreateObject("SldWorks.Application")
    Set swModel = swApp.ActiveDoc
    Set SwSketchMgr = swModel.SketchManager
    vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
    
    If Not IsEmpty(vBlockDef) Then
        For i = 0 To UBound(vBlockDef)
            Set swBlockDef = vBlockDef(i)
            
            Text = swBlockDef.Name
            
            vNote = swBlockDef.GetNotes   'vide ou erreur
            
            If Not IsEmpty(vNote) Then
                For j = 0 To UBound(vNote)
                    swNote = vNote(j)
                    Text = swNote.GetText
                Next
            End If
            
            vBlockInst = swBlockDef.GetInstances
            
            If Not IsEmpty(vBlockInst) Then
                For j = 0 To UBound(vBlockInst)
                    Set swlockInst = vBlockInst(j)
                    
                    Text = swlockInst.Name
                    vNote = swlockInst.GetAttributes  'Erreur d'exécution '-670099352 (d80f1868)': Erreur Automation
                    If Not IsEmpty(vNote) Then
                        For k = 0 To UBound(vNote)
                            Set swNote = vNote(k)
                            Text = swNote.TagName
                            
                        Next
                    End If
                Next
            End If
        Next i
    End If
End Sub

Hello
So a lot of errors in the code.
Below is the corrected code that should work (works on 2024 SP5), taken from the API help code.

Sub main()
    Dim swApp                       As SldWorks.SldWorks
    Dim swModel                     As SldWorks.ModelDoc2
    Dim SwSketchMgr                 As SldWorks.SketchManager
    Dim vBlockDef                   As Variant
    Dim swBlockDef                  As SldWorks.SketchBlockDefinition
    Dim vBlockInst                  As Variant
    Dim swBlockInst                 As SldWorks.SketchBlockInstance
    Dim vNote                       As Variant
    Dim swNote                      As SldWorks.Note
    Dim i                           As Long
    Dim j                           As Long
    Dim k                           As Long
    Dim Text                        As String
    
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    Set SwSketchMgr = swModel.SketchManager
    vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
    
    If Not IsEmpty(vBlockDef) Then
        For i = 0 To UBound(vBlockDef)
            Set swBlockDef = vBlockDef(i)
            
            vNote = swBlockDef.GetNotes   'vide ou erreur
            
            If Not IsEmpty(vNote) Then
                For j = 0 To UBound(vNote)
                    Set swNote = vNote(j)
                    Text = swNote.GetText
                Next
            End If
            
            vBlockInst = swBlockDef.GetInstances
            
            If Not IsEmpty(vBlockInst) Then
                For j = 0 To UBound(vBlockInst)
                    Set swBlockInst = vBlockInst(j)
                    
                    Text = swBlockInst.Name
                    vNote = swBlockInst.GetAttributes
                    If Not IsEmpty(vNote) Then
                        For k = 0 To UBound(vNote)
                            Set swNote = vNote(k)
                            Text = swNote.TagName
                            
                        Next
                    End If
                Next
            End If
        Next i
    End If
End Sub

Basically, declaring variables that are incorrect:

 Dim vBlockDef()                 As SldWorks.BlockDefinition 

Variable type Variant and no parentheses to put on the name of this variable.
Missing a set of the swNote variable and many others.

1 Like

Hello
You're right about the missing sets on swNote = vNote(i)
On the other hand, when Dim vBlockDef As Variant, I get an error at the line Set swBlockDef = vBlockDef(i), that I am when Dim vBlockDef() As SldWorks.BlockDefinition

Which version of SW?
I have no mistakes on SW 2024.

The @Cyril_f macro also works in Solidworks 2022.
When you talk about an error, please indicate its number (or take a screenshot).

I'm in SW2022 sp5.0
It's strange from my side:
When vNote as variant, then vNote = swBlockDef.GetNotes or vNote = swlockInst.GetAttributes are empty
When vNote() As SldWorks.Note, then the same functions create a runtime error 13: Type mismatch

We should look at the references (Tools-> References).
Mine are these, but my code contains different macros that need more references than necessary for the needs of the block macro.
image
Then another problem that has already happened to me is the version of VBA which is not the right one and generates macOS operating errors

I just did the test of the @Cyril_f macro on an old file before 2007...
In this case, the variables are effectively empty.
=> In this situation you have to use the information provided in the example that we have already presented to you twice:
https://help.solidworks.com/2022/english/api/sldworksapi/get_block_information_example_vb.htm?verRedirect=1

with:

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' OLD BLOCKS: Obsolete and not supported block
    '             interfaces as of SOLIDWORKS 2007
    'Dim swBlockDef                  As SldWorks.BlockDefinition
    'Dim swBlockInst                 As SldWorks.BlockInstance
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' NEW BLOCKS: New block interfaces as of SOLIDWORKS 2007
    Dim swBlockDef                  As SldWorks.SketchBlockDefinition
    Dim swBlockInst                 As SldWorks.SketchBlockInstance
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Without wanting to offend you, @Patrick_CHARDON , you don't seem very comfortable with variable declarations. I recommend that you trust @Cyril_f, moreover its macro works with us.
What do you want to get as information from your bock exactly, we can probably help you but if we don't really know what you're trying to do it's complicated... And now we're going around in circles...

1 Like

Hello

I don't have a file with blocks dating from 2007 so it's difficult to test a code that would solve the problem. I can, however, provide a code for testing

Hello

Below the code to be tested, works on blocks created on a version higher than 2007, as explained no debugging possible on my side on previous versions. @Maclane if you can test.

    Dim swApp                       As SldWorks.SldWorks
    Dim swModel                     As SldWorks.ModelDoc2
    Dim swDraw                      As SldWorks.DrawingDoc
    Dim SwSketchMgr                 As SldWorks.SketchManager
    Dim vBlockDef                   As Variant
    Dim swBlockDef                  As SldWorks.SketchBlockDefinition
    Dim OldSwBlockDef               As SldWorks.BlockDefinition
    Dim vBlockInst                  As Variant
    Dim swBlockInst                 As SldWorks.SketchBlockInstance
    Dim OldSwBlockInst              As SldWorks.BlockInstance
    Dim vNote                       As Variant
    Dim swNote                      As SldWorks.Note
    Dim bOldBlock                   As Boolean
    Dim i                           As Long
    Dim j                           As Long
    Dim k                           As Long
    Dim Text                        As String
Sub main()
    
    Set swApp = Application.SldWorks
    bOldBlock = False
    Set swModel = swApp.ActiveDoc
    Set swDraw = swModel
    Set SwSketchMgr = swModel.SketchManager
    vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
    If IsEmpty(vBlockDef) Then
        vBlockDef = swDraw.GetBlockDefinitions
        bOldBlock = True
    End If
    If Not IsEmpty(vBlockDef) Then
        For i = 0 To UBound(vBlockDef)
            If Not bOldBlock Then
                Set swBlockDef = vBlockDef(i)
                vNote = swBlockDef.GetNotes
                vBlockInst = swBlockDef.GetInstances
            Else
                Set OldSwBlockDef = vBlockDef(i)
                vNote = OldSwBlockDef.GetNotes
                vBlockInst = OldSwBlockDef.GetBlockInstances
            End If
            If Not IsEmpty(vNote) Then
                For j = 0 To UBound(vNote)
                    Set swNote = vNote(j)
                    Text = swNote.GetText
                    Debug.Print Text
                Next
            End If
            
            If Not IsEmpty(vBlockInst) Then
                For j = 0 To UBound(vBlockInst)
                    If Not bOldBlock Then
                        Set swBlockInst = vBlockInst(j)
                        Text = swBlockInst.Name
                        Debug.Print Text
                        vNote = swBlockInst.GetAttributes
                    Else
                        Set OldSwBlockInst = vBlockInst(j)
                        Text = OldSwBlockDef.Name
                        Debug.Print Text
                        vNote = OldSwBlockInst.GetAttributes
                    End If
                    If Not IsEmpty(vNote) Then
                        For k = 0 To UBound(vNote)
                            Set swNote = vNote(k)
                            Text = swNote.TagName
                            Debug.Print Text
                        Next
                    End If
                Next
            End If
        Next i
    End If
End Sub

1 Like

@Cyril_f , your Macro seems to work without problems on old blocks before 2007.
… Even if the test is a bit biased by the fact that I didn't use many attributes in my old blocks. (I had suffered way too much with Autocad's at the time...) :sweat_smile:

I took the liberty of adding a few comments to your code for educational purposes: ( In reality it was the AI " Perplexity " that did it. And this is the only use of AI that I allow myself to date... and even then they sometimes hallucinate ... ).

' Déclaration des variables liées à l'API SolidWorks
Dim swApp                       As SldWorks.SldWorks                  ' Objet principal de l'application SolidWorks
Dim swModel                     As SldWorks.ModelDoc2                 ' Document actif (pièce, assemblage ou mise en plan)
Dim swDraw                      As SldWorks.DrawingDoc                ' Document de type mise en plan
Dim SwSketchMgr                 As SldWorks.SketchManager             ' Gestionnaire des esquisses
Dim vBlockDef                   As Variant                            ' Tableau/variant contenant les définitions de blocs
Dim swBlockDef                  As SldWorks.SketchBlockDefinition     ' Définition d’un bloc (mode SketchManager)
Dim OldSwBlockDef               As SldWorks.BlockDefinition           ' Définition d’un bloc (ancienne interface)
Dim vBlockInst                  As Variant                            ' Tableau/variant contenant les instances de blocs
Dim swBlockInst                 As SldWorks.SketchBlockInstance       ' Instance d’un bloc (mode SketchManager)
Dim OldSwBlockInst              As SldWorks.BlockInstance             ' Instance d’un bloc (ancienne interface)
Dim vNote                       As Variant                            ' Tableau/variant contenant les notes
Dim swNote                      As SldWorks.Note                      ' Objet note (annotation textuelle)
Dim bOldBlock                   As Boolean                            ' Indicateur : True si bloc utilisant l'ancienne API
Dim i                           As Long                               ' Compteur boucle externe
Dim j                           As Long                               ' Compteur boucle intermédiaire
Dim k                           As Long                               ' Compteur boucle interne
Dim Text                        As String                             ' Chaîne temporaire pour stocker du texte

Sub main()
    
    ' Récupère l'instance active de SolidWorks
    Set swApp = Application.SldWorks
    
    ' Par défaut, on suppose qu’on utilise la nouvelle API (pas de vieux blocs)
    bOldBlock = False
    
    ' Récupère le document actif dans SolidWorks
    Set swModel = swApp.ActiveDoc
    
    ' Force la variable swDraw à être le document actif considéré comme un DrawingDoc
    Set swDraw = swModel
    
    ' Récupère le gestionnaire d’esquisse (permet d’accéder aux blocs d’esquisse)
    Set SwSketchMgr = swModel.SketchManager
    
    ' Tente de récupérer les définitions de blocs "nouvelle API" via le SketchManager
    vBlockDef = SwSketchMgr.GetSketchBlockDefinitions
    
    ' Si aucune définition trouvée, on essaie via l’ancienne méthode pour les mises en plan
    If IsEmpty(vBlockDef) Then
        vBlockDef = swDraw.GetBlockDefinitions
        bOldBlock = True  ' Utilisation de l’ancienne API détectée
    End If
    
    ' Vérifie si on a bien trouvé au moins une définition de bloc
    If Not IsEmpty(vBlockDef) Then
        
        ' Parcourt l'ensemble des définitions de blocs récupérées
        For i = 0 To UBound(vBlockDef)
            
            ' En fonction du type de bloc (nouveau ou ancien), on caste dans le bon objet
            If Not bOldBlock Then
                Set swBlockDef = vBlockDef(i)             ' Définition de bloc "nouvelle API"
                vNote = swBlockDef.GetNotes               ' Récupère toutes les notes associées à ce bloc
                vBlockInst = swBlockDef.GetInstances      ' Récupère toutes ses instances
            Else
                Set OldSwBlockDef = vBlockDef(i)           ' Définition de bloc "ancienne API"
                vNote = OldSwBlockDef.GetNotes
                vBlockInst = OldSwBlockDef.GetBlockInstances
            End If
            
            ' ----- TRAITEMENT DES NOTES ASSOCIÉES AU BLOC -----
            If Not IsEmpty(vNote) Then
                For j = 0 To UBound(vNote)
                    Set swNote = vNote(j)
                    Text = swNote.GetText                  ' Récupère le texte complet de la note
                    Debug.Print Text                       ' Affiche dans la fenêtre d’exécution VBA
                Next
            End If
            
            ' ----- TRAITEMENT DES INSTANCES DE BLOCS -----
            If Not IsEmpty(vBlockInst) Then
                For j = 0 To UBound(vBlockInst)
                    
                    If Not bOldBlock Then
                        Set swBlockInst = vBlockInst(j)     ' Instance (nouvelle API)
                        Text = swBlockInst.Name
                        Debug.Print Text
                        vNote = swBlockInst.GetAttributes   ' Récupère les attributs (métadonnées) de l’instance
                    Else
                        Set OldSwBlockInst = vBlockInst(j)  ' Instance (ancienne API)
                        Text = OldSwBlockDef.Name           ' ? Ici : on affiche le nom de la définition, pas de l’instance
                        Debug.Print Text
                        vNote = OldSwBlockInst.GetAttributes
                    End If
                    
                    ' ----- TRAITEMENT DES ATTRIBUTS DE L’INSTANCE -----
                    If Not IsEmpty(vNote) Then
                        For k = 0 To UBound(vNote)
                            Set swNote = vNote(k)           ' Ici, un "attribut" est représenté comme un objet Note/Annotation
                            Text = swNote.TagName           ' Récupère le nom de balise (TagName) de l’attribut
                            Debug.Print Text
                        Next
                    End If
                    
                Next
            End If
        Next i
    End If
End Sub
1 Like

I took the liberty of modifying the code in both messages because I realized that the last line was useless (I had started with another idea at the beginning and I omitted to delete what was no longer useful).
Thank you for the test and the addition of comments (I admit that I don't comment too much on my codes anymore since I'm the only one to code in my company)
@Patrick_CHARDON , it's up to you

2 Likes