6 Replies Latest reply on Mar 14, 2010 6:07 AM by AMCBridge eXperts

    2 questions 1 macro

    Aaron Larson

      Is it possible for this BoundingBox macro to be used in another macro that traverses an assembly and adds custom properties to the components?  Also is it possible for the BB macro to report the correct trailing zeroes as specified by the document properties?  For instance... (40.000 rather than 40).

        • Re: 2 questions 1 macro
          AMCBridge eXperts

          Yes, it is possible.

           

          Please attach the original macro and I'll help you to update it.

            • Re: 2 questions 1 macro
              Aaron Larson

              Not sure which question you were answering (hopefully both).  Below is the bounding box macro (I've commented out some lines I don't want):

               

              ' **********************************************************************
              ' * This macro gets the bounding box dimensions for the config specific
              ' * model and adds a small amount to it.  This amount can be changed
              ' * by modifying the "AddFactor" value below.  It checks to make sure
              ' * you have a proper document open.  It checks & utilizes the user units.
              ' * It will add 3 separate properties or combine them all into one property.
              ' * It will optionally draw a 3D sketch for you.
              ' *
              ' * Modified by Wayne Tiffany, Oct 12, 2004
              ' * Updated 10/15/04
              ' *
              ' * Original few lines of demo code by someone else (unknown).  Fraction
              ' * converter original code from rocheey.  3D sketch original code from
              ' * SW help.
              ' **********************************************************************

              Dim swApp As SldWorks.SldWorks
              Dim Part As SldWorks.ModelDoc2
              Dim Height As Variant
              Dim Width As Variant
              Dim Length As Variant
              Dim Corners As Variant
              Dim retval As Boolean
              Dim UserUnits As Variant
              Dim ConvFactor As Double
              Dim AddFactor As Double
              Dim ConfigName  As String
              Dim SwConfig As SldWorks.Configuration
              Dim MsgResponse As Integer
              Dim swSketchPt(8) As SldWorks.SketchPoint
              Dim swSketchSeg(12) As SldWorks.SketchSegment

              Const swDocPart = 1
              Const swDocASSEMBLY = 2

              'Enum swLengthUnit_e
              Const swMM = 0
              Const swCM = 1
              Const swMETER = 2
              Const swINCHES = 3
              Const swFEET = 4
              Const swFEETINCHES = 5
              Const swANGSTROM = 6
              Const swNANOMETER = 7
              Const swMICRON = 8
              Const swMIL = 9
              Const swUIN = 10

              'Enum swFractionDisplay_e
              Const swNONE = 0
              Const swDECIMAL = 1
              Const swFRACTION = 2

              Function DecimalToFeetInches(DecimalLength As Variant, Denominator As Integer) As String
                ' converts decimal inches to feet/inches/fractions
                   
                Dim intFeet As Integer
                Dim intInches As Integer
                Dim intFractions As Integer
                Dim FractToDecimal As Double
                Dim remainder As Double
                Dim tmpVal As Double
                
                ' compute whole feet
                intFeet = Int(DecimalLength / 12)
                remainder = DecimalLength - (intFeet * 12)
                tmpVal = CDbl(Denominator)

                ' compute whole inches
                intInches = Int(remainder)
                remainder = remainder - intInches
                
                ' compute fractional inches & check for division by zero
                If Not (remainder = 0) Then
                  If Not (Denominator = 0) Then
                    FractToDecimal = 1 / tmpVal
                      If FractToDecimal > 0 Then
                        intFractions = Int(remainder / FractToDecimal)
                        If (remainder / FractToDecimal) - intFractions > 0 Then  ' Round up so bounding box is always larger.
                          intFractions = intFractions + 1
                        End If
                      End If
                   End If
                End If
                    'Debug.Print "Feet = " & intFeet & ", Inches = " & intInches & ", Numerator = " & intFractions & ", Denominator = " & FractToDecimal
                Call FractUp(intFeet, intInches, intFractions, Denominator) ' Simplify up & down
               
                ' format output
                DecimalToFeetInches = LTrim$(Str$(intFeet)) & "'-"
                DecimalToFeetInches = DecimalToFeetInches & LTrim$(Str$(intInches))
                If intFractions > 0 Then
                  DecimalToFeetInches = DecimalToFeetInches & " "
                  DecimalToFeetInches = DecimalToFeetInches & LTrim$(Str$(intFractions))
                  DecimalToFeetInches = DecimalToFeetInches & "\" & LTrim$(Str$(Denominator))
                End If
                 
                DecimalToFeetInches = DecimalToFeetInches & Chr$(34)
                    'Debug.Print DecimalToFeetInches

              End Function

              Function FractUp(InputFt As Integer, InputInch As Integer, InputNum As Integer, InputDenom As Integer)
                 
                     'Debug.Print InputFt, InputInch, InputNum, InputDenom
               
                ' Simplify the fractions, Example: 6/8" becomes 3/4"
                While InputNum Mod 2 = 0 And InputDenom Mod 2 = 0
                  InputNum = InputNum / 2
                  InputDenom = InputDenom / 2
                Wend
               
                ' See if we now have a full inch or 12 inches.  If so, bump stuff up
                If InputDenom = 1 Then  ' Full inch
                  InputInch = InputInch + 1
                  InputNum = 0
                  If InputInch = 12 Then  ' Full foot
                    InputFt = InputFt + 1
                    InputInch = 0
                  End If
                End If
                     'Debug.Print InputFt, InputInch, InputNum, InputDenom
                     
              End Function

              Function GetCurrentConfigName()
               
                Set SwConfig = Part.GetActiveConfiguration  ' See what config we are now on & set the variable
                GetCurrentConfigName = Part.GetActiveConfiguration.Name  ' Return the name

              End Function

              Sub DrawBox()
                 
                Part.Insert3DSketch2 True
                Part.SetAddToDB True
                Part.SetDisplayWhenAdded False

                'Draw points at each corner of bounding box
                Set swSketchPt(0) = Part.CreatePoint2(Corners(3), Corners(1), Corners(5))
                Set swSketchPt(1) = Part.CreatePoint2(Corners(0), Corners(1), Corners(5))
                Set swSketchPt(2) = Part.CreatePoint2(Corners(0), Corners(1), Corners(2))
                Set swSketchPt(3) = Part.CreatePoint2(Corners(3), Corners(1), Corners(2))
                Set swSketchPt(4) = Part.CreatePoint2(Corners(3), Corners(4), Corners(5))
                Set swSketchPt(5) = Part.CreatePoint2(Corners(0), Corners(4), Corners(5))
                Set swSketchPt(6) = Part.CreatePoint2(Corners(0), Corners(4), Corners(2))
                Set swSketchPt(7) = Part.CreatePoint2(Corners(3), Corners(4), Corners(2))
               
                ' Now draw bounding box
                Set swSketchSeg(0) = Part.CreateLine2(swSketchPt(0).X, swSketchPt(0).Y, swSketchPt(0).Z, swSketchPt(1).X, swSketchPt(1).Y, swSketchPt(1).Z)
                Set swSketchSeg(1) = Part.CreateLine2(swSketchPt(1).X, swSketchPt(1).Y, swSketchPt(1).Z, swSketchPt(2).X, swSketchPt(2).Y, swSketchPt(2).Z)
                Set swSketchSeg(2) = Part.CreateLine2(swSketchPt(2).X, swSketchPt(2).Y, swSketchPt(2).Z, swSketchPt(3).X, swSketchPt(3).Y, swSketchPt(3).Z)
                Set swSketchSeg(3) = Part.CreateLine2(swSketchPt(3).X, swSketchPt(3).Y, swSketchPt(3).Z, swSketchPt(0).X, swSketchPt(0).Y, swSketchPt(0).Z)
                Set swSketchSeg(4) = Part.CreateLine2(swSketchPt(0).X, swSketchPt(0).Y, swSketchPt(0).Z, swSketchPt(4).X, swSketchPt(4).Y, swSketchPt(4).Z)
                Set swSketchSeg(5) = Part.CreateLine2(swSketchPt(1).X, swSketchPt(1).Y, swSketchPt(1).Z, swSketchPt(5).X, swSketchPt(5).Y, swSketchPt(5).Z)
                Set swSketchSeg(6) = Part.CreateLine2(swSketchPt(2).X, swSketchPt(2).Y, swSketchPt(2).Z, swSketchPt(6).X, swSketchPt(6).Y, swSketchPt(6).Z)
                Set swSketchSeg(7) = Part.CreateLine2(swSketchPt(3).X, swSketchPt(3).Y, swSketchPt(3).Z, swSketchPt(7).X, swSketchPt(7).Y, swSketchPt(7).Z)
                Set swSketchSeg(8) = Part.CreateLine2(swSketchPt(4).X, swSketchPt(4).Y, swSketchPt(4).Z, swSketchPt(5).X, swSketchPt(5).Y, swSketchPt(5).Z)
                Set swSketchSeg(9) = Part.CreateLine2(swSketchPt(5).X, swSketchPt(5).Y, swSketchPt(5).Z, swSketchPt(6).X, swSketchPt(6).Y, swSketchPt(6).Z)
                Set swSketchSeg(10) = Part.CreateLine2(swSketchPt(6).X, swSketchPt(6).Y, swSketchPt(6).Z, swSketchPt(7).X, swSketchPt(7).Y, swSketchPt(7).Z)
                Set swSketchSeg(11) = Part.CreateLine2(swSketchPt(7).X, swSketchPt(7).Y, swSketchPt(7).Z, swSketchPt(4).X, swSketchPt(4).Y, swSketchPt(4).Z)

                Part.SetDisplayWhenAdded True
                Part.SetAddToDB False
                Part.Insert3DSketch2 True

              End Sub

              Sub Main()

              AddFactor = 0      ' This is the amount added - change to suit

              Set swApp = CreateObject("SldWorks.Application")
              Set Part = swApp.ActiveDoc

              If Part Is Nothing Then                    ' Did we get anything?
                MsgBox "You need to have a part or assy open at this point." & Chr$(13) & Chr$(10) _
                        & Chr$(10) & "Open one and try again."
                Exit Sub
              End If

              If (Part.GetType = swDocPart) Then
                Corners = Part.GetPartBox(True)         ' True comes back as system units - meters
              ElseIf Part.GetType = swDocASSEMBLY Then  ' Units will come back as meters
                Corners = Part.GetBox(0)
              Else
                MsgBox "This macro is only useful with a part or assy." & Chr$(13) & Chr$(10) & "Open one of those and try again."
                Exit Sub
              End If

              UserUnits = Part.GetUnits()
                'Debug.Print "LengthUnit = " & UserUnits(0)
                'Debug.Print "Fraction Base = " & UserUnits(1)
                'Debug.Print "FractionDenominator = " & UserUnits(2)
                'Debug.Print "SignificantDigits = " & UserUnits(3)
                'Debug.Print "RoundToFraction = " & UserUnits(4)
               
              Select Case Part.GetUnits(0)
                Case swMM
                  ConvFactor = 1 * 1000
                Case swCM
                  ConvFactor = 1 * 100
                Case swMETER
                  ConvFactor = 1
                Case swINCHES
                  ConvFactor = 1 / 0.0254
                Case swFEET
                  ConvFactor = 1 / (0.0254 * 12)
                Case swFEETINCHES
                  ConvFactor = 1 / 0.0254  ' Pass inches through
                Case swANGSTROM
                  ConvFactor = 10000000000#
                Case swNANOMETER
                  ConvFactor = 1000000000
                Case swMICRON
                  ConvFactor = 1000000
                Case swMIL
                  ConvFactor = (1 / 0.0254) * 1000
                Case swUIN
                  ConvFactor = (1 / 0.0254) * 1000000
              End Select

              Height = Round((Abs(Corners(4) - Corners(1)) * ConvFactor) + AddFactor, UserUnits(3)) ' Z axis
              Width = Round((Abs(Corners(5) - Corners(2)) * ConvFactor) + AddFactor, UserUnits(3))  ' Y axis
              Length = Round((Abs(Corners(3) - Corners(0)) * ConvFactor) + AddFactor, UserUnits(3)) ' X axis
                  'Debug.Print Height & " x " & Width & " x " & Length

              ' Check for either (Feet-Inches OR Inches) AND fractions.  If so, return Ft-In
              If (UserUnits(0) = 5 Or UserUnits(0) = 3) And UserUnits(1) = 2 Then
                Height = DecimalToFeetInches(Height, Val(UserUnits(2)))
                Width = DecimalToFeetInches(Width, Val(UserUnits(2)))
                Length = DecimalToFeetInches(Length, Val(UserUnits(2)))
              End If
                  'Debug.Print Height & " x " & Width & " x " & Length

              ConfigName = GetCurrentConfigName() ' See what config we are now on

              ' MsgBoxMsg = "The default for this program is to combine the 3 values into one property." & Chr$(13) & Chr$(10) _
                     '  & "Do you want to keep it this way?" & Chr$(13) & Chr$(10) _
                     ' & Chr$(10) & "(Clicking the No button will add 3 separate properties.)"

              ' MsgResponse = MsgBox(MsgBoxMsg, vbInformation + vbYesNoCancel)

              ' If MsgResponse = vbYes Then  ' One property
                 retval = Part.DeleteCustomInfo2(ConfigName, "Finished Size") 'Remove existing properties
                 retval = Part.AddCustomInfo3(ConfigName, "Finished Size", swCustomInfoText, _
                         Height & " x " & Width & " x " & Length)  'Add latest values
              ' ElseIf MsgResponse = vbNo Then  ' 3 properties
                'Remove existing properties
                ' retval = Part.DeleteCustomInfo2(ConfigName, "Height")
                ' retval = Part.DeleteCustomInfo2(ConfigName, "Width")
                ' retval = Part.DeleteCustomInfo2(ConfigName, "Length")
                'Add latest values
                ' retval = Part.AddCustomInfo3(ConfigName, "Height", swCustomInfoNumber, Height)
                ' retval = Part.AddCustomInfo3(ConfigName, "Width", swCustomInfoNumber, Width)
                ' retval = Part.AddCustomInfo3(ConfigName, "Length", swCustomInfoNumber, Length)
              ' Else
                Exit Sub
              ' End If

              ' MsgBoxMsg = "Do you want to draw a 3D sketch that represents the bounding box?" & Chr$(13) & Chr$(10) _
                      & "This is a good way to visualize the dimensions."

              ' MsgResponse = MsgBox(MsgBoxMsg, vbInformation + vbYesNo)

              ' If MsgResponse = vbYes Then Call DrawBox

              End Sub

              • Re: 2 questions 1 macro
                Aaron Larson

                Here is the macro for which I'd like to insert the BB macro.  You can see it at the bottom of the macro - it is currently commented out.

                 

                Option Explicit


                Dim swApp As SldWorks.SldWorks

                Sub main()
                Dim swModel As ModelDoc2

                Dim vComps As Variant
                Dim swComp As SldWorks.Component2
                Dim swAssy As SldWorks.AssemblyDoc
                Dim i As Integer
                Set swApp = Application.SldWorks
                Set swModel = swApp.ActiveDoc

                updateProperty swModel

                If swModel.GetType = swDocASSEMBLY Then
                    Set swAssy = swModel
                    vComps = swAssy.GetComponents(False)
                    For i = 0 To UBound(vComps)
                        Set swComp = vComps(i)
                        If swComp.GetSuppression = swComponentFullyResolved Then
                            Set swModel = swComp.GetModelDoc2
                            updateProperty swModel
                        Else
                           
                        End If
                    Next i
                End If


                End Sub

                Function updateProperty(swModel As SldWorks.ModelDoc2) As Boolean
                Dim cpm As CustomPropertyManager


                Dim path As String, filename As String, GenericDescription As String
                Dim DescVal As String
                Dim RetVal As Boolean

                'Sets Generic Description Property to Filename w/TN parsed
                Set cpm = swModel.Extension.CustomPropertyManager("")
                    'gets pathname
                path = swModel.GetPathName
                filename = Mid$(path, InStrRev(path, "\") + 1) ' With extension
                filename = Left$(filename, InStrRev(filename, ".") - 1) ' Remove extension
                    'Strips T/N if "T" is prefix
                If InStr(Left(filename, 1), "t") = True Then
                    GenericDescription = UCase(Right(filename, Len(filename) - 7))
                Else
                    'Strips T/N if no "T" previx
                    GenericDescription = UCase(Right(filename, Len(filename) - 6))
                  
                End If

                'Replaces underscores with spaces
                GenericDescription = Replace(GenericDescription, "_", " ")

                'If no prop "GenericDescription" exists--> adds it with GenericDescription
                cpm.Add2 "GenericDescription", swCustomInfoText, GenericDescription
                'If "GenericDescription" already exists--> changes value to GenericDescription
                cpm.Set "GenericDescription", GenericDescription

                 

                'Adds concantenated "Description Property"
                Set cpm = swModel.Extension.CustomPropertyManager("")
                DescVal = "$PRP:""GenericDescription"" $PRP:""ConfigDescription"""
                cpm.Add2 "Description", swCustomInfoText, DescVal
                cpm.Set "Description", DescVal

                RetVal = swModel.DeleteCustomInfo2("", "Material")
                RetVal = swModel.AddCustomInfo2("Material", 30, """SW-Material@FileName.SLDPRT""")
                ' RetVal = swApp.RunMacro("I:\ME\Tooling Standards\Solidworks\Macros\BoundingBox.swp", "BoundingBoxCode", "Main")

                End Function

                  • Re: 2 questions 1 macro
                    AMCBridge eXperts

                    Excuse me for the delayed responce.

                     

                    It seems your first issue is resolved with the last macro. As I can see you already traverses all the components within the assembly and run the BB macro. Isn't it?

                     

                    As for your second issue. You could get the decimal places number using the following method:

                     

                    IModelDocExtension::GetUserPreferenceInteger(swUserPreferenceIntegerValue_e.swDetailingLinearDimPrecision,  swUserPreferenceOption_e.swDetailingDimension)

                     

                    Next add required number of '0' to your value which should go to Custom Properties.

                      • Re: 2 questions 1 macro
                        Aaron Larson

                        I believe what is happening in the macro is that during the traversing, IF the model is fully resolved it calls the "updateProperty" function. The BB macro call is the last line of that function.  Wouldln't the BB macro then get called inside that function?  I have also tried calling the BB macro directly in the traversing IF statement and that doesn't work either.

                         

                        Regarding the decimal places - I don't think I'm experienced enough to know where to put that snippet or how it functions.  Any help would be appreciated.  When you say "Next add required number of '0' to your value which should go to Custom Properties" you mean this is something that would be added to the code so that the proper number of zeroes would automatically input into the custom property?

                          • Re: 2 questions 1 macro
                            AMCBridge eXperts
                            Here is the small sample how to format the number depending of decimal places count. You should pass the model's doc pointer to the
                            RoundToDecPlaces function and the value you would like to format. Is it what are you looking for?

                            Dim swApp As SldWorks.SldWorks

                            Sub main()

                                Set swApp = Application.SldWorks
                               
                                Dim roundVal As String
                                roundVal = RoundToDecPlaces(swApp.ActiveDoc, 40)
                               
                            End Sub

                            Function RoundToDecPlaces(swModel As SldWorks.ModelDoc2, val As Double) As String
                               
                                Dim decPlaces As Integer
                                Dim retVal As String
                               
                                decPlaces = swModel.Extension.GetUserPreferenceInteger(swUserPreferenceIntegerValue_e.swDetailingLinearDimPrecision, swUserPreferenceOption_e.swDetailingDimension)
                                   
                                retVal = FormatNumber(val, decPlaces)
                               
                            End Function