1 Reply Latest reply on Jan 4, 2017 10:35 AM by William Cruz

    Wait for assembly to load before executing macro feature

    Farzad Sidhva



      I am attempting to run a simple macro that gets custom property data from a top level model and passes it to a subassembly within said top assembly. I want it to run every time the model is opened so I have the macro called in a macro feature. It seems as though the macro is being executed too early and is causing crashes occasionally before the full top assembly is loaded. I have tried using a timer prior to executing but seeing as this macro will run on different systems, rebuild times could take between 5 and 30 seconds. I have also tried looping a Do while swActiveDoc is nothing and that simply causes the program to stop running (I have been coding for less than a year so I apologize if that was not even close to the right solution).Is there a way to have the program wait until the model is fully loaded before executing? Note that the macro runs fine when executed outside of the macro feature. Also note that the comments in the program are for those at my company that wouldn't know what they are doing when they see this.


      Thank you for your time,


      Farzad Sidhva


      Option Explicit

      Dim swApp               As SldWorks.SldWorks

      Dim swModel_1           As SldWorks.ModelDoc2

      Dim swModel_2           As SldWorks.ModelDoc2

      Dim swCustProp          As CustomPropertyManager

      Dim Model_1Name         As String

      Dim Model_2Name         As String

      Dim val                 As String

      Dim instances           As String

      Dim length              As String

      Dim WireRatio           As String

      Dim RndSpacing          As String

      Dim spacing             As String

      Dim WireLength          As String

      Dim VarDocFileName      As String

      Dim Side_Markers        As String

      Dim bool_1              As Boolean

      Dim bool_2              As Boolean

      Dim bRet                As Boolean

      Dim nErrors             As Long

      Dim nWarnings           As Long

      Dim swModelDocExt       As ModelDocExtension


      Sub GetProperty()



          Set swApp = Application.SldWorks


          'Set pointer to the top level assembly, get the name of the assembly, and get the 2 driving custom properties

          Set swModel_1 = swApp.ActiveDoc

          Let Model_1Name = swModel_1.GetTitle

          Set swModelDocExt = swModel_1.Extension

          Set swCustProp = swModelDocExt.CustomPropertyManager("")

          bool_1 = swCustProp.Get5("NUMBER OF SIDE MARKERS", False, val, instances, True)

          bool_2 = swCustProp.Get5("TRAILER LENGTH", False, val, length, True)


              Debug.Print "TOP LEVEL FILE NAME = "; Model_1Name

              Debug.Print "INSTANCES = "; instances

              Debug.Print "LENGTH = "; length


          'An equation for the spacing based on trailer length and number of marker lights was derived from a best fit line of all marker possibilities

          'it is then rounded to the nearest 10 because the side panels are always 10" in width

          WireRatio = length / instances


          spacing = (1.4568 * WireRatio) - 16.948


          RndSpacing = 10 * Int((spacing / 10) + 0.5)


              Debug.Print "WIRE RATIO = "; WireRatio

              Debug.Print "SPACING = "; spacing

              Debug.Print "ROUNDED SPACING = "; RndSpacing


          'This section determines what file to write the custom properties, the max and min spacing for each harness size was determined by our controls analyst

              If spacing <= 15 Then

                  WireLength = 24


                  ElseIf spacing <= 25 Then

                  WireLength = 36


                  ElseIf spacing <= 50 Then

                  WireLength = 60


                  ElseIf spacing <= 70 Then

                  WireLength = 84


                  ElseIf spacing <= 90 Then

                  WireLength = 108


                  ElseIf spacing <= 110 Then

                  WireLength = 120


                  ElseIf spacing <= 120 Then

                  WireLength = 132


                  ElseIf spacing <= 150 Then

                  WireLength = 168


                  ElseIf spacing <= 210 Then

                  WireLength = 228



                  WireLength = 276


              End If


              Debug.Print "WIRE LENGTH = "; WireLength



          'The file names of the affected assemblies are syntaxed as such that the only thing that changes is one number

          'This section opens the required assembly, gets the name of the assembly (without the extension or path), sets the custom property, and rebuilds it

          VarDocFileName = "C:\EXAMPLE\000s\MODELS\" & WireLength & " IN SIDE MARKER SPACING.SLDASM"

          Set swModel_2 = swApp.OpenDoc6(VarDocFileName, swDocASSEMBLY, 1, "Default", nErrors, nWarnings)

          Let Model_2Name = swModel_2.GetTitle


              Debug.Print "MARKER ASSEMBLY FILE NAME = "; Model_2Name


          Set swCustProp = swModel_2.Extension.CustomPropertyManager("")

          swCustProp.Set2 "SIDE_MARKERS", instances


          bRet = swModel_2.ForceRebuild3(False)


          'The active document is then switched to the original and is rebuilt. Then the sub-assembly document is closed

          Set swModel_1 = swApp.ActivateDoc2(Model_1Name, True, nErrors)


          bRet = swModel_1.ForceRebuild3(False)



      End Sub

        • Re: Wait for assembly to load before executing macro feature
          William Cruz

          You should remove all time events from your code and use the events that SW provides to capture most, if not all of what your looking for with little or no modification at all. When creating a sw addin, these get created automatically. See below for an extract of what comes in from SW when creating an addin.


                  private bool AttachSwEvents()
                          SwEventPtr.ActiveDocChangeNotify += new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(OnDocChange);
                          SwEventPtr.DocumentLoadNotify2 += new DSldWorksEvents_DocumentLoadNotify2EventHandler(OnDocLoad);
                          SwEventPtr.FileNewNotify2 += new DSldWorksEvents_FileNewNotify2EventHandler(OnFileNew);
                          SwEventPtr.ActiveModelDocChangeNotify += new DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler(OnModelChange);
                          SwEventPtr.FileOpenPostNotify += new DSldWorksEvents_FileOpenPostNotifyEventHandler(FileOpenPostNotify);
                          return true;
                      catch (Exception e)
                          return false;


          List of SW events:


          namespace SolidWorks.Interop.sldworks
              [ComEventInterface(typeof(DSldWorksEvents), typeof(DSldWorksEvents_EventProvider))]
              public interface DSldWorksEvents_Event
                  event DSldWorksEvents_ActiveDocChangeNotifyEventHandler ActiveDocChangeNotify;
                  event DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler ActiveModelDocChangeNotify;
                  event DSldWorksEvents_BackgroundProcessingEndNotifyEventHandler BackgroundProcessingEndNotify;
                  event DSldWorksEvents_BackgroundProcessingStartNotifyEventHandler BackgroundProcessingStartNotify;
                  event DSldWorksEvents_BeginRecordNotifyEventHandler BeginRecordNotify;
                  event DSldWorksEvents_BeginTranslationNotifyEventHandler BeginTranslationNotify;
                  event DSldWorksEvents_CommandCloseNotifyEventHandler CommandCloseNotify;
                  event DSldWorksEvents_CommandOpenPreNotifyEventHandler CommandOpenPreNotify;
                  event DSldWorksEvents_DestroyNotifyEventHandler DestroyNotify;
                  event DSldWorksEvents_DocumentConversionNotifyEventHandler DocumentConversionNotify;
                  event DSldWorksEvents_DocumentLoadNotifyEventHandler DocumentLoadNotify;
                  event DSldWorksEvents_DocumentLoadNotify2EventHandler DocumentLoadNotify2;
                  event DSldWorksEvents_EndRecordNotifyEventHandler EndRecordNotify;
                  event DSldWorksEvents_EndTranslationNotifyEventHandler EndTranslationNotify;
                  event DSldWorksEvents_FileCloseNotifyEventHandler FileCloseNotify;
                  event DSldWorksEvents_FileNewNotifyEventHandler FileNewNotify;
                  event DSldWorksEvents_FileNewNotify2EventHandler FileNewNotify2;
                  event DSldWorksEvents_FileNewPreNotifyEventHandler FileNewPreNotify;
                  event DSldWorksEvents_FileOpenNotifyEventHandler FileOpenNotify;
                  event DSldWorksEvents_FileOpenNotify2EventHandler FileOpenNotify2;
                  event DSldWorksEvents_FileOpenPostNotifyEventHandler FileOpenPostNotify;
                  event DSldWorksEvents_FileOpenPreNotifyEventHandler FileOpenPreNotify;
                  event DSldWorksEvents_InterfaceBrightnessThemeChangeNotifyEventHandler InterfaceBrightnessThemeChangeNotify;
                  event DSldWorksEvents_JournalWriteNotifyEventHandler JournalWriteNotify;
                  event DSldWorksEvents_LightSheetCreateNotifyEventHandler LightSheetCreateNotify;
                  event DSldWorksEvents_NonNativeFileOpenNotifyEventHandler NonNativeFileOpenNotify;
                  event DSldWorksEvents_OnIdleNotifyEventHandler OnIdleNotify;
                  event DSldWorksEvents_PromptForFilenameNotifyEventHandler PromptForFilenameNotify;
                  event DSldWorksEvents_PromptForMultipleFileNamesNotifyEventHandler PromptForMultipleFileNamesNotify;
                  event DSldWorksEvents_PropertySheetCreateNotifyEventHandler PropertySheetCreateNotify;
                  event DSldWorksEvents_ReferencedFilePreNotifyEventHandler ReferencedFilePreNotify;
                  event DSldWorksEvents_ReferenceNotFoundNotifyEventHandler ReferenceNotFoundNotify;