Pb recovery tolerance in VBA

Hi all

I try to create a macro to extract a series of selected dimensions in a plan, and export them to Excel.
I recover three properties, allowing to quickly identify the file from which the dimensions were extracted.

The macro works perfectly (the layout is Ok, the properties are retrieved, the selected dimensions appear well), except that the tolerances systematically come out to zero...

Chat GPT, which was a great help to me when creating this macro, stumbles on the problem. Another AI, Claude, could not do better.

Does anyone know what makes the zero value systematically rise? I specify that on the dimensions that I select on my plan to test have a tolerance, symmetrical, of +/-0.15, entered directly from the property manager quote.

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 and tolmax are declared but no value is assigned to them anywhere.

To retrieve the value of a tolerance I added:

                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

just below your code:

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

And I get the value of the tolerances in the debug.print will have to finalize the code with these values

And for your information, beware of GPT chat and company, it is imperative to look at and understand the code because it has an annoying tendency to put useless and unfinished code!
And obviously a lot of trouble on SW code (you're not the 1st to be fooled)

Edit:
For the code it is imperative to put the entire code in a tag, to do this click here and then paste the code:
image

Otherwise the code is unreadable. Please edit your 1st post and correct if possible.

2 Likes

You have to multiply the tolerance values by 1000.
Otherwise unit error and cala rounded to 0 with the Round(value,2) function.
For the final code that seems to be functional:

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

And remember never trusts cats, they are on earth only to enjoy humans!
:dog2::dog2::dog2:Dog power! :rofl: :rofl: :rofl:

3 Likes

So thank you very much!! it works (almost :grin:)

First of all, correction made for the formatting of my initial post, my flattest apologies, it's true that it's much more readable now.

Being a complete neophyte in VBA, chat GPT (and the like) is rather useful, allowing me to make codes that I would be hard pressed to write by myself, at least in a reasonable time. After several iterations, we often (not all the time) arrive at a decent result. And as I try to understand a minimum of what it does (and here thanks to the automatic addition of comments in the code), I tell myself that I am progressing a little, by force :sweat_smile:

Well done for the *1000 values, I should have thought about it, he already did a trick like that at the beginning, wanting to convert into mm values that ... were already in mm :dizzy_face:
But from there to imagine that it should be applied only to tolerances

By correcting my code based on yours, I do get the tolerance values (:+1::clinking_glasses::partying_face:) but... It doesn't work well for symmetrical tolerances.

If my rating has no tolerance, I have zero everywhere.
If my IT is off-center (for example +0/+0.15, or -0.2/+0), it works perfectly
But if I have +/-0.15, it only shows me 0.15 in the IT max box.

But it's a huge step forward, I've been fighting with it since this morning!

And I don't like cats either :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

Hello

I haven't decoded all the code so these might not be the right variables but it's to illustrate the idea.

You should be able to get away with a comparison like:
if the min box is empty it is the negative of max (if itMax is not null either), so we tell it to display the same value as max but with the minus sign.

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

or

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

yes but what if you have a bilateral tolerance, like +0/+0.2? :grin:

Then itMin is 0, and therefore not null, so the condition is " ignored ".

I hadn't seen it like that, to test, indeed :+1:

Unless I'm mistaken, you should be able to integrate it as follows:

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

Instead of

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

decryption:
IF itMin is Null and itMax is non-Null, THEN the itMin cell is -itMax rounded up, OTHERWISE the itMin cell is rounded itMin

1 Like

It doesn't work, the macro crashes with this piece of code. But stubborn (and lazy :grin:) I am, so I reinjected the corrected macro into ChatGPT who offered me to add this after the recovery of the min and 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

And it works! I get everything back!

Thank you both for your help!

For those who would like to make a similar macro, here is the complete code:

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




2 Likes

I had warned that I had read the code diagonally and that the idea would have to be adapted.

My last piece of code is probably just a syntax error, but the first one should have worked. But admittedly, testing the type instead of the value is indeed undoubtedly cleaner.