7 Replies Latest reply on Jun 1, 2018 10:51 AM by Ivana Kolin

    Macro to select the first component in the model tree

    Mike Childs

      I created an assembly and and have assembled a part that is used as a skeleton to attach the rest of the components. The skeleton part will always be the first component in the model tree and all of the other component placement dimensions are in that part. I need to be able to edit the skeleton part in my macro to modify the dimensions whenever there is a change to the assembly but the part name will vary every time the assembly is copied to a new folder within our PDM vault. Can anyone suggest a way I can select the skeleton component for editing regardless of what the component name is.

       

      Another forum post I came across suggested an example to traverse the assembly at https://forum.solidworks.com/external-link.jspa?url=http%3A%2F%2Fhelp.solidworks.com%2F2016%2Fenglish%2Fapi%2Fsldworksap… but I'm hoping there is a simpler way to find the first component.

       

      For clarification. The assembly will only have one config and the first assembled component, which is the skeleton part, will never be suppressed.

       

      Thanks for the help.

        • Re: Macro to select the first component in the model tree
          Artem Taturevych

          Try this

           

          Dim swApp As SldWorks.SldWorks

          Dim swAssy As SldWorks.AssemblyDoc

           

          Sub main()

           

              Set swApp = Application.SldWorks

           

              Set swAssy = swApp.ActiveDoc

             

              Dim vComps As Variant

             

              vComps = swAssy.GetComponents(True)

             

              Dim swComp As SldWorks.Component2

             

              Set swComp = vComps(0)

             

              swComp.Select4 False, Nothing, False

             

          End Sub

            • Re: Macro to select the first component in the model tree
              Mike Childs

              Thanks Artem.

               

              I had originally wrote my macro to edit a part in context in order to change dimensions and was trying to find the first assembled component as most of the dimensions are placed there. I would prefer to simply modify the component dimension at the assembly level and have been trying to find a way to do that but can't seem to get it to work. This is what I've come up with so far, bear in mind I have programmed in VB.NET before but I'm new to programming in VBA for SW:

               

              Dim swApp As SldWorks.SldWorks

              Dim swMdl As SldWorks.ModelDoc2

              Dim swAssy As SldWorks.AssemblyDoc

              Dim swComp As SldWorks.Component2

              Dim swComponents() As SldWorks.Component2

              Dim swPart As SldWorks.PartDoc

              Dim swDim As SldWorks.Dimension

              Dim rowCount As Integer

              Dim ComponentCount As Integer

              Dim atMarker As Integer

              Dim propName()

              Dim propValue()

               

              Set swApp = Application.SldWorks

              Set swMdl = swApp.ActiveDoc

              Set swAssy = swMdl

               

              swComponents() = swAssy .GetComponents(False)

                   For ComponentCount = 0 To swAssy .GetComponentCount(False) - 1

                        Set swComp = swComponents(ComponentCount)

                        Set swPart = swComp.GetModelDoc2

                        If Not swPart Is Nothing Then

                             Set swDim = swPart.Parameter(Right(propName(rowCount), Len(propName(rowCount)) - atMarker))

                             If Not swDim Is Nothing Then

                                  swDim.SystemValue = propValue(rowCount)

                             End If

                        End If

                   Next ComponentCount

               

              When debugging, swPart is always being set to Nothing and therefore is not triggering the lines to change the dimension. Is there an additional step I need to do?

                • Re: Macro to select the first component in the model tree
                  Josh Brady

                  Your VBA syntax needs some spiffin' up.

                  GetComponents returns an array.  However, you don't know what size it is.  I'm pretty sure that in VBA the only variable that can receive an array of unknown size or type is a Variant.

                  I'm not even sure if you can use a Component2 array to receive the result from GetComponents if you resize it prior to.  Using a Variant is the way shown in the API help examples for VBA.

                    • Re: Macro to select the first component in the model tree
                      Mike Childs

                      Thanks Josh. The code I've shown does appear to populate the array, when debugging it adds 109 components to the array. I had originally used a ReDim command to set the array size but this seemed to work. It might be worthwhile to put it back in though.

                       

                      I tried your suggestion to change the array to a Variant but I get a type mismatch error when running it.

                        • Re: Macro to select the first component in the model tree
                          Josh Brady
                          Dim swApp As SldWorks.SldWorks
                          
                          
                          Dim swMdl As SldWorks.ModelDoc2
                          
                          
                          Dim swAssy As SldWorks.AssemblyDoc
                          
                          
                          Dim swComp As SldWorks.Component2
                          
                          
                          Dim swComponents As Variant
                          
                          
                          Dim swPart As SldWorks.ModelDoc2
                          
                          
                          Dim swDim As SldWorks.Dimension
                          
                          
                          Dim rowCount As Integer
                          
                          
                          Dim ComponentCount As Integer
                          
                          
                          Dim atMarker As Integer
                          
                          
                          Dim propName()
                          
                          
                          Dim propValue()
                          
                          
                          Sub poo()
                          
                          
                          
                          
                          
                          
                          Set swApp = Application.SldWorks
                          
                          
                          Set swMdl = swApp.ActiveDoc
                          
                          
                          Set swAssy = swMdl
                          
                          
                          
                          
                          
                          swComponents = swAssy.GetComponents(False)
                          
                          
                               For ComponentCount = 0 To UBound(swComponents)
                          
                          
                                    Set swComp = swComponents(ComponentCount)
                          
                          
                                    Set swPart = swComp.GetModelDoc2
                                    Debug.Print swPart.GetPathName
                          
                          
                                    If Not swPart Is Nothing Then
                          
                          
                                         Set swDim = swPart.Parameter("D1@Sketch2")
                          
                          
                                         If Not swDim Is Nothing Then
                          
                          
                                              Debug.Print swDim.Value
                          
                          
                                         End If
                          
                          
                                    End If
                          
                          
                               Next ComponentCount
                          End Sub
                          

                           

                          This works for me.  Note that swPart is declared as ModelDoc2 instead of PartDoc.  If the first component returned is a subassembly then you'll get a mismatch if it's PartDoc.

                    • Re: Macro to select the first component in the model tree
                      Ivana Kolin

                      GetComponents

                      The components returned by this method can be in any order. You should not rely on the order to indicate anything about children or parents. If the hierarchy and order are important, then use IModelDoc2::FirstFeature, IFeature::GetTypeName2, IFeature::GetSpecificFeature2, IComponent2::FirstFeature, and IFeature::GetNextFeature to retrieve your information.