3 Replies Latest reply on Feb 6, 2017 5:45 PM by Keith Rice

    Regenerate Macro Feature using SwComFeature

    Brian Smith

      I am trying to write a macro that does two things.

      1.) A Control-Q rebuild

      2.) Traverse assemblies and all sub-assemblies for nonread-only parts and rebuild any macro feature in them


      I am doing this because calling a "full-full" rebuild (   swModel.ForceRebuild3(false)  ) takes a very long time for our assemblies because it is literally rebuilding every feature in every part and assembly. This "full-full" rebuild comes from: 2016 SOLIDWORKS API Help - Force Rebuild Example (VBA) and was the start of my macro.


      This is currently the only way I know how to force a rebuild on lower level macro features. The macro I am trying to write now is meant to replace the control-Q rebuild and search out my macro features and will hopefully be faster than the "full-full" rebuild


      I believe I am close and I think I am stuck on the last step, which is is running the SwComFeature regenerate method. 2015 SOLIDWORKS API Help - Regenerate Method (ISwComFeature)


      I've already added the swPublished interface library, but when I try to call the regenerate rebuild I getting "Run-time error '91' : Object variable or with block variable not set"


      I believe the problem is that I am not setting my ISWcomFeature object properly. I am still pretty green at writing macros so any help is appreciated. The line that is erroring out is bolded below.





      Option Explicit

      Public Enum swUserPreferenceIntegerValue_e

          swAutoSaveInterval = 3

      End Enum



      Sub RegenerateMacroFeature(Doc As SldWorks.ModelDoc2)

          Dim swApp As SldWorks.SldWorks

          Dim swFeat As SldWorks.Feature

          Dim instance As ISwComFeature

          Dim temp As Object


          Set swFeat = Doc.FirstFeature

          Set swApp = Application.SldWorks


          While Not swFeat Is Nothing

              If (swFeat.GetTypeName2 = "MacroFeature") Then

                  Set temp = instance.Regenerate(swApp, Doc, swFeat)

              End If

              Set swFeat = swFeat.GetNextFeature


      End Sub


      Sub TraverseComponent(swComp As SldWorks.Component2, nLevel As Long)

          Dim swApp As SldWorks.SldWorks

          Dim vChildComp As Variant

          Dim swChildComp As SldWorks.Component2

          Dim swCompConfig As SldWorks.Configuration

          Dim sPadStr As String

          Dim Doc As ModelDoc2


          Dim i As Long

          For i = 0 To nLevel - 1

              sPadStr = sPadStr + "  "

          Next i

          vChildComp = swComp.GetChildren

          For i = 0 To UBound(vChildComp)

              Set swChildComp = vChildComp(i)


              Set Doc = swChildComp.GetModelDoc2

              If Doc.GetType() = 1 Then

                  If Doc.IsOpenedReadOnly() = False Then

                      RegenerateMacroFeature Doc

                  End If

              End If

              TraverseComponent swChildComp, nLevel + 1

              Debug.Print sPadStr & swChildComp.Name2 & " <" & swChildComp.ReferencedConfiguration & ">"

          Next i

      End Sub



      Sub main()

          Dim swApp As SldWorks.SldWorks

          Dim swModel As SldWorks.ModelDoc2

          Dim swConf As SldWorks.Configuration

          Dim swRootComp As SldWorks.Component2

          Dim nStart As Single

          Dim i As Long

          Dim bRet As Boolean


          Set swApp = Application.SldWorks

          Set swModel = swApp.ActiveDoc

          Set swConf = swModel.GetActiveConfiguration

          Set swRootComp = swConf.GetRootComponent3(True)


         'Turn off automatic save

          bRet = swApp.SetUserPreferenceIntegerValue(swAutoSaveInterval, 0)

          nStart = Timer



          bRet = swModel.ForceRebuild3(True)

          TraverseComponent swRootComp, 1

      End Sub

        • Re: Regenerate Macro Feature using SwComFeature
          Keith Rice

          Hello Brian,


          You want to rebuild the a macro feature, but that is not what this function does. This function contains what will happen when the macro feature gets rebuilt. More specifically, ISwComFeature is what addins must implement in order to create a macro feature. ISwComFeature.Regenerate is one of the implemented functions. That function will include the code that runs whenever the macro feature rebuilds.


          If you want to rebuild a macro feature then you will have to rebuild some or all of the feature tree. You can rebuild only the portions of the feature tree that require rebuilding via IModelDoc2.EditRebuild3. You can force a rebuild of the entire tree via IModelDoc2.ForceRebuild3.


          Anyway, although you won't be able to use this function in the way you want, I should note that you are getting the "object not set error" because you declared "instance" but then never assigned a value to it. The default value is Nothing. Nothing, obviously, has no method called "Regenerate", so you get an error. Moreover, if you look at the API Help page for ISwComFeature, you see that there is no Accessors list, which means that there is no way to ever assign a value to your ISwComFeature variable. (Again, it has to be implemented in a .NET addin to be used.)


          I would recommend you check out this post on VBA Debugging Tips and Tricks, which describes this error (in the blog post itself toward the end) and also links to a handy PDF that you can use as a reference for when you run into an error and aren't certain of what it means or how to solve it.



          SolidWorks API Training and Services

            • Re: Regenerate Macro Feature using SwComFeature
              Brian Smith

              Thanks Keith for the response. I see the error in the direction I was taking. But your recommendations do not work for what I am trying to do, specifically IModelDoc2.EditRebuild3 and IModelDoc2.ForceRebuild3.


              EditRebuild3 doesn't see the macro feature as something that needs updating and ForceRebuild3 would rebuild every feature, which works but is extremely slow (about 20 seconds when rebuilding any common assembly we have).


              I want to be be able to snipe out the macro feature and rebuild it. So I don't see a method that rebuilds a specific feature in IModelDoc2, IFeature, or IFeatureManager. Maybe I am not looking hard enough.


              Alternatively I think if I edit the macro feature it would provide the same solution because when SW goes to edit a macro feature it doesn't do anything and rebuilds that macro feature. I feel like IModelDoc2.featedit accomplishes this, but I don't understand how it knows what feat it targets the edit with.