Tolerancja odzysku Pb w VBA

Cze wszystkim

Próbuję utworzyć makro, aby wyodrębnić serię wybranych wymiarów w planie i wyeksportować je do Excela.
Odzyskuję trzy właściwości, co pozwala na szybką identyfikację pliku, z którego zostały wyodrębnione wymiary.

Makro działa doskonale (układ jest Ok, właściwości są pobierane, wybrane wymiary wyglądają dobrze), z wyjątkiem tego, że tolerancje systematycznie wychodzą do zera...

Chat GPT, który był dla mnie bardzo pomocny podczas tworzenia tego makra, natyka się na problem. Inna sztuczna inteligencja, Claude, nie mogła zrobić tego lepiej.

Czy ktoś wie co sprawia, że wartość zerowa systematycznie rośnie? Określam, że na wymiarach, które wybiorę na moim planie do testowania, mają tolerancję, symetryczną, wynoszącą +/-0,15, wprowadzoną bezpośrednio z wyceny zarządcy nieruchomości.

Option Explicit

Sub main()
    ExportCotesVersExcel
End Sub

Sub ExportCotesVersExcel()
    Dim swApp As Object
    Dim swModel As Object
    Dim swDraw As Object
    Dim swSelMgr As Object
    Dim swDispDim As Object
    Dim swDim As Object
    Dim xlApp As Object
    Dim xlWorkbook As Object
    Dim xlSheet As Object
    Dim i As Integer
    Dim j As Integer
    Dim tolMin As Double
    Dim tolMax As Double
    Dim value As Double
    Dim valueMin As Double
    Dim valueMax As Double
    Dim itMin As Double
    Dim itMax As Double
    
    ' Créer une instance de SolidWorks (Late Binding)
    Set swApp = CreateObject("SldWorks.Application")
    Set swModel = swApp.ActiveDoc
    
    ' Vérification si un dessin est actif
    If swModel Is Nothing Then
        MsgBox "Veuillez ouvrir un dessin 2D avant d'exécuter la macro.", vbExclamation
        Exit Sub
    End If
    
    ' Vérification du type de document
    If swModel.GetType <> 3 Then ' 3 correspond à swDocDRAWING
        MsgBox "Cette macro fonctionne uniquement sur un dessin 2D.", vbExclamation
        Exit Sub
    End If
    
    Set swDraw = swModel
    Set swSelMgr = swModel.SelectionManager
    
    ' Créer une instance d'Excel (Late Binding)
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application") ' Vérifier si Excel est ouvert
    If xlApp Is Nothing Then
        Set xlApp = CreateObject("Excel.Application") ' Ouvrir Excel si ce n'est pas le cas
    End If
    On Error GoTo 0
    
    xlApp.Visible = True
    Set xlWorkbook = xlApp.Workbooks.Add
    Set xlSheet = xlWorkbook.Sheets(1)
    
    ' Entêtes Excel pour les propriétés
    xlSheet.Cells(1, 1).value = "Référence M3_2D"
    xlSheet.Cells(2, 1).value = "Indice"
    xlSheet.Cells(3, 1).value = "Description"
    
    ' Ajouter une ligne vide après les propriétés
    xlSheet.Cells(4, 1).value = ""
    
    ' Récupérer les propriétés du modèle (Référence M3_2D, Indice, Description)
    Dim customProps As Object
    Set customProps = swModel.Extension.CustomPropertyManager("")

    Dim refM3_2D As String
    Dim indice As String
    Dim description As String
    
    ' Essayer de récupérer les propriétés en tenant compte des erreurs
    On Error Resume Next
    refM3_2D = customProps.Get("Référence M3_2D")
    If Err.Number <> 0 Then refM3_2D = "Non disponible"
    
    indice = customProps.Get("Indice")
    If Err.Number <> 0 Then indice = "Non disponible"
    
    description = customProps.Get("Description")
    If Err.Number <> 0 Then description = "Non disponible"
    On Error GoTo 0
    
    ' Ajouter les propriétés dans Excel
    xlSheet.Cells(1, 2).value = refM3_2D
    xlSheet.Cells(2, 2).value = indice
    xlSheet.Cells(3, 2).value = description
    
    ' Ajouter une ligne vide après les propriétés
    xlSheet.Cells(4, 1).value = ""
    
    ' Ajouter les en-têtes pour les cotes
    xlSheet.Cells(5, 1).value = "Nom de la cote"
    xlSheet.Cells(5, 2).value = "Valeur"
    xlSheet.Cells(5, 3).value = "IT Min"
    xlSheet.Cells(5, 4).value = "IT Max"
    xlSheet.Cells(5, 5).value = "Valeur Cote Min"
    xlSheet.Cells(5, 6).value = "Valeur Cote Max"
    
    ' Vérifier si des cotes sont sélectionnées
    Dim nbCotes As Integer
    nbCotes = swSelMgr.GetSelectedObjectCount()
    
    If nbCotes = 0 Then
        MsgBox "Veuillez sélectionner des cotes avant d'exécuter la macro.", vbExclamation
        Exit Sub
    End If

    ' Parcours des cotes sélectionnées
    i = 6 ' Commencer à la ligne 6 après les propriétés, la ligne vide et les en-têtes
    Dim ent As Object
    For j = 1 To nbCotes
        Set ent = swSelMgr.GetSelectedObject6(j, -1)
        
        ' Vérifier si l'entité sélectionnée est une cote
        If Not ent Is Nothing Then
            If TypeOf ent Is SldWorks.DisplayDimension Then
                Set swDispDim = ent
                Set swDim = swDispDim.GetDimension
                
                ' Vérification de swDim avant d’accéder à ses valeurs
                If Not swDim Is Nothing Then
                    ' Récupérer la valeur de la cote
                    value = swDim.value
                    
                    ' Calcul des valeurs min et max de la cote
                    valueMin = value - tolMin
                    valueMax = value + tolMax
                    
                    ' Récupérer les tolérances IT (si disponibles)
                    On Error Resume Next
                    itMin = swDim.tolerance.itMin
                    itMax = swDim.tolerance.itMax
                    On Error GoTo 0
                    
                    ' Si les tolérances IT ne sont pas disponibles, les assigner à 0
                    If IsError(itMin) Then itMin = 0
                    If IsError(itMax) Then itMax = 0
                    
                    ' Exporter la cote, sa valeur, les tolérances IT et les valeurs min et max dans Excel
                    xlSheet.Cells(i, 1).value = swDim.FullName ' Nom de la cote
                    xlSheet.Cells(i, 2).value = Round(value, 2) ' Valeur de la cote
                    xlSheet.Cells(i, 3).value = Round(itMin, 2) ' Tolérance IT Min
                    xlSheet.Cells(i, 4).value = Round(itMax, 2) ' Tolérance IT Max
                    xlSheet.Cells(i, 5).value = Round(valueMin, 2) ' Valeur min de la cote
                    xlSheet.Cells(i, 6).value = Round(valueMax, 2) ' Valeur max de la cote
                    
                    i = i + 1
                Else
                    Debug.Print "Erreur : swDim est null pour un élément sélectionné."
                End If
            Else
                Debug.Print "L'élément sélectionné n'est pas une cote."
            End If
        Else
            Debug.Print "Erreur : ent est null pour l'élément " & j
        End If
    Next j
    
    ' Ajuster la largeur de la colonne A en fonction de son contenu
    xlSheet.Columns("A:A").AutoFit
    
    MsgBox "Exportation terminée avec succès !", vbInformation
End Sub

tolMin i tolmax są zadeklarowane, ale nigdzie nie jest im przypisana żadna wartość.

Aby uzyskać wartość tolerancji dodałem:

                Dim swDimTol As SldWorks.DimensionTolerance
                Set swDimTol = swDim.Tolerance
                If swDimTol.Type <> swTolType_e.swTolNONE Then
                Debug.Print swDimTol.GetMinValue
                Debug.Print swDimTol.GetMaxValue
                End If

Tuż pod kodem:

                ' Récupérer la valeur de la cote
                value = swDim.value

I dostaję wartość tolerancji w debug.print będę musiał sfinalizować kod z tymi wartościami

A dla twojej informacji, uważaj na czat i towarzystwo GPT, konieczne jest przyjrzenie się i zrozumienie kodu, ponieważ ma on irytującą tendencję do umieszczania bezużytecznego i niedokończonego kodu!
I oczywiście dużo kłopotów z kodem SW (nie jesteś 1-szym, który daje się nabrać)

Redagować:
W przypadku kodu konieczne jest umieszczenie całego kodu w tagu, aby to zrobić, kliknij tutaj, a następnie wklej kod:
image

W przeciwnym razie kod jest nieczytelny. Edytuj swój 1. post i popraw, jeśli to możliwe.

2 polubienia

Musisz pomnożyć wartości tolerancji przez 1000.
W przeciwnym razie błąd jednostki i cala zaokrąglone do 0 za pomocą funkcji Round(value,2).
Dla końcowego kodu, który wydaje się być funkcjonalny:

Option Explicit

Sub main()
ExportCotesVersExcel
End Sub

Sub ExportCotesVersExcel()
Dim swApp As Object
Dim swModel As Object
Dim swDraw As Object
Dim swSelMgr As Object
Dim swDispDim As Object
Dim swDim As Object
Dim xlApp As Object
Dim xlWorkbook As Object
Dim xlSheet As Object
Dim i As Integer
Dim j As Integer
Dim tolMin As Double
Dim tolMax As Double
Dim value As Double
Dim valueMin As Double
Dim valueMax As Double
Dim itMin As Double
Dim itMax As Double

' Créer une instance de SolidWorks (Late Binding)
Set swApp = CreateObject("SldWorks.Application")
Set swModel = swApp.ActiveDoc

' Vérification si un dessin est actif
If swModel Is Nothing Then
    MsgBox "Veuillez ouvrir un dessin 2D avant d'exécuter la macro.", vbExclamation
    Exit Sub
End If

' Vérification du type de document
If swModel.GetType <> 3 Then ' 3 correspond à swDocDRAWING
    MsgBox "Cette macro fonctionne uniquement sur un dessin 2D.", vbExclamation
    Exit Sub
End If

Set swDraw = swModel
Set swSelMgr = swModel.SelectionManager

' Créer une instance d'Excel (Late Binding)
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application") ' Vérifier si Excel est ouvert
If xlApp Is Nothing Then
    Set xlApp = CreateObject("Excel.Application") ' Ouvrir Excel si ce n'est pas le cas
End If
On Error GoTo 0

xlApp.Visible = True
Set xlWorkbook = xlApp.Workbooks.Add
Set xlSheet = xlWorkbook.Sheets(1)

' Entêtes Excel pour les propriétés
xlSheet.Cells(1, 1).value = "Référence M3_2D"
xlSheet.Cells(2, 1).value = "Indice"
xlSheet.Cells(3, 1).value = "Description"

' Ajouter une ligne vide après les propriétés
xlSheet.Cells(4, 1).value = ""

' Récupérer les propriétés du modèle (Référence M3_2D, Indice, Description)
Dim customProps As Object
Set customProps = swModel.Extension.CustomPropertyManager("")

Dim refM3_2D As String
Dim indice As String
Dim description As String

' Essayer de récupérer les propriétés en tenant compte des erreurs
On Error Resume Next
refM3_2D = customProps.Get("Référence M3_2D")
If Err.Number <> 0 Then refM3_2D = "Non disponible"

indice = customProps.Get("Indice")
If Err.Number <> 0 Then indice = "Non disponible"

description = customProps.Get("Description")
If Err.Number <> 0 Then description = "Non disponible"
On Error GoTo 0

' Ajouter les propriétés dans Excel
xlSheet.Cells(1, 2).value = refM3_2D
xlSheet.Cells(2, 2).value = indice
xlSheet.Cells(3, 2).value = description

' Ajouter une ligne vide après les propriétés
xlSheet.Cells(4, 1).value = ""

' Ajouter les en-têtes pour les cotes
xlSheet.Cells(5, 1).value = "Nom de la cote"
xlSheet.Cells(5, 2).value = "Valeur"
xlSheet.Cells(5, 3).value = "IT Min"
xlSheet.Cells(5, 4).value = "IT Max"
xlSheet.Cells(5, 5).value = "Valeur Cote Min"
xlSheet.Cells(5, 6).value = "Valeur Cote Max"

' Vérifier si des cotes sont sélectionnées
Dim nbCotes As Integer
nbCotes = swSelMgr.GetSelectedObjectCount()

If nbCotes = 0 Then
    MsgBox "Veuillez sélectionner des cotes avant d'exécuter la macro.", vbExclamation
    Exit Sub
End If

' Parcours des cotes sélectionnées
i = 6 ' Commencer à la ligne 6 après les propriétés, la ligne vide et les en-têtes
Dim ent As Object
For j = 1 To nbCotes
    Set ent = swSelMgr.GetSelectedObject6(j, -1)
    
    ' Vérifier si l'entité sélectionnée est une cote
    If Not ent Is Nothing Then
        If TypeOf ent Is SldWorks.DisplayDimension Then
            Set swDispDim = ent
            Set swDim = swDispDim.GetDimension
            
            ' Vérification de swDim avant d’accéder à ses valeurs
            If Not swDim Is Nothing Then
                ' Récupérer la valeur de la cote
                value = swDim.value
                
                Dim swDimTol As SldWorks.DimensionTolerance
                Set swDimTol = swDim.Tolerance
                If swDimTol.Type <> swTolType_e.swTolNONE Then
                Debug.Print swDimTol.GetMinValue * 1000
                Debug.Print swDimTol.GetMaxValue * 1000
                End If
                
                ' Calcul des valeurs min et max de la cote
                valueMin = value + (swDimTol.GetMinValue * 1000)
                valueMax = value + (swDimTol.GetMaxValue * 1000)
                
                ' Récupérer les tolérances IT (si disponibles)
                On Error Resume Next
                itMin = swDim.Tolerance.GetMinValue * 1000 '.itMin
                itMax = swDim.Tolerance.GetMaxValue * 1000 '.itMax
                On Error GoTo 0
                
                ' Si les tolérances IT ne sont pas disponibles, les assigner à 0
                If IsError(itMin) Then itMin = 0
                If IsError(itMax) Then itMax = 0
                
                ' Exporter la cote, sa valeur, les tolérances IT et les valeurs min et max dans Excel
                xlSheet.Cells(i, 1).value = swDim.FullName ' Nom de la cote
                xlSheet.Cells(i, 2).value = Round(value, 2) ' Valeur de la cote
                xlSheet.Cells(i, 3).value = Round(itMin, 2) ' Tolérance IT Min
                xlSheet.Cells(i, 4).value = itMax ' Tolérance IT Max
                xlSheet.Cells(i, 5).value = Round(valueMin, 2) ' Valeur min de la cote
                xlSheet.Cells(i, 6).value = Round(valueMax, 2) ' Valeur max de la cote
                
                i = i + 1
            Else
                Debug.Print "Erreur : swDim est null pour un élément sélectionné."
            End If
        Else
            Debug.Print "L'élément sélectionné n'est pas une cote."
        End If
    Else
        Debug.Print "Erreur : ent est null pour l'élément " & j
    End If
Next j

' Ajuster la largeur de la colonne A en fonction de son contenu
xlSheet.Columns("A:A").AutoFit

MsgBox "Exportation terminée avec succès !", vbInformation
End Sub

I pamiętaj, że nigdy nie ufa kotom, są na ziemi tylko po to, by cieszyć się ludźmi!
:dog2::dog2::dog2:Psia siła! :rofl: :rofl: :rofl:

3 polubienia

Więc bardzo dziękuję!! To działa (prawie :grin:)

Przede wszystkim wprowadzono poprawkę formatowania mojego początkowego posta, przepraszam, prawda jest, że jest teraz znacznie bardziej czytelny.

Będąc kompletnym nowicjuszem w VBA, czat GPT (i tym podobne) jest dość przydatny, pozwalając mi tworzyć kody, które trudno byłoby mi napisać samodzielnie, przynajmniej w rozsądnym czasie. Po kilku iteracjach często (nie zawsze) dochodzimy do przyzwoitego wyniku. A jak staram się zrozumieć minimum z czego robi (i to dzięki automatycznemu dodawaniu komentarzy w kodzie), to mówię sobie, że trochę się rozwijam, na siłę :sweat_smile:

Dobra robota dla wartości *1000, powinienem był o tym pomyśleć, już na początku zrobił taką sztuczkę, chcąc przeliczyć na wartości mm, które ... były już w mm :dizzy_face:
Ale stamtąd można sobie wyobrazić, że należy go stosować tylko do tolerancji

Poprawiając mój kod na podstawie Twojego, otrzymuję wartości tolerancji (:+1::clinking_glasses::partying_face:), ale... Nie działa dobrze w przypadku tolerancji symetrycznych.

Jeśli moja ocena nie ma tolerancji, wszędzie mam zero.
Jeśli mój dział IT jest poza centrum (na przykład +0/+0,15 lub -0,2/+0), działa idealnie
Ale jeśli mam +/- 0,15, pokazuje mi tylko 0,15 w polu IT max.

Ale to ogromny krok naprzód, walczę z tym od dzisiejszego poranka!

Nie lubię też kotów :grin:


Option Explicit

Sub main()
    ExportCotesVersExcel
End Sub

Sub ExportCotesVersExcel()
    Dim swApp As Object
    Dim swModel As Object
    Dim swDraw As Object
    Dim swSelMgr As Object
    Dim swDispDim As Object
    Dim swDim As Object
    Dim xlApp As Object
    Dim xlWorkbook As Object
    Dim xlSheet As Object
    Dim i As Integer
    Dim j As Integer
    Dim tolMin As Double
    Dim tolMax As Double
    Dim value As Double
    Dim valueMin As Double
    Dim valueMax As Double
    Dim itMin As Double
    Dim itMax As Double
    
    ' Créer une instance de SolidWorks (Late Binding)
    Set swApp = CreateObject("SldWorks.Application")
    Set swModel = swApp.ActiveDoc
    
    ' Vérification si un dessin est actif
    If swModel Is Nothing Then
        MsgBox "Veuillez ouvrir un dessin 2D avant d'exécuter la macro.", vbExclamation
        Exit Sub
    End If
    
    ' Vérification du type de document
    If swModel.GetType <> 3 Then ' 3 correspond à swDocDRAWING
        MsgBox "Cette macro fonctionne uniquement sur un dessin 2D.", vbExclamation
        Exit Sub
    End If
    
    Set swDraw = swModel
    Set swSelMgr = swModel.SelectionManager
    
    ' Créer une instance d'Excel (Late Binding)
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application") ' Vérifier si Excel est ouvert
    If xlApp Is Nothing Then
        Set xlApp = CreateObject("Excel.Application") ' Ouvrir Excel si ce n'est pas le cas
    End If
    On Error GoTo 0
    
    xlApp.Visible = True
    Set xlWorkbook = xlApp.Workbooks.Add
    Set xlSheet = xlWorkbook.Sheets(1)
    
    ' Entêtes Excel pour les propriétés
    xlSheet.Cells(1, 1).value = "Référence M3_2D"
    xlSheet.Cells(2, 1).value = "Indice"
    xlSheet.Cells(3, 1).value = "Description"
    
    ' Fusionner les cellules B1:F1, B2:F2 et B3:F3 et justifier à gauche
    With xlSheet.Range("B1:F1")
    .Merge
    .HorizontalAlignment = -4131 ' xlLeft
End With
With xlSheet.Range("B2:F2")
    .Merge
    .HorizontalAlignment = -4131 ' xlLeft
End With
With xlSheet.Range("B3:F3")
    .Merge
    .HorizontalAlignment = -4131 ' xlLeft
End With
    
    ' Ajouter une ligne vide après les propriétés
    xlSheet.Cells(4, 1).value = ""
    
    ' Récupérer les propriétés du modèle (Référence M3_2D, Indice, Description)
    Dim customProps As Object
    Set customProps = swModel.Extension.CustomPropertyManager("")

    Dim refM3_2D As String
    Dim indice As String
    Dim description As String
    
    ' Essayer de récupérer les propriétés en tenant compte des erreurs
    On Error Resume Next
    refM3_2D = customProps.Get("Référence M3_2D")
    If Err.Number <> 0 Then refM3_2D = "Non disponible"
    
    indice = customProps.Get("Indice")
    If Err.Number <> 0 Then indice = "Non disponible"
    
    description = customProps.Get("Description")
    If Err.Number <> 0 Then description = "Non disponible"
    On Error GoTo 0
    
    ' Ajouter les propriétés dans Excel
    xlSheet.Cells(1, 2).value = refM3_2D
    xlSheet.Cells(2, 2).value = indice
    xlSheet.Cells(3, 2).value = description
    
    ' Ajouter une ligne vide après les propriétés
    xlSheet.Cells(4, 1).value = ""
    
    ' Ajouter les en-têtes pour les cotes
    xlSheet.Cells(5, 1).value = "Nom de la cote"
    xlSheet.Cells(5, 2).value = "Valeur"
    xlSheet.Cells(5, 3).value = "IT Min"
    xlSheet.Cells(5, 4).value = "IT Max"
    xlSheet.Cells(5, 5).value = "Valeur Cote Min"
    xlSheet.Cells(5, 6).value = "Valeur Cote Max"
    
    ' Vérifier si des cotes sont sélectionnées
    Dim nbCotes As Integer
    nbCotes = swSelMgr.GetSelectedObjectCount()
    
    If nbCotes = 0 Then
        MsgBox "Veuillez sélectionner des cotes avant d'exécuter la macro.", vbExclamation
        Exit Sub
    End If

    ' Parcours des cotes sélectionnées
    i = 6 ' Commencer à la ligne 6 après les propriétés, la ligne vide et les en-têtes
    Dim ent As Object
    For j = 1 To nbCotes
        Set ent = swSelMgr.GetSelectedObject6(j, -1)
        
        ' Vérifier si l'entité sélectionnée est une cote
        If Not ent Is Nothing Then
            If TypeOf ent Is SldWorks.DisplayDimension Then
                Set swDispDim = ent
                Set swDim = swDispDim.GetDimension
                
                ' Vérification de swDim avant d’accéder à ses valeurs
                If Not swDim Is Nothing Then
                    ' Récupérer la valeur de la cote
                      value = swDim.value
                
                Dim swDimTol As SldWorks.DimensionTolerance
                Set swDimTol = swDim.tolerance
                If swDimTol.Type <> swTolType_e.swTolNONE Then
                Debug.Print swDimTol.GetMinValue * 1000
                Debug.Print swDimTol.GetMaxValue * 1000
                End If
                
                '  Calcul des valeurs min et max de la cote
                valueMin = value + (swDimTol.GetMinValue * 1000)
                valueMax = value + (swDimTol.GetMaxValue * 1000)
                
                ' Récupérer les tolérances IT (si disponibles)
                On Error Resume Next
                itMin = swDim.tolerance.GetMinValue * 1000 '.itMin
                itMax = swDim.tolerance.GetMaxValue * 1000 '.itMax
                On Error GoTo 0
                
                ' Si les tolérances IT ne sont pas disponibles, les assigner à 0
                If IsError(itMin) Then itMin = 0
                If IsError(itMax) Then itMax = 0
                
                ' Exporter la cote, sa valeur, les tolérances IT et les valeurs min et max dans Excel
                xlSheet.Cells(i, 1).value = swDim.FullName ' Nom de la cote
                xlSheet.Cells(i, 2).value = Round(value, 2) ' Valeur de la cote
                xlSheet.Cells(i, 3).value = Round(itMin, 2) ' Tolérance IT Min
                xlSheet.Cells(i, 4).value = itMax ' Tolérance IT Max
                xlSheet.Cells(i, 5).value = Round(valueMin, 2) ' Valeur min de la cote
                xlSheet.Cells(i, 6).value = Round(valueMax, 2) ' Valeur max de la cote
                
                i = i + 1
            Else
                Debug.Print "Erreur : swDim est null pour un élément sélectionné."
            End If
        Else
            Debug.Print "L'élément sélectionné n'est pas une cote."
        End If
    Else
        Debug.Print "Erreur : ent est null pour l'élément " & j
    End If
Next j
    
    ' Ajuster la largeur des colonnes pour s'adapter au contenu
    xlSheet.Columns("A:A").AutoFit ' Ajuste la colonne A
    xlSheet.Columns("C:C").AutoFit ' Ajuste la colonne C (IT Min)
    xlSheet.Columns("D:D").AutoFit ' Ajuste la colonne D (IT Max)
    xlSheet.Columns("E:E").AutoFit ' Ajuste la colonne E (Valeur Cote Min)
    xlSheet.Columns("F:F").AutoFit ' Ajuste la colonne F (Valeur Cote Max)
    
    MsgBox "Exportation terminée avec succès !", vbInformation
End Sub

Witam

Nie rozszyfrowałem całego kodu, więc mogą to nie być właściwe zmienne, ale to ma na celu zilustrowanie idei.

Powinieneś być w stanie uciec od porównania takiego jak:
jeśli pole min jest puste, jest to ujemne maksimum (jeśli toMax również nie ma wartości null), więc mówimy mu, aby wyświetlał tę samą wartość co max, ale ze znakiem minus.

If (IsNull(itMin) & Not IsNull(itMax)) Then itMin = -(itMax)

lub

If (IsNull(itMin) & Not IsNull(itMax)) Then itMin = itMax-(itMax*2)

Tak, ale co, jeśli masz tolerancję obustronną, np. +0/+0,2? :grin:

Wtedy itMin ma wartość 0, a zatem nie ma wartości null, więc warunek to " ignorowane ".

Nie widziałem tego w takim stanie, żeby to przetestować :+1:

O ile się nie mylę, powinieneś być w stanie zintegrować go w następujący sposób:

xlSheet.Cells(i, 3).value = Round(IIf((IsNull(itMin) & Not IsNull(itMax)), itMax-(itMax*2), itMin), 2) ' Tolérance IT Min

Zamiast

xlSheet.Cells(i, 3).value = Round(itMin, 2) ' Tolérance IT Min

odszyfrowywanie:
JEŚLI itMin ma wartość Null i itMax ma wartość inną niż Null, TO komórka itMin jest zaokrąglona w górę jako -itMax, w przeciwnym razie komórka itMin jest zaokrąglona itMin

1 polubienie

To nie działa, makro ulega awarii z tym fragmentem kodu. Ale jestem uparty (i leniwy :grin:), więc ponownie wstrzyknąłem poprawione makro do ChatGPT, który zaproponował mi dodanie tego po odzyskaniu min i max IT:


' Vérifier si la tolérance est symétrique et corriger itMin
If swDimTol.Type = swTolType_e.swTolSYMMETRIC Then
    itMin = -itMax
End If

I to działa! Dostaję wszystko z powrotem!

Dziękuję Wam obojgu za pomoc!

Dla tych, którzy chcieliby zrobić podobne makro, oto kompletny kod:

Option Explicit

Sub main()
    ExportCotesVersExcel
End Sub

Sub ExportCotesVersExcel()
    Dim swApp As Object
    Dim swModel As Object
    Dim swDraw As Object
    Dim swSelMgr As Object
    Dim swDispDim As Object
    Dim swDim As Object
    Dim xlApp As Object
    Dim xlWorkbook As Object
    Dim xlSheet As Object
    Dim i As Integer
    Dim j As Integer
    Dim tolMin As Double
    Dim tolMax As Double
    Dim value As Double
    Dim valueMin As Double
    Dim valueMax As Double
    Dim itMin As Double
    Dim itMax As Double
    
    ' Créer une instance de SolidWorks (Late Binding)
    Set swApp = CreateObject("SldWorks.Application")
    Set swModel = swApp.ActiveDoc
    
    ' Vérification si un dessin est actif
    If swModel Is Nothing Then
        MsgBox "Veuillez ouvrir un dessin 2D avant d'exécuter la macro.", vbExclamation
        Exit Sub
    End If
    
    ' Vérification du type de document
    If swModel.GetType <> 3 Then ' 3 correspond à swDocDRAWING
        MsgBox "Cette macro fonctionne uniquement sur un dessin 2D.", vbExclamation
        Exit Sub
    End If
    
    Set swDraw = swModel
    Set swSelMgr = swModel.SelectionManager
    
    ' Créer une instance d'Excel (Late Binding)
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application") ' Vérifier si Excel est ouvert
    If xlApp Is Nothing Then
        Set xlApp = CreateObject("Excel.Application") ' Ouvrir Excel si ce n'est pas le cas
    End If
    On Error GoTo 0
    
    xlApp.Visible = True
    Set xlWorkbook = xlApp.Workbooks.Add
    Set xlSheet = xlWorkbook.Sheets(1)
    
    ' Entêtes Excel pour les propriétés
    xlSheet.Cells(1, 1).value = "Référence M3_2D"
    xlSheet.Cells(2, 1).value = "Indice"
    xlSheet.Cells(3, 1).value = "Description"
    
    ' Fusionner les cellules B1:F1, B2:F2 et B3:F3 et justifier à gauche
    With xlSheet.Range("B1:F1")
    .Merge
    .HorizontalAlignment = -4131 ' xlLeft
End With
With xlSheet.Range("B2:F2")
    .Merge
    .HorizontalAlignment = -4131 ' xlLeft
End With
With xlSheet.Range("B3:F3")
    .Merge
    .HorizontalAlignment = -4131 ' xlLeft
End With
    
    ' Ajouter une ligne vide après les propriétés
    xlSheet.Cells(4, 1).value = ""
    
    ' Récupérer les propriétés du modèle (Référence M3_2D, Indice, Description)
    Dim customProps As Object
    Set customProps = swModel.Extension.CustomPropertyManager("")

    Dim refM3_2D As String
    Dim indice As String
    Dim description As String
    
    ' Essayer de récupérer les propriétés en tenant compte des erreurs
    On Error Resume Next
    refM3_2D = customProps.Get("Référence M3_2D")
    If Err.Number <> 0 Then refM3_2D = "Non disponible"
    
    indice = customProps.Get("Indice")
    If Err.Number <> 0 Then indice = "Non disponible"
    
    description = customProps.Get("Description")
    If Err.Number <> 0 Then description = "Non disponible"
    On Error GoTo 0
    
    ' Ajouter les propriétés dans Excel
    xlSheet.Cells(1, 2).value = refM3_2D
    xlSheet.Cells(2, 2).value = indice
    xlSheet.Cells(3, 2).value = description
    
    ' Ajouter une ligne vide après les propriétés
    xlSheet.Cells(4, 1).value = ""
    
    ' Ajouter les en-têtes pour les cotes
    xlSheet.Cells(5, 1).value = "Nom de la cote"
    xlSheet.Cells(5, 2).value = "Valeur"
    xlSheet.Cells(5, 3).value = "IT Min"
    xlSheet.Cells(5, 4).value = "IT Max"
    xlSheet.Cells(5, 5).value = "Valeur Cote Min"
    xlSheet.Cells(5, 6).value = "Valeur Cote Max"
    
    ' Vérifier si des cotes sont sélectionnées
    Dim nbCotes As Integer
    nbCotes = swSelMgr.GetSelectedObjectCount()
    
    If nbCotes = 0 Then
        MsgBox "Veuillez sélectionner des cotes avant d'exécuter la macro.", vbExclamation
        Exit Sub
    End If

    ' Parcours des cotes sélectionnées
    i = 6 ' Commencer à la ligne 6 après les propriétés, la ligne vide et les en-têtes
    Dim ent As Object
    For j = 1 To nbCotes
        Set ent = swSelMgr.GetSelectedObject6(j, -1)
        
        ' Vérifier si l'entité sélectionnée est une cote
        If Not ent Is Nothing Then
            If TypeOf ent Is SldWorks.DisplayDimension Then
                Set swDispDim = ent
                Set swDim = swDispDim.GetDimension
                
                ' Vérification de swDim avant d’accéder à ses valeurs
                If Not swDim Is Nothing Then
                    ' Récupérer la valeur de la cote
                      value = swDim.value
                
                Dim swDimTol As SldWorks.DimensionTolerance
                Set swDimTol = swDim.tolerance
                If swDimTol.Type <> swTolType_e.swTolNONE Then
                Debug.Print swDimTol.GetMinValue * 1000
                Debug.Print swDimTol.GetMaxValue * 1000
                End If
                
                '  Calcul des valeurs min et max de la cote
                valueMin = value + (swDimTol.GetMinValue * 1000)
                valueMax = value + (swDimTol.GetMaxValue * 1000)
                
                ' Récupérer les tolérances IT (si disponibles)
                On Error Resume Next
                itMin = swDim.tolerance.GetMinValue * 1000 '.itMin
                itMax = swDim.tolerance.GetMaxValue * 1000 '.itMax
                On Error GoTo 0
                
                ' Vérifier si la tolérance est symétrique et corriger itMin
If swDimTol.Type = swTolType_e.swTolSYMMETRIC Then
    itMin = -itMax
End If
                
                ' Si les tolérances IT ne sont pas disponibles, les assigner à 0
                If IsError(itMin) Then itMin = 0
                If IsError(itMax) Then itMax = 0
                
                ' Exporter la cote, sa valeur, les tolérances IT et les valeurs min et max dans Excel
                xlSheet.Cells(i, 1).value = swDim.FullName ' Nom de la cote
                xlSheet.Cells(i, 2).value = Round(value, 2) ' Valeur de la cote
                xlSheet.Cells(i, 3).value = Round(itMin, 2) ' Tolérance IT Min
                xlSheet.Cells(i, 4).value = itMax ' Tolérance IT Max
                xlSheet.Cells(i, 5).value = Round(valueMin, 2) ' Valeur min de la cote
                xlSheet.Cells(i, 6).value = Round(valueMax, 2) ' Valeur max de la cote
                
                i = i + 1
            Else
                Debug.Print "Erreur : swDim est null pour un élément sélectionné."
            End If
        Else
            Debug.Print "L'élément sélectionné n'est pas une cote."
        End If
    Else
        Debug.Print "Erreur : ent est null pour l'élément " & j
    End If
Next j
    
    ' Ajuster la largeur des colonnes pour s'adapter au contenu
    xlSheet.Columns("A:A").AutoFit ' Ajuste la colonne A
    xlSheet.Columns("C:C").AutoFit ' Ajuste la colonne C (IT Min)
    xlSheet.Columns("D:D").AutoFit ' Ajuste la colonne D (IT Max)
    xlSheet.Columns("E:E").AutoFit ' Ajuste la colonne E (Valeur Cote Min)
    xlSheet.Columns("F:F").AutoFit ' Ajuste la colonne F (Valeur Cote Max)
    
    MsgBox "Exportation terminée avec succès !", vbInformation
End Sub




3 polubienia

Uprzedziłem, że przeczytałem kod po przekątnej i że pomysł będzie musiał zostać dostosowany.

Mój ostatni fragment kodu to prawdopodobnie tylko błąd składniowy, ale pierwszy powinien zadziałać. Trzeba jednak przyznać, że testowanie typu zamiast wartości jest niewątpliwie czystsze.