Problèmes pour accéder aux notes ou aux attributs des blocks ou instance de blocks en VBA

Bonjour, je cherches à lire et modifier les notes ou les attributs dans les blocks ou instances de blocks en VBA dans les mise en plan SolidWorks.
J’arrive a récupérer les objets block ou instance de block, mais après les fonctions ci-dessous me crée des erreurs :
swBlockDef.GetNotes
swBlockDef.GetNoteCount
avec swBlockDef as SldWorks.BlockDefinition
ou
swlockInst.GetAnnotation
swlockInst.GetAttributes
swlockInst.GetAttributeCount
swlockInst.GetAttributeValue
swlockInst.SetAttributeValue
avec swlockInst as SldWorks.BlockInstance

Au par avant, j’ai déjà utilisé swBlockDef.GetNotes avec succès, mais la, cela ne fonctionne plus.
Quelqu’un aurait-il une solution à me proposer?
Merci d’avance

Bonjour et bienvenue;

Ce serait plus simple si vous postiez (entre balises) l’ensemble de votre macro…

Il semble que SldWorks.BlockDefinition soit obsolète depuis la version de 2007:
image

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

extrait:

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

il semble nécessaire de le remplacer par:
SldWorks.SketchBlockDefinition

avec les attributs:
https://help.solidworks.com/2022/english/api/sldworksapiprogguide/Overview/Block_Definitions_and_Block_Instances.htm

Cordialement.

Bonjour,

J’utilise bien SldWorks.SketchBlockDefinition et SldWorks.SketchBlockInstance
J’arrive bien a avoir les objets block et Blockinstance.
C’est après que j’ai des problèmes…

Bonjour,

Il faut regarder cet exemple de l’API: Get Block Information Example (VBA) - 2024 - SOLIDWORKS API Help
L’accès aux notes contenues dans un bloc se fait dans une variable de type variant.

Vous devriez essayer ce code qui existe depuis fort longtemps.
De mon coté, il ne fonctionne plus.

Cela ne veux pas dire grand chose « il ne fonctionne plus »:

  • Vous avez des messages d’erreurs ? Si oui lesquels + capture ecran.
  • Quels changements ont été realisé entre le « il fonctionne » et le « il ne fonctionne plus ».
  • Vous n’avez pas précisé la version de Solidworks en cours.

La macro que je vous ai proposé (qui est la même que celle de @Cyril_f ( … vilain copieur vas :grin:) fonctionne sur mon Solidworks 2022 sp4:

Voici le résultat…

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 « J'aime »

Oups, désolé. Crevé en ce moment, je n’ai pas fait attention au lien présent dans ta réponse.

1 « J'aime »

Bonjour,
Vous trouverez ci-dessous le code que j’utilise pour mes test
Quand vNote est vNote() as sldworks.note, alors code erreur d’exécution 13 incompatibilité de type
Quand vNote as variant, la ligne vNote = swBlockDef.GetNotes donne vNote égale vide
Et, la ligne vNote = swlockInst.GetAttributes, alors code erreur ‹ -670099352 (d80f1868) ›: Erreur 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

Bonjour,
Alors pas mal d’erreurs dans le code.
Ci-dessous le code corrigé qui devrait fonctionner (fonctionne sur 2024 SP5), repris à partir du code de l’aide API.

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

En gros, déclaration des variables qui sont incorrectes :

 Dim vBlockDef()                 As SldWorks.BlockDefinition 

Variable de type Variant et pas de parenthèses à mettre sur le nom de cette variable.
Manque un Set de la variable swNote et bien d’autres.

1 « J'aime »

Bonjour,
Vous avez raison pour les set manquant sur swNote = vNote(i)
Par contre quand Dim vBlockDef As Variant, j’ai une erreur à la ligne Set swBlockDef = vBlockDef(i), que je n’est quand Dim vBlockDef() As SldWorks.BlockDefinition

Quelle version de SW?
Je n’ai aucune erreur sur SW 2024.

La macro de @Cyril_f fonctionne aussi sous Solidworks 2022.
Quand tu parle d’erreur, merci d’indiquer son numéro (ou de faire une capture écran).

Je suis en SW2022 sp5.0
C’est étrange de mon coté:
Quand vNote as variant, alors vNote = swBlockDef.GetNotes ou vNote = swlockInst.GetAttributes sont vide
Quand vNote() As SldWorks.Note, alors les mêmes fonction créent une erreur d’exécution 13 : Incompatibilité de type

Il faudrait regarder du côté des références (Outils-> Références).
Les miennes sont celles-ci mais mon code contient différentes macros qui ont besoin de plus de références que nécessaire pour le besoin de la macro des blocs.
image
Ensuite autre problème qui m’est déjà arrivé, c’est la version de VBA qui n’est pas la bonne et génère des erreurs de fonctionnement des macos

Je viens de faire le teste de la macro de @Cyril_f sur un vieux fichier antérieur à 2007…
Dans ce cas les variables sont effectivement vides.
=> Dans cette situation il faut utiliser les informations fournies dans l’exemple que nous t’avons présenté déjà deux fois:
https://help.solidworks.com/2022/english/api/sldworksapi/get_block_information_example_vb.htm?verRedirect=1

avec:

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

Sans vouloir te vexer, @Patrick_CHARDON , tu ne semble pas très à l’aise avec les déclarations de variables. Je te recommande de te fier à @Cyril_f, d’ailleur sa macro fonctionne chez nous.
Que veux-tu obtenir comme informations de tes bock exactement, nous pouvons sans doutes t’aider mais si on ne sait pas vraiment ce que tu cherche à faire c’est compliqué… Et là on tourne en rond…

1 « J'aime »

Bonjour,

Je n’ai pas de fichier avec des blocs datant de la 2007 donc difficile de tester un code qui réglerait le problème. Je peux toutefois fournir un code pour test

Bonjour,

Ci-dessous le code à tester, fonctionne sur les blocs créés sur une version supérieure à 2007, comme expliqué pas de débugge possible de mon côté sur des versions antérieures. @Maclane si tu peux tester.

    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 « J'aime »

@Cyril_f , Ta Macro semble fonctionner sans problèmes sur des vieux bloc antérieurs à 2007.
… Même si le test est un peu biaisé par le fait que je n’utilisai pas beaucoup d’attributs dans mes bloc de l’ancien temps. (J’avais beaucoup trop souffert avec ceux d’Autocad à l’époque… :sweat_smile:.)

Je me suis permis d’ajouter quelques commentaires à ton code dans un but pédagogique : ( En réalité c’est l’ IA « Perplexity » qui l’a fait. Et c’est bien la seule utilisation d’ IA que je me permet à ce jour …et même là il leur arrive parfois d’halluciner … ).

' 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 « J'aime »

Je me suis permis de modifier le code dans les deux messages car je me suis aperçu que la dernière ligne ne servait à rien (j’étais parti sur une autre idée au début et j’ai omis de supprimer ce qui ne servait plus).
Merci pour le test et l’ajout des commentaires (j’admet ne plus trop commenter mes codes vu que je suis le seul à coder dans ma société)
@Patrick_CHARDON , à vous de jouer

2 « J'aime »