Problemen met het verkrijgen van toegang tot notities of attributen van blokken of blokinstanties in VBA

Hallo, ik ben op zoek naar het lezen en bewerken van notities of attributen in VBA-blokken of instanties van blokken in SolidWorks-tekeningen.
Ik kan de blokobjecten of blokinstanties ophalen, maar na de volgende functies maak ik fouten aan:
swBlockDef.GetNotes
swBlockDef.GetNoteCount
met swBlockDef als SldWorks.BlockDefinition
of
swlockInst.GetAnnotation
swlockInst.GetAttributes
swlockInst.GetAttributeCount
swlockInst.GetAttributeValue
swlockInst.SetAttributeValue
met swlockInst als SldWorks.BlockInstance

In het verleden heb ik swBlockDef.GetNotes al met succes gebruikt, maar nu werkt het niet meer.
Heeft iemand een oplossing voor mij?
Bij voorbaat dank

Hallo en welkom;

Het zou gemakkelijker zijn als je (tussen tags) je hele macro zou posten...

Het lijkt erop dat SldWorks.BlockDefinition is verouderd sinds de versie van 2007:
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
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Het lijkt noodzakelijk om het te vervangen door:
SldWorks.SketchBlockDefinition

Met de attributen:
https://help.solidworks.com/2022/english/api/sldworksapiprogguide/Overview/Block_Definitions_and_Block_Instances.htm

Vriendelijke groeten.

Hallo

Ik gebruik SldWorks.SketchBlockDefinition en SldWorks.SketchBlockInstance
Ik kan de blok- en Blockinstance-objecten krijgen.
Het is daarna dat ik problemen heb...

Hallo

Je moet naar dit API-voorbeeld kijken: Voorbeeld van blokinformatie ophalen (VBA) - 2024 - SOLIDWORKS API Help
De noten in een blok worden benaderd in een variabele van het type variant.

Je zou deze code moeten proberen die al heel lang bestaat.
Aan mijn kant werkt het niet meer.

Dit betekent niet veel " het werkt niet meer ":

  • Heeft u foutmeldingen? Zo ja, welke + screenshot.
  • Welke veranderingen zijn er aangebracht tussen " het werkt " en " het werkt niet meer ".
  • U hebt de huidige versie van Solidworks niet opgegeven.

De macro die ik je heb voorgesteld (die dezelfde is als die in @Cyril_f ( ... vervelende kopieermachine VAS :grin:) werkt op mijn Solidworks 2022 sp4:

Hier is het resultaat...

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

Oeps, sorry. Uitgeput op dit moment, heb ik geen aandacht besteed aan de link in je antwoord.

1 like

Hallo
Hieronder staat de code die ik gebruik voor mijn tests
Wanneer vNote vNote() is als sldworks.note, komt runtime-foutcode 13 niet overeen
Wanneer vNote als variant is, is de regel vNote = swBlockDef.GetNotes geeft vNote gelijk aan leeg
En, de regel vNote = swlockInst.GetAttributes, dan foutcode ‹ - 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

Hallo
Dus veel fouten in de code.
Hieronder staat de gecorrigeerde code die zou moeten werken (werkt op 2024 SP5), afkomstig uit de API-helpcode.

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

Kortom, het declareren van variabelen die onjuist zijn:

 Dim vBlockDef()                 As SldWorks.BlockDefinition 

Variabeletype Variant en geen haakjes om op de naam van deze variabele te zetten.
Er ontbreekt een set van de swNote-variabele en vele andere.

1 like

Hallo
Je hebt gelijk over de ontbrekende sets op swNote = vNote(i)
Aan de andere kant, wanneer Dim vBlockDef als variant, krijg ik een foutmelding op de regel Set swBlockDef = vBlockDef(i), dat ben ik wanneer Dim vBlockDef() As SldWorks.BlockDefinition

Welke versie van SW?
Ik heb geen fouten op SW 2024.

De macro @Cyril_f werkt ook in Solidworks 2022.
Als je het over een fout hebt, vermeld dan het nummer (of maak een screenshot).

Ik zit in SW2022 sp5.0
Het is vreemd van mijn kant:
Als vNote als variant is, dan zijn vNote = swBlockDef.GetNotes of vNote = swlockInst.GetAttributes leeg
Wanneer vNote() Als SldWorks.Note, dan creëren dezelfde functies een runtime-fout 13: Type mismatch

We moeten kijken naar de referenties (Tools-> References).
De mijne zijn deze, maar mijn code bevat verschillende macro's die meer referenties nodig hebben dan nodig is voor de behoeften van de blokmacro.
image
Dan is een ander probleem dat mij al is overkomen, de versie van VBA die niet de juiste is en macOS-bedieningsfouten genereert

Ik heb net de test van de @Cyril_f macro op een oud bestand vóór 2007 ...
In dit geval zijn de variabelen effectief leeg.
=> In deze situatie moet u de informatie gebruiken die u in het voorbeeld heeft gegeven en die we u al twee keer hebben gepresenteerd:
https://help.solidworks.com/2022/english/api/sldworksapi/get_block_information_example_vb.htm?verRedirect=1

met:

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' 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
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Zonder je te willen beledigen, @Patrick_CHARDON , lijk je niet erg op je gemak te voelen bij variabele declaraties. Ik raad je aan om @Cyril_f te vertrouwen, bovendien werkt de macro met ons mee.
Wat wil je precies als informatie uit je bock halen, we kunnen je waarschijnlijk helpen maar als we niet echt weten wat je probeert te doen is het ingewikkeld... En nu draaien we in cirkels rond...

1 like

Hallo

Ik heb geen bestand met blokken uit 2007, dus het is moeilijk om een code te testen die het probleem zou oplossen. Ik kan echter wel een code opgeven om te testen

Hallo

Onder de te testen code werkt op blokken die zijn gemaakt op een versie hoger dan 2007, zoals uitgelegd geen foutopsporing mogelijk aan mijn kant op eerdere versies. @Maclane als je kunt testen.

    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 , je Macro lijkt zonder problemen te werken op oude blokken van voor 2007.
… Ook al is de test een beetje bevooroordeeld door het feit dat ik niet veel attributen in mijn oude blokken heb gebruikt. (Ik had op dat moment veel te veel last van Autocad's...) :sweat_smile:

Ik ben zo vrij geweest om een paar opmerkingen aan je code toe te voegen voor educatieve doeleinden: ( In werkelijkheid was het de AI " Perplexity " die het deed. En dit is het enige gebruik van AI dat ik mezelf tot nu toe toesta... En zelfs dan hallucineren ze soms ....).

' 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

Ik ben zo vrij geweest om de code in beide berichten aan te passen omdat ik me realiseerde dat de laatste regel nutteloos was (ik was in het begin met een ander idee begonnen en ik heb nagelaten te verwijderen wat niet langer nuttig was).
Bedankt voor de test en de toevoeging van opmerkingen (ik geef toe dat ik niet al te veel commentaar meer geef op mijn codes omdat ik de enige ben die codeert in mijn bedrijf)
@Patrick_CHARDON , het is aan jou

2 likes