4 Replies Latest reply on Aug 15, 2017 5:59 AM by Raymond Yau

    Get specific weldment 'LENGTH' - loop/iterate

    Raymond Yau

      Hi,

       

      I'm attemping to put together a macro which iterates through each part configuration and then loops through the cut-list in a part file to look within each cut-list item for a variable called 'LENGTH'. If the variable exists, then it will add it to the 'Configuration Specific' properties list (or just print it to the debug console for the time being).

       

      Here's my irrational code thus far:

       

      Sub main()

          Dim swApp           As SldWorks.SldWorks

          Dim swModel         As SldWorks.ModelDoc2

          Dim swFeat          As SldWorks.Feature

          Dim swCustPropMgr   As SldWorks.CustomPropertyManager

          Dim swConfig        As SldWorks.Configuration

          Dim strValue        As String

          Dim vConfNameArr    As Variant

          Dim swConfigName    As String

          Dim i               As Long

         

          Set swApp = Application.SldWorks

          Set swModel = swApp.ActiveDoc

         

          Set swCustPropMgr = swModel.Extension.CustomPropertyManager(swConfigName)

       

          vConfNameArr = swModel.GetConfigurationNames 'get full list of configurations

         

          For i = 0 To UBound(vConfNameArr) 'Do this for all configurations

         

          swConfigName = vConfNameArr(i)

       

          Do While Not swFeat Is Nothing 'Do this for all cut-list items

                   

                  Set swCustPropMgr = swFeat.CustomPropertyManager

                 

                  If swCustPropMgr.Get4 = "LENGTH" Then 'if LENGTH exists then get value

                                         

                  swCustPropMgr.Get4 "LENGTH", False, Empty, strValue

                 

                  Debug.Print (strValue) 'Print length valuen to console

                   

                  Exit Do

              End If

              Set swFeat = swFeat.GetNextFeature

          Loop

       

          Next i

         

      End Sub

       

      I'm thinking of a boolean instead of an if statement (at the point highlighted). I know it doesn't make much sense at the moment.

       

      Can someone point me in the right direction?

       

      Cheers,

       

      Ray

        • Re: Get specific weldment 'LENGTH' - loop/iterate
          Deepak Gupta

          Try this

           

          Option Explicit
              Dim swApp           As SldWorks.SldWorks
              Dim swModel         As SldWorks.ModelDoc2
              Dim swFeat          As SldWorks.Feature
              Dim swCustPropMgr   As SldWorks.CustomPropertyManager
              Dim swConfig        As SldWorks.Configuration
              Dim vConfNameArr    As Variant
              Dim swConfigName    As String
              Dim i               As Long
              Dim strValue(1)     As String
              Dim swBodyFolder    As SldWorks.BodyFolder
          
          Sub main()
              Set swApp = Application.SldWorks
              Set swModel = swApp.ActiveDoc   
              Set swCustPropMgr = swModel.Extension.CustomPropertyManager(swConfigName)
              vConfNameArr = swModel.GetConfigurationNames 'get full list of configurations
             
              For i = 0 To UBound(vConfNameArr) 'Do this for all configurations
              swConfigName = vConfNameArr(i)
              Set swFeat = swModel.FirstFeature
                  Do While Not swFeat Is Nothing
                      If swFeat.GetTypeName = "SolidBodyFolder" Or swFeat.GetTypeName = "CutListFolder" Or swFeat.GetTypeName = "SubWeldFolder" Then
                       Set swBodyFolder = swFeat.GetSpecificFeature2
                       Set swCustPropMgr = swFeat.CustomPropertyManager
                       swFeat.CustomPropertyManager.Get4 "LENGTH", False, strValue(0), strValue(1)
                       Debug.Print strValue(1)
                       End If
                  Set swFeat = swFeat.GetNextFeature
                  Loop
              Next i
              
          End Sub
          
            • Re: Get specific weldment 'LENGTH' - loop/iterate
              Raymond Yau

              Hi Deepak,

               

              Thanks for sorting out my code, I can now get an output 'LENGTH' value from the cut-list items. However, I noticed that in scenarios where bodies grouped into folders, Solidworks see them as a single body and only gives me a single Length output (See below):

               

              To get around the problem, there's a couple of ways which I can think of doing this:

              1. Use 'Get4' fucntion again to get the 'QUANTITY' value from CustomProps list, so then I can manipulate 'LENGTH' and 'QUANTITY' to get the total length and for other purposes.
              2. Another way I can think of doing this is to create sub-weldments of any grouped bodies (its the best and most ideal way for me since I have a lot of parts with existing sub-weldment bodies/folders). This should give me the breakdown of the output.

               

              On the first approach, I tried casting strValue(1) to a Double so I can manipulate the 'Length' and ''Quantity' values later but it doesn't seem to like it very much and keeps throwing up a 'Type mismatch error' ===> CDbl(strValue(1)).

               

              On the second approach, I created sub-weldments manually for each body, and it now successfully outputs the individual 'Length' values for each item/body, which is great! I had to remove the swFeat.GetTypeName = "SubWeldFolder" because it also produces duplicate Length values since there is now an extra Tier within the Cut-list Hierarchy.

              But I guess my questions now would be:

              1. What's the best way to create subweldments automatically without me having to go through all my parts, configs and cut-lists and manually create subweldments?
              2. And finally, the output strValue(1) variable from the Get4 function is still returns a string. How can I convert this to a Double so I can use it later for some logic? (I've tried CDbl(strValue(1)) and Convert.ToDecimal(strValue(1)).

               

              Thanks again

            • Re: Get specific weldment 'LENGTH' - loop/iterate
              John Alexander

              How are you getting custom properties to be associated with a body? As far as I'm aware, the "custom property manager" is a document-level object that can be split into configurations. I'm not aware of it being a body-level deal. Are the bodies' lengths assigned to separate configurations in your model?

               

              Also, at first glance, it doesn't look like swFeat is ever assigned a value so the macro will never enter the while loop.

              It doesn't seem like you are looping over cut list items (which are Bodies) but rather Features in the part. You can loop over all features in a part, but this will include all bodies also. If you need specific bodies, you need to loop over the bodies.

               

              2012 SOLIDWORKS API Help - GetBodies2 Method (IPartDoc)

               

               

              Regarding your bolded lines, according to the documentation:

              2012 SOLIDWORKS API Help - Get4 Method (ICustomPropertyManager)

               

              swCustPropMgr.Get4 should return False if it fails.

               

              You could do something like the following

              if swCustPropMgr.Get4("LENGTH", False, Empty, strValue) then

                   'get4 succeeded, do what you need to with strValue

              else

                   'get4 failed, handle that (or don't and jump to the next cut list item)

              end if

                • Re: Get specific weldment 'LENGTH' - loop/iterate
                  Raymond Yau

                  Hi John,

                   

                  Thanks for your input, I have a question about Visual Basic If Else statements in general. Say if I wanted to get the QUANTITY value only from a body which contains a LENGTH variable. It would be something such as:

                   

                  if swCustPropMgr.Get4("LENGTH", False, Empty, strValue) then

                       swFeat.CustomPropertyManager.Get4("Quantity", False, Empty, strValue(1))

                  else

                       Continue '(to next item) I know in C# its continue or break, but not sure about VB.

                  end if

                  Would the above be a good way to go about doing this? Also, do I even need an else statement for the above?