Problemy z dostępem do notatek lub atrybutów bloków lub instancji bloków w języku VBA

Witam, zamierzam czytać i edytować notatki lub atrybuty w blokach VBA lub instancjach bloków na rysunkach SolidWorks.
Mogę pobrać obiekty blokowe lub instancje bloku, ale po wykonaniu następujących funkcji tworzę błędy:
swBlockDef.GetNotes
swBlockDef.GetNoteCount
z swBlockDef jako SldWorks.BlockDefinition
lub
swlockInst.GetAnnotation
swlockInst.GetAttributes
swlockInst.GetAttributeCount
swlockInst.GetAttributeValue
swlockInst.SetAttributeValue
z swlockInst jako SldWorks.BlockInstance

W przeszłości z powodzeniem używałem już swBlockDef.GetNotes, ale teraz już nie działa.
Czy ktoś ma dla mnie rozwiązanie?
Z góry dziękuję

Witam serdecznie;

Byłoby łatwiej, gdybyś opublikował (między tagami) całe makro...

Wygląda na to, że SldWorks.BlockDefinition jest przestarzały od wersji 2007:
image

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

ekstrakt:

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

Konieczne wydaje się zastąpienie go przez:
SldWorks.SketchBlockDefinition

z atrybutami:
https://help.solidworks.com/2022/english/api/sldworksapiprogguide/Overview/Block_Definitions_and_Block_Instances.htm

Pozdrowienia.

Witam

Używam SldWorks.SketchBlockDefinition i SldWorks.SketchBlockInstance
Mogę pobrać obiekty block i Blockinstance.
Dopiero po tym mam problemy...

Witam

Musisz spojrzeć na ten przykład API: Pobierz przykład informacji o bloku (VBA) - 2024 - Pomoc SOLIDWORKS API
Dostęp do nut zawartych w bloku jest uzyskiwany w zmiennej typu variant.

Powinieneś wypróbować ten kod, który istnieje od bardzo dawna.
Z mojej strony to już nie działa.

To niewiele znaczy " to już nie działa ":

  • Masz komunikaty o błędach? Jeśli tak, to które + zrzut ekranu.
  • Jakie zmiany zostały wprowadzone między " to działa " a " już nie działa ".
  • Nie określono bieżącej wersji Solidworks.

Makro, które Ci zaproponowałem (które jest takie samo jak to w @Cyril_f ( ... paskudny kopiarka VAS) działa na moim Solidworks 2022 SP4:grin::

Oto wynik...

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 polubienie

Ups, przepraszam. Zmęczony w tej chwili nie zwróciłem uwagi na link w Twojej odpowiedzi.

1 polubienie

Witam
Poniżej znajduje się kod, którego używam do moich testów
Gdy vNote to vNote() jako sldworks.note, to niezgodność typu kodu błędu wykonania 13
Gdy vNote jest wariantem, wiersz vNote = swBlockDef.GetNotes daje vNote równa się puste
I wiersz vNote = swlockInst.GetAttributes, a następnie kod błędu ‹ - 670099352 (d80f1868) ›: Automatyzacja błędów

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

Witam
Czyli dużo błędów w kodzie.
Poniżej znajduje się poprawiony kod, który powinien działać (działa na 2024 SP5), zaczerpnięty z kodu pomocy 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

Zasadniczo, deklarowanie zmiennych, które są niepoprawne:

 Dim vBlockDef()                 As SldWorks.BlockDefinition 

Typ zmiennej Variant i brak nawiasów do umieszczenia w nazwie tej zmiennej.
Brak zestawu zmiennej swNote i wielu innych.

1 polubienie

Witam
Masz rację co do brakujących zestawów w swNote = vNote(i)
Z drugiej strony, gdy Dim vBlockDef As Variant, otrzymuję błąd w wierszu Set swBlockDef = vBlockDef(i), że jestem, gdy Dim vBlockDef() As SldWorks.BlockDefinition

Która wersja oprogramowania?
Nie mam żadnych błędów na SW 2024.

Makro @Cyril_f działa również w Solidworks 2022.
Kiedy mówisz o błędzie, podaj jego numer (lub zrób zrzut ekranu).

Jestem w SW2022 sp5.0
To dziwne z mojej strony:
Gdy vNote jako wariant, to vNote = swBlockDef.GetNotes lub vNote = swlockInst.GetAttributes są puste
Gdy vNote() As SldWorks.Note, te same funkcje tworzą błąd wykonania 13: Niezgodność typów

Powinniśmy przyjrzeć się referencjom (Tools-> References).
Moje to te, ale mój kod zawiera różne makra, które wymagają więcej odwołań niż jest to konieczne na potrzeby makra blokowego.
image
Kolejnym problemem, który już mi się przydarzył, jest wersja VBA, która nie jest właściwa i generuje błędy operacyjne macOS

Właśnie przeprowadziłem test makra @Cyril_f na starym pliku sprzed 2007 roku...
W takim przypadku zmienne są faktycznie puste.
=> W tej sytuacji musisz skorzystać z informacji podanych w przykładzie, który już dwukrotnie Ci przedstawiliśmy:
https://help.solidworks.com/2022/english/api/sldworksapi/get_block_information_example_vb.htm?verRedirect=1

z:

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

Nie chcąc cię urazić, @Patrick_CHARDON , nie wydajesz się zbyt komfortowo z deklaracjami zmiennych. Polecam zaufać @Cyril_f, ponadto jego makro współpracuje z nami.
Co dokładnie chcesz uzyskać jako informacje od swojego koźlaka, prawdopodobnie możemy Ci pomóc, ale jeśli tak naprawdę nie wiemy, co próbujesz zrobić, jest to skomplikowane... A teraz kręcimy się w kółko...

1 polubienie

Witam

Nie mam pliku z blokami pochodzącymi z 2007 roku, więc ciężko jest przetestować kod, który rozwiązałby problem. Mogę jednak podać kod do testowania

Witam

Poniżej kodu, który ma być testowany, działa na blokach utworzonych w wersji wyższej niż 2007, jak wyjaśniono, debugowanie nie jest możliwe z mojej strony w poprzednich wersjach. @Maclane , czy możesz przetestować.

    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 polubienie

@Cyril_f , Twoje makro wydaje się działać bez problemów na starych blokach sprzed 2007 roku.
… Nawet jeśli test jest nieco tendencyjny przez fakt, że nie używałem wielu atrybutów w moich starych blokach. (W tamtym czasie zbyt wiele wycierpiałem z powodu Autocada...) :sweat_smile:

Pozwoliłem sobie dodać kilka komentarzy do twojego kodu w celach edukacyjnych: ( W rzeczywistości to AI " Zakłopotanie " to zrobiła. I to jest jedyne zastosowanie AI, na jakie sobie do tej pory pozwalam... a nawet wtedy czasami mają halucynacje ... ).

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

Pozwoliłem sobie zmodyfikować kod w obu wiadomościach, ponieważ zdałem sobie sprawę, że ostatnia linijka była bezużyteczna (na początku zacząłem od innego pomysłu i pominąłem usunięcie tego, co nie było już przydatne).
Dziękuję za test i dodanie komentarzy (przyznam, że nie komentuję już zbytnio swoich kodów, ponieważ jestem jedyną osobą, która koduje w mojej firmie)
@Patrick_CHARDON , to zależy od Ciebie

2 polubienia