Dostęp do ustawień konstrukcji blachowej wielu obiektów za pomocą VBA

Dzień dobry

Szukam dostępu do parametrów składania arkusza blachy na części wielobryłowej, mam ten kod, który pomyślałem, że może rozwiązać moje problemy.
Ale kiedy go uruchamiam, daje mi wartości, które są wszędzie identyczne i nie mają odpowiedniego promienia i grubości.

Kod:

Dim swApp As SldWorks.SldWorks
Dim myModel As SldWorks.ModelDoc2
Dim featureMgr As SldWorks.FeatureManager
Dim feat As SldWorks.Feature
Dim sheetMetalFolder As SldWorks.sheetMetalFolder
Dim featArray As Variant
Dim i As Long
Dim swBaseFlangeFeat As SldWorks.BaseFlangeFeatureData
Option Explicit

Sub main()

    Set swApp = Application.SldWorks
    Set myModel = swApp.ActiveDoc
    Set featureMgr = myModel.FeatureManager
   

    Set sheetMetalFolder = featureMgr.GetSheetMetalFolder
    Set feat = sheetMetalFolder.GetFeature
    Debug.Print "Sheet metal folder name: " & feat.Name
    Debug.Print "  Number of sheet metal features in the folder: " & sheetMetalFolder.GetSheetMetalCount
    featArray = sheetMetalFolder.GetSheetMetals
    For i = LBound(featArray) To UBound(featArray)
        Set feat = featArray(i)
        Debug.Print "    " & feat.Name
        Set swBaseFlangeFeat = myModel.FeatureManager.CreateDefinition(swFmBaseFlange)
        swBaseFlangeFeat.OverrideDefaultSheetMetalParameters = True
    'swBaseFlangeFeat.Thickness = 0.065
    'swBaseFlangeFeat.OverrideRadius = False
    
    'swBaseFlangeFeat.BendRadius = 1
    Debug.Print swBaseFlangeFeat.BendRadius
    Debug.Print swBaseFlangeFeat.Thickness
    Next i

End Sub

Oto jedno z moich ustawień blachy:
Screenshot_54

A oto wynik powyższego kodu:

Sheet metal folder name: Tôlerie
  Number of sheet metal features in the folder: 4
    Tôlerie3
 0.00015 
 0.0005 
    Tôlerie12
 0.00015 
 0.0005 
    Tôlerie14
 0.00015 
 0.0005 
    Tôlerie34
 0.00015 
 0.0005 

Czy możesz mi powiedzieć, dlaczego nie mam odpowiednich wartości?
Nie rozumiem, dlaczego zawsze mam 0,00015, co odpowiada 0,15 mm
i 0,0005, co odpowiada 0,5 mm.

Dobry wieczór @treza88

Błąd wynika z funkcji tych dwóch linii:

Set swBaseFlangeFeat = myModel.FeatureManager.CreateDefinition(swFmBaseFlange)
        swBaseFlangeFeat.OverrideDefaultSheetMetalParameters = True

Pierwsza z nich tworzy strukturę danych konstrukcji blachowej z ustawieniami domyślnymi.
Drugi wymaga wymiany obecnej konstrukcji nadwozia z blachy w konstrukcji.
Co wyjaśnia, dlaczego wszystkie są identyczne...

Dołączone makro używa tej metody Set swSheetMetalData = swFeat.GetDefinition do pobierania danych z obiektu arkusza blachy i wyświetlania ich.

SettingsTolerie.swp (51,5 KB)

1 polubienie

Wielkie dzięki @m_blt za kod, działa idealnie.

Gdybym ośmielił się nadużywać, czy mógłbyś mi powiedzieć, jak mogę użyć tego kodu w zestawie i zapętlić wszystkie części tego samego zestawu?

Dobry wieczór

Poniższe makro powinno odpowiedzieć na to " obraźliwe " pytanie. :wink:
Skanuje całe drzewo zespołu w celu znalezienia części, identyfikuje dla każdej części, czy jest to część arkusza blachy, a jeśli tak, wyświetla jej właściwości.
Pozostałe elementy (inne niż arkusz blachy) są ignorowane.

Makro twierdzi również, że działa na dokumencie części.

UstawieniaSheet MetalAssemb.swp (64,5 KB)

Wielkie dzięki, to bardzo miłe z twojej strony, kod działa doskonale w zestawie i w pliku części. Chciałbym czuć się tak komfortowo z VBA Solidworks, jak Ty.

Zamierzam przeanalizować ten kod i spróbuję go zmodyfikować tak, aby mógł wykryć, czy w głównym zestawie znajdują się jakieś zestawy potomne.

Twój kod wydaje mi się wystarczająco jasny, żebym mógł tam dotrzeć, i na wypadek, gdybym wrócił na forum.
Zweryfikuję Twoją odpowiedź i anuluję ją, jeśli będę musiał wrócić, aby zadać pytania

W zasadzie makro reaguje już na głęboką eksplorację drzewa asemblera.
Przechodzi przez pierwszy poziom zespołu głównego w procedurze " main ", ale także podzespoły, niezależnie od ich poziomu, w procedurze " BrowseComponents ", która działa rekurencyjnie.

Ostatnia funkcja " SheetPart " jest prawie identyczna z tą w mojej poprzedniej przesyłce, aby wyświetlić ustawienia blachy części.

Dziękuję , @m_blt go przetestowałem i działa idealnie.

Z drugiej strony próbowałem zmodyfikować promień gięcia, dodając:

swSheetMetalData.BendRadius = 2.06 / 1000

Ale to nie działa, jak zmienić wartość promienia?

Witam

W funkcji " SheetPart " mojego makra zmienna " swSheetMetalData " typu " SheetMetalFeatureData " zawiera parametry funkcji arkusza blachy ("swFet ").
Metoda " AccessSelections " tej klasy pozwala na dostęp do parametrów tej struktury danych i zmianę jej wartości.
Następnie, metoda " ModifyDefinition " elementu konstrukcji blachowej (" swFeat ") powoduje zmianę.

Jeżeli otworzysz Pomoc API SolidWorks (na dole strony https://help.solidworks.com/) i wyszukasz klasę " ISheetMetalFeatureData ", znajdziesz sugerowany przykład " Zmień promień gięcia części arkusza blachy (VBA) ", który dokładnie odpowiada na Twoje pytanie.

Ogólnie rzecz biorąc, pomoc interfejsów API jest niestrawna, ale bardzo kompletna i oferuje wiele przykładów, z których można czerpać inspirację.
Dzień dobry...

Przepraszam, że jestem niezdarny, ale zmodyfikowałem kod w następujący sposób:

Dodałem, co najwyraźniej umożliwia dostęp do " BendRadius ":

 bRet = swSheetMetalData.AccessSelections(swModel, Nothing): Debug.Assert bRet

Odnosząc się do przykładu, ale to nadal nie działa, chociaż:
" swSheetMetalData " jest rzeczywiście zdefiniowany jako obiekt " swFeat.GetDefinition ", jak w przykładzie?

Function SheetPart(swModel As ModelDoc2) As Boolean

    Dim swFeat              As Feature
    Dim vFeatArray          As Variant
    Dim sheetMetalFolder    As sheetMetalFolder
    Dim swSheetMetalData    As SheetMetalFeatureData
    Dim gaugeTableFile      As String
    Dim swCustBend          As CustomBendAllowance
    Dim i                   As Long
    Dim bRet                As Boolean
    Dim lRet                As Long
    

    Set sheetMetalFolder = swModel.FeatureManager.GetSheetMetalFolder
    If sheetMetalFolder Is Nothing Then
        Exit Function
    End If
    
    Set swFeat = sheetMetalFolder.GetFeature
    Debug.Print "-------------------------------------------------"
    Debug.Print "Composant : " & swModel.GetPathName
    Debug.Print "  Nom du dossier de tôlerie : " & swFeat.Name
    Debug.Print "  Nombre de fonctions de tôlerie dans le dossier : " & sheetMetalFolder.GetSheetMetalCount
    Debug.Print ""
    vFeatArray = sheetMetalFolder.GetSheetMetals
    For i = LBound(vFeatArray) To UBound(vFeatArray)
        Set swFeat = vFeatArray(i)
        Set swSheetMetalData = swFeat.GetDefinition
        Set swCustBend = swSheetMetalData.GetCustomBendAllowance
        nbTotal = nbTotal + 1
        bRet = swSheetMetalData.AccessSelections(swModel, Nothing): Debug.Assert bRet
        If swSheetMetalData.Thickness * 1000 = 1.5 And swSheetMetalData.BendRadius * 1000 <> 1.025 Then
            swSheetMetalData.BendRadius = 1.025 / 1000
            swCustBend.Type = 1
            nbModif = nbModif + 1
            Stop
        ElseIf swSheetMetalData.Thickness * 1000 = 2 And swSheetMetalData.BendRadius * 1000 <> 1.5 Then
            swSheetMetalData.BendRadius = 1.5 / 1000
            swCustBend.Type = 1
            nbModif = nbModif + 1
            Stop
        ElseIf (swSheetMetalData.Thickness = 0.003 And swSheetMetalData.BendRadius <> 0.00206) Then
            swSheetMetalData.BendRadius = 2.06 / 1000
            swCustBend.Type = 1
            nbModif = nbModif + 1
            Stop
        ElseIf swSheetMetalData.Thickness * 1000 = 4 And swSheetMetalData.BendRadius * 1000 <> 5.4 Then
            swSheetMetalData.BendRadius = 5.4 / 1000
            swCustBend.Type = 1
            nbModif = nbModif + 1
            Stop
        ElseIf swSheetMetalData.Thickness * 1000 = 5 And swSheetMetalData.BendRadius * 1000 <> 5 Then
            swSheetMetalData.BendRadius = 5 / 1000
            swCustBend.Type = 1
            nbModif = nbModif + 1
            Stop
        End If
        
        Debug.Print "  " & swFeat.Name
        Debug.Print "      Tolérance de pliage        = " & swSheetMetalData.BendAllowance * 1000# & " mm"
        Debug.Print "      Fichier de table de pliage = " & swSheetMetalData.BendTableFile
        Debug.Print "      Epaisseur                  = " & swSheetMetalData.Thickness * 1000# & " mm"
        Debug.Print "      Rayon                      = " & swSheetMetalData.BendRadius * 1000# & " mm"
        Debug.Print "      Perte au pli               = " & swCustBend.BendDeduction * 1000# & " mm"
        Debug.Print "      KFactor                    = " & swSheetMetalData.KFactor
        Debug.Print "      Type de pli                = " & swCustBend.Type
        Debug.Print ""
        
    Next i

End Function

Aby sprawdzić poprawność zmian, ta instrukcja musi zostać dodana po zdefiniowaniu wartości, a przed serią wyświetleń...

     bRet = swFeat.ModifyDefinition(swSheetMetalData, swModel, Nothing)

O ile się nie mylę, zmiana jest dokonywana na domyślną wartość promienia funkcji " Blacha". 
Wygląda na to, że konieczne jest również zaznaczenie pola " Zastąp ustawienia..."  aby zmiana była skuteczna.

image

Zmiana nie ma wpływu na promienie zagięć utworzonych przez kolejne funkcje, jeśli zostały one zdefiniowane za pomocą określonych promieni (zagięcie przejściowe, zagięcie naszkicowane, arkusz zagięty krawędzią itp.). W takim przypadku konieczne jest uzyskanie dostępu do każdej z tych konkretnych funkcji. Kambuz...
Zobacz ten przykład z pomocy interfejsu API:
Pobierz przykład wszystkich danych elementów konstrukcji blachowej (VBA)

Naprawdę dziękuję za wyjaśnienia, które pozostają przystępne dla mnie, jako częściowo neofity.

Z tego też powodu najwyraźniej błędnie sądziłem, że muszę zweryfikować następującą właściwość (w poście #1), aby móc nadpisać domyślny promień gięcia:

swBaseFlangeFeat.OverrideDefaultSheetMetalParameters = True

Nie może być więc łatwiej uzyskać dostęp do modyfikacji tych promieni gięcia.

Ale jeśli musisz przejść przez cały ten kod "Pobierz przykład danych elementów konstrukcji blachowej (VBA)", to jest to niezwykle skomplikowane, aby zmienić promień gięcia na wszystkich komponentach lub obiektach.


EDYCJA: Opcja "Pobierz przykład wszystkich danych elementu konstrukcji blachowej (VBA)" nie zezwala na modyfikację, a jedynie służy do pozyskiwania danych. Nie ma czegoś takiego jak " Zestaw danych elementu arkusza blachy "?


Można by pomyśleć, że tak długo, jak długo uzyskuje się dostęp do komponentu lub ciała, które jest obiektem o właściwościach, którego częścią jest promień gięcia.
Można zmodyfikować promień podstawy zgięcia, który jest częścią właściwości tego samego obiektu.

Ale widocznie tak nie jest?

Mam nadzieję, że rozumiesz moje rozumowanie (niekoniecznie logiczne), które opiera się na obiektach i ich własnościach.

Instrukcja, która pozwala zaznaczyć/odznaczyć pole " Zamień parametry..." to ta, umieszczona przed walidacją modyfikacji. Do przetestowania.

swSheetMetalData.SetOverrideDefaultParameter2 swSheetMetalOverrideDefaultParameters_BendParameters, True

Jeśli chodzi o funkcje, które wykorzystują poszczególne promienie, to nie widzę innego rozwiązania niż szukanie po kolei danych funkcji w drzewie.

Nie jest to potworne, o ile jest bardzo powtarzalne, a kluczem jest znajomość nazw używanych przez Solidworks. Stąd zainteresowanie przykładem " Pobierz całą blachę..." »

Witam i dziękuję @m_blt za powyższą instrukcję, która pozwoliła mi poczynić duże postępy i powiedziałbym, że prawie ukończyłem mój kod (który jest w zasadzie twój).

Jednak nadal mam problem, wszystko działa tak jak bym chciał, dzięki czemu mogę zmienić domyślne ustawienia blachy, ale także ustawienia wymiany w przypadku części wielobryłowej.
Kiedy uruchamiam makro z jedno- lub wielobryłową częścią arkusza blachy, wszystko działa idealnie.
Z drugiej strony, gdy sprawiłem, że działał z zespołem, cały proces przetwarzania najwyraźniej działa dobrze, ale gdy makro zakończy działanie, plik pozostaje częściowo zablokowany.
Nie mogę już kliknąć prawym przyciskiem myszy, na przykład, aby wyświetlić menu kontekstowe i jestem zmuszony zamknąć plik i ponownie go otworzyć, aby znów działał.

Nie rozumiem, dlaczego w przypadku montaży tak robi.
Każda pomoc będzie dla mnie cenna do zrozumienia, z góry dziękuję.

Oto kod:

Dim nbTotalCorps             As Integer
Dim nbTotalDossier          As Integer
Dim nbModifCorps            As Integer
Dim nbModifDossier          As Integer
Dim pieceCorps              As Boolean

Option Explicit


Sub main()
    Dim swApp           As SldWorks.SldWorks
    Dim swModel         As ModelDoc2
    Dim swAssemb        As AssemblyDoc
    Dim swComp          As Component2
    Dim vComponents     As Variant
    Dim i               As Integer
    Dim OK              As Boolean
    
    nbTotalCorps = 0
    nbTotalDossier = 0
    nbModifCorps = 0
    nbModifDossier = 0

    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
    If swModel Is Nothing Then                      ' Si aucun document n'est ouvert
        MsgBox "Un document de pièce ou d'assemblage doit être ouvert.", vbExclamation
        Exit Sub
    
    ElseIf swModel.GetType = swDocPART Then         ' Si c'est une pièce...
        OK = SheetPart(swModel)
        MsgBox nbModifDossier & " rayon de pliage modifier sur " & nbTotalDossier & " de dossier par défaut de tolerie" & vbCrLf & _
        nbModifCorps & " rayon de pliage modifier sur " & nbTotalCorps & " corps de tolerie"
        Exit Sub
    
    ElseIf swModel.GetType = swDocASSEMBLY Then     ' Si c'est un assemblage...
        Set swAssemb = swModel
        vComponents = swAssemb.GetComponents(True)  ' Tableau des composants de niveau 1 de l'assemblage
        For i = 0 To UBound(vComponents)
            Set swComp = vComponents(i)
            ParcourirComposants swComp              ' Parcours des composants (récursif)
        Next i
        MsgBox nbModifDossier & " rayon de pliage modifier sur " & nbTotalDossier & " de dossier par défaut de tolerie" & vbCrLf & _
        nbModifCorps & " rayon de pliage modifier sur " & nbTotalCorps & " corps de tolerie"
        
    End If

End Sub

Sub ParcourirComposants(swComp As SldWorks.Component2)
    
    Dim vChildComponents    As Variant
    Dim swModel             As ModelDoc2
    Dim swChildComp         As SldWorks.Component2
    Dim i                   As Integer
    Dim OK                  As Boolean
    
    Set swModel = swComp.GetModelDoc2                   ' Modèle associé au composant
    If Not swModel Is Nothing Then
        If swModel.GetType = swDocPART Then             ' Si c'est une pièce...
            OK = SheetPart(swModel)
            
        ElseIf swModel.GetType = swDocASSEMBLY Then     ' Si c'est un assemblage...
            vChildComponents = swComp.GetChildren       ' Liste des composants enfants
            For i = 0 To UBound(vChildComponents)
                Set swChildComp = vChildComponents(i)
                ParcourirComposants swChildComp         ' Parcours du composant enfant (récursif)
            Next i
        End If
        
    End If
End Sub


Function SheetPart(swModel As ModelDoc2) As Boolean

    Dim swFeat                  As Feature
    Dim vFeatArray              As Variant
    Dim sheetMetalFolder        As sheetMetalFolder
    Dim swSelMgr                As SldWorks.SelectionMgr
    Dim swSheetMetal            As SldWorks.SheetMetalFeatureData
    Dim swSheetMetalData        As SheetMetalFeatureData
    Dim gaugeTableFile          As String
    Dim swCustBend              As CustomBendAllowance
    Dim i                       As Long
    Dim bRet                    As Boolean
    Dim lRet                    As Long
    Dim errors                  As Long
    Dim overrideParameters      As Boolean
    Dim swFeature               As SldWorks.Feature
    Dim swSheetMetalFeatureData As SldWorks.SheetMetalFeatureData

    
    Set sheetMetalFolder = swModel.FeatureManager.GetSheetMetalFolder
    If sheetMetalFolder Is Nothing Then
        Exit Function
    End If
    
    Set swFeat = sheetMetalFolder.GetFeature
    Debug.Print "-------------------------------------------------"
    Debug.Print "Composant : " & swModel.GetPathName
    Debug.Print "  Nom du dossier de tôlerie : " & swFeat.Name
    Debug.Print "  Nombre de fonctions de tôlerie dans le dossier : " & sheetMetalFolder.GetSheetMetalCount
    Debug.Print ""
    
    'Création du tableau comportant chaque element de tolerie contenu dans le dossier de tolerie
    vFeatArray = sheetMetalFolder.GetSheetMetals
    'Stop
    Debug.Print "  Nom du dossier de tôlerie : " & vFeatArray(0).Name
    
    '
    Set swSheetMetal = swFeat.GetDefinition
    Set swCustBend = swSheetMetal.GetCustomBendAllowance

    'Accession au parametres de tolerie par défaut
    bRet = swSheetMetal.IAccessSelections2(swModel, Nothing): Debug.Assert bRet
    
    pieceCorps = True
    nbTotalDossier = nbTotalDossier + 1
    'Appel de la fonction choixRayonPliageParEpaisseur
    choixRayonPliageParEpaisseur swCustBend, swSheetMetal, pieceCorps
        
    'On valide les modifications des parametres de tolerie par défaut
    bRet = swFeat.ModifyDefinition(swSheetMetal, swModel, Nothing): Debug.Assert bRet
    
    Debug.Print "  Modified bend radius = " & swSheetMetal.BendRadius * 1000# & " mm"
    
    'Boucle sur les elements de tolerie contenu dans le dossier
    For i = LBound(vFeatArray) To UBound(vFeatArray)
        Set swFeat = vFeatArray(i)
        Set swSheetMetalData = swFeat.GetDefinition
        Set swCustBend = swSheetMetalData.GetCustomBendAllowance
        pieceCorps = False
        nbTotalCorps = nbTotalCorps + 1
        
        'verification de l'état "Remplacer les parametres de pliage"
        errors = swSheetMetalData.GetOverrideDefaultParameter2(swSheetMetalOverrideDefaultParameters_e.swSheetMetalOverrideDefaultParameters_BendParameters, overrideParameters)
            Debug.Print ("  Bend parameters: " & overrideParameters)
        
        'Si "remplacer les parametres de pliage" est coché
        If overrideParameters Then
            'On accede au parametres de pliage et à la zone de pliage
            errors = swSheetMetalData.SetOverrideDefaultParameter2(swSheetMetalOverrideDefaultParameters_e.swSheetMetalOverrideDefaultParameters_BendParameters, True)
            errors = swSheetMetalData.SetOverrideDefaultParameter2(swSheetMetalOverrideDefaultParameters_e.swSheetMetalOverrideDefaultParameters_BendAllowance, True)
            
            'Appel de la fonction choixRayonPliageParEpaisseur
            choixRayonPliageParEpaisseur swCustBend, swSheetMetalData, pieceCorps

            'On valide les modifications des parametres de tolerie
            bRet = swFeat.ModifyDefinition(swSheetMetalData, swModel, Nothing): Debug.Assert bRet
            'Stop
            Debug.Print "  Modified bend radius = " & swSheetMetalData.BendRadius * 1000# & " mm"
        End If
        
        Debug.Print "  " & swFeat.Name
        Debug.Print "      Tolérance de pliage        = " & swSheetMetalData.BendAllowance * 1000# & " mm"
        Debug.Print "      Fichier de table de pliage = " & swSheetMetalData.BendTableFile
        Debug.Print "      Epaisseur                  = " & swSheetMetalData.Thickness * 1000# & " mm"
        Debug.Print "      Rayon                      = " & swSheetMetalData.BendRadius * 1000# & " mm"
        Debug.Print "      Perte au pli               = " & swCustBend.BendDeduction * 1000# & " mm"
        Debug.Print "      KFactor                    = " & swSheetMetalData.KFactor
        Debug.Print "      Type de pli                = " & swCustBend.Type
        Debug.Print ""
        
    Next i

End Function

Function choixRayonPliageParEpaisseur(swCustBend As CustomBendAllowance, swSheetMetal As SldWorks.SheetMetalFeatureData, _
pieceCorps As Boolean)

'Test si epaisseur 1.5mm, rayon de pliage 1.5 et utilisation d'une table de pliage
If swSheetMetal.Thickness * 1000 = 1.5 And swSheetMetal.BendRadius * 1000 <> 1.5 _
Or swCustBend.Type <> 1 Then
            swSheetMetal.BendRadius = 1.5 / 1000
            swCustBend.Type = 1
            If pieceCorps Then
                nbModifDossier = nbModifDossier + 1
            Else
                nbModifCorps = nbModifCorps + 1
            End If

'Test si epaisseur 2mm, rayon de pliage 2 et utilisation d'une table de pliage
ElseIf swSheetMetal.Thickness * 1000 = 2 And swSheetMetal.BendRadius * 1000 <> 2 _
Or swCustBend.Type <> 1 Then
            swSheetMetal.BendRadius = 2 / 1000
            swCustBend.Type = 1
            If pieceCorps Then
                nbModifDossier = nbModifDossier + 1
            Else
                nbModifCorps = nbModifCorps + 1
            End If

'Test si epaisseur 3mm, rayon de pliage 3 et utilisation d'une table de pliage
ElseIf (swSheetMetal.Thickness * 1000 = 3 And swSheetMetal.BendRadius * 1000 <> 36) _
Or swCustBend.Type <> 1 Then
            swSheetMetal.BendRadius = 3 / 1000
            swCustBend.Type = 1
            If pieceCorps Then
                nbModifDossier = nbModifDossier + 1
            Else
                nbModifCorps = nbModifCorps + 1
            End If

'Test si epaisseur 4mm, rayon de pliage 4 et utilisation d'une table de pliage
ElseIf swSheetMetal.Thickness * 1000 = 4 And swSheetMetal.BendRadius * 1000 <> 4 _
Or swCustBend.Type <> 1 Then
            swSheetMetal.BendRadius = 4 / 1000
            swCustBend.Type = 1
            If pieceCorps Then
                nbModifDossier = nbModifDossier + 1
            Else
                nbModifCorps = nbModifCorps + 1
            End If
'Test si epaisseur 5mm, rayon de pliage 5 et utilisation d'une table de pliage
ElseIf swSheetMetal.Thickness * 1000 = 5 And swSheetMetal.BendRadius * 1000 <> 5 _
Or swCustBend.Type <> 1 Then
            swSheetMetal.BendRadius = 5 / 1000
            swCustBend.Type = 1
            If pieceCorps Then
                nbModifDossier = nbModifDossier + 1
            Else
                nbModifCorps = nbModifCorps + 1
            End If

        End If
End Function

Witam

Problem jest związany z parametrami przekazywanymi do dwóch metod AccessSelections() i ModifyDefinition(), które różnią się w zależności od tego, czy głównym dokumentem jest PART, czy ASSEMBLY.
Pomoc API podkreśla ten problem w swoich przypisach i wskazuje, że zamieszanie nie blokuje wykonywania, ale może spowodować " nieoczekiwane " zachowanie. :laughing:

W pierwszym przypadku należy przekazać ModeleDoc części arkusza blachy, w drugim należy przekazać ModelDoc zespołu i komponentu arkusza blachy, którego dotyczy zmiana.

Korekta musi być dokonana w 3 miejscach, w których pojawiają się te metody, poprzez sprawdzenie, czy głównym dokumentem jest część, czy złożenie.
Drzewo konstrukcyjne zespołu powraca wtedy do normalnego zachowania...

Wersja poprawiona w załączonym dokumencie.
Zasadność obróbki z punktu widzenia obróbki blach pozostaje do sprawdzenia.

FoldWallet2.swp (93 KB)

1 polubienie

Wielkie podziękowania @m_blt za całą pomoc, której mi udzieliliście.

Oto mój ostateczny kod (głównie Twój @m_blt ), jeśli może się komuś przydać:

Option Explicit

Dim nbTotalCorps             As Integer
Dim nbTotalDossier          As Integer
Dim nbModifCorps            As Integer
Dim nbModifDossier          As Integer
Dim pieceCorps              As Boolean
Dim swApp           As SldWorks.SldWorks
Dim boolstatus As Boolean
Dim swCustBend2 As CustomBendAllowance
Dim swSheetMetal As SldWorks.SheetMetalFeatureData




Sub main()
    Dim swModel         As ModelDoc2
    Dim swAssemb        As AssemblyDoc
    Dim swComp          As Component2
    Dim vComponents     As Variant
    Dim i               As Integer
    Dim OK              As Boolean
    
    nbTotalCorps = 0
    nbTotalDossier = 0
    nbModifCorps = 0
    nbModifDossier = 0

    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
    If swModel Is Nothing Then                      ' Si aucun document n'est ouvert
        MsgBox "Un document de pièce ou d'assemblage doit être ouvert.", vbExclamation
        Exit Sub
    
    ElseIf swModel.GetType = swDocPART Then         ' Si c'est une pièce...
        OK = SheetPart(Nothing, swModel)
        MsgBox nbModifDossier & " rayon de pliage modifier sur " & nbTotalDossier & " de dossier par défaut de tolerie" & vbCrLf & _
        nbModifCorps & " rayon de pliage modifier sur " & nbTotalCorps & " corps de tolerie"
        Exit Sub
    
    ElseIf swModel.GetType = swDocASSEMBLY Then     ' Si c'est un assemblage...
        Set swAssemb = swModel
        vComponents = swAssemb.GetComponents(True)  ' Tableau des composants de niveau 1 de l'assemblage
        For i = 0 To UBound(vComponents)
            Set swComp = vComponents(i)
            ParcourirComposants swComp              ' Parcours des composants (récursif)
        Next i
        MsgBox nbModifDossier & " rayon de pliage modifier sur " & nbTotalDossier & " de dossier par défaut de tolerie" & vbCrLf & _
        nbModifCorps & " rayon de pliage modifier sur " & nbTotalCorps & " corps de tolerie"
        
    End If
    swModel.ForceRebuild3 (True)

End Sub

Sub ParcourirComposants(swComp As SldWorks.Component2)
    
    Dim vChildComponents    As Variant
    Dim swModel             As ModelDoc2
    Dim swChildComp         As SldWorks.Component2
    Dim i                   As Integer
    Dim OK                  As Boolean
    
    Set swModel = swComp.GetModelDoc2                   ' Modèle associé au composant
    If Not swModel Is Nothing Then
        If swModel.GetType = swDocPART Then             ' Si c'est une pièce...
            OK = SheetPart(swComp, swModel)
            
        ElseIf swModel.GetType = swDocASSEMBLY Then     ' Si c'est un assemblage...
            vChildComponents = swComp.GetChildren       ' Liste des composants enfants
            For i = 0 To UBound(vChildComponents)
                Set swChildComp = vChildComponents(i)
                ParcourirComposants swChildComp         ' Parcours du composant enfant (récursif)
            Next i
        End If
        
    End If
End Sub


Function SheetPart(swComp As Component2, swModel As ModelDoc2) As Boolean

    Dim swFeat                  As Feature
    Dim vFeatArray              As Variant
    Dim sheetMetalFolder        As sheetMetalFolder
    Dim swSelMgr                As SelectionMgr
    Dim swSheetMetalData        As SheetMetalFeatureData
    Dim swCustBend              As CustomBendAllowance
    Dim gaugeTableFile          As String
    
    Dim i                       As Long
    Dim bRet                    As Boolean
    Dim lRet                    As Long
    Dim errors                  As Long
    Dim overrideParameters      As Boolean
    Dim swFeature               As SldWorks.Feature
    
    
    Set sheetMetalFolder = swModel.FeatureManager.GetSheetMetalFolder
    If sheetMetalFolder Is Nothing Then
        Exit Function
    End If
    
    Set swFeat = sheetMetalFolder.GetFeature
    Debug.Print "-------------------------------------------------"
    Debug.Print "Composant : " & swModel.GetPathName
    Debug.Print "  Nom du dossier de tôlerie : " & swFeat.Name
    Debug.Print "  Nombre de fonctions de tôlerie dans le dossier : " & sheetMetalFolder.GetSheetMetalCount
    Debug.Print ""
    
    'Création du tableau comportant chaque element de tolerie contenu dans le dossier de tolerie
    vFeatArray = sheetMetalFolder.GetSheetMetals
    'Stop
    Debug.Print "  Nom du dossier de tôlerie : " & vFeatArray(0).Name
    
    '
    Set swSheetMetalData = swFeat.GetDefinition
    Set swCustBend = swSheetMetalData.GetCustomBendAllowance

    'Accession au parametres de tolerie par défaut
    
    If swApp.ActiveDoc.GetType = swDocPART Then                             ' Si document principal type PIECE
        bRet = swSheetMetalData.AccessSelections(swModel, Nothing)
        
    Else
        bRet = swSheetMetalData.AccessSelections(swApp.ActiveDoc, swComp)   ' ou si type ASSEMBLAGE
       
    End If
    
    pieceCorps = True
    nbTotalDossier = nbTotalDossier + 1

   'Appel de la fonction choixRayonPliageParEpaisseur
            choixRayonPliageParEpaisseur swCustBend, swSheetMetalData, swComp, swModel, swFeat
   
    Debug.Print "  Modified bend radius = " & swSheetMetalData.BendRadius * 1000# & " mm"
    
    'Boucle sur les elements de tolerie contenu dans le dossier

    For i = LBound(vFeatArray) To UBound(vFeatArray)
        Set swFeat = vFeatArray(i)
        Set swSheetMetalData = swFeat.GetDefinition
        Set swCustBend = swSheetMetalData.GetCustomBendAllowance
        pieceCorps = False
        nbTotalCorps = nbTotalCorps + 1

        'verification de l'état "Remplacer les parametres de pliage"
        errors = swSheetMetalData.GetOverrideDefaultParameter2(swSheetMetalOverrideDefaultParameters_BendParameters, overrideParameters)
            Debug.Print ("  Bend parameters: " & overrideParameters)

        'Si "remplacer les parametres de pliage" est coché
        If overrideParameters Then
            'On accede au parametres de pliage et à la zone de pliage
            errors = swSheetMetalData.SetOverrideDefaultParameter2(swSheetMetalOverrideDefaultParameters_BendParameters, True)
            errors = swSheetMetalData.SetOverrideDefaultParameter2(swSheetMetalOverrideDefaultParameters_BendAllowance, True)

            'Appel de la fonction choixRayonPliageParEpaisseur
            choixRayonPliageParEpaisseur swCustBend, swSheetMetalData, swComp, swModel, swFeat

            Debug.Print "  Modified bend radius = " & swSheetMetalData.BendRadius * 1000# & " mm"
        End If

        Debug.Print "  " & swFeat.Name
        Debug.Print "      Tolérance de pliage        = " & swSheetMetalData.BendAllowance * 1000# & " mm"
        Debug.Print "      Fichier de table de pliage = " & swSheetMetalData.bendTablefile
        Debug.Print "      Epaisseur                  = " & swSheetMetalData.Thickness * 1000# & " mm"
        Debug.Print "      Rayon                      = " & swSheetMetalData.BendRadius * 1000# & " mm"
        Debug.Print "      Perte au pli               = " & swCustBend.BendDeduction * 1000# & " mm"
        Debug.Print "      KFactor                    = " & swSheetMetalData.KFactor
        Debug.Print "      Type de pli                = " & swCustBend.Type
        Debug.Print ""

    Next i

End Function

Sub choixRayonPliageParEpaisseur(swCustBend As CustomBendAllowance, swSheetMetalData As SheetMetalFeatureData, _
 swComp As Component2, swModel As ModelDoc2, swFeat As Feature)
'Stop

    Dim bRet                    As Boolean
    Dim epaisseur As Double
    Dim rayon As Double
    Dim tabEpRayon(4, 1) As Double
    Dim j As Integer
    Dim bendTablefile As String
    
    
    tabEpRayon(0, 0) = 1.5
    tabEpRayon(0, 1) = 1.5
    tabEpRayon(1, 0) = 2
    tabEpRayon(1, 1) = 2
    tabEpRayon(2, 0) = 3
    tabEpRayon(2, 1) = 3
    tabEpRayon(3, 0) = 4
    tabEpRayon(3, 1) = 4
    tabEpRayon(4, 0) = 5
    tabEpRayon(4, 1) = 5
    
    bendTablefile = "C:\Program Files\SOLIDWORKS Corp 2022\SOLIDWORKS\lang\french\Sheetmetal Bend Tables\TABLE DE PLIAGE EN MM B.XLS"
    
    epaisseur = swSheetMetalData.Thickness * 1000
    rayon = swSheetMetalData.BendRadius * 1000
    
    For j = 0 To 4

        'Test si epaisseur 1.5mm, rayon de pliage 1.025 et utilisation d'une table de pliage
        If tabEpRayon(j, 0) = epaisseur And tabEpRayon(j, 1) <> rayon Or _
            tabEpRayon(j, 0) = epaisseur And swCustBend.Type <> 1 Or _
            tabEpRayon(j, 0) = epaisseur And swSheetMetalData.bendTablefile <> bendTablefile Then
            'Stop
            swSheetMetalData.BendRadius = tabEpRayon(j, 1) / 1000
            swCustBend.Type = 1
            swSheetMetalData.bendTablefile = bendTablefile
            If pieceCorps Then
                nbModifDossier = nbModifDossier + 1
            Else
            nbModifCorps = nbModifCorps + 1
            End If
        End If
    Next j
   
    Debug.Print swModel.GetType
    Debug.Print swModel.GetTitle
    Debug.Print swComp.GetPathName
    'On valide les modifications des parametres de tolerie
    If swApp.ActiveDoc.GetType = swDocPART Then                                     ' Si document principal type PIECE
        bRet = swFeat.ModifyDefinition(swSheetMetalData, swModel, Nothing)
        'Stop
    Else
        bRet = swFeat.ModifyDefinition(swSheetMetalData, swApp.ActiveDoc, swComp)   ' ou si type ASSEMBLAGE
        'Stop
    End If
        
End Sub


1 polubienie