Please Fix My Macro

Discussion in 'SolidWorks' started by inthepickle, Mar 19, 2007.

  1. inthepickle

    inthepickle Guest

    I have been trying to write a macro that does the following:

    1) traverse an assembly
    2) list all children
    3) rebuild each child
    4) get rebuild time for each child
    5) print results to a txt file

    I think I am almost complete, but there is one snag. The command I am
    using to rebuild the child component is not working. It is rebuilding
    the entire assembly instead. Would someone please modify my macro to
    make it rebuild only the child. I am not an expert programmer. I
    have taken bits and pieces of code around the net, along with my own
    additions to construct this macro. So, be gentle if the code is
    confusing in places.

    Thanks

    Declare Function ShellExecute Lib "shell32.dll" Alias
    "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String,
    ByVal lpFile As String, ByVal lpParameters As String, ByVal
    lpDirectory As String, ByVal nShowCmd As Long) As Long
    Sub Traverse()
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swAssy As SldWorks.AssemblyDoc
    Dim swConf As SldWorks.Configuration
    Dim swRootComp As SldWorks.Component2
    Dim bRet As Boolean
    Dim FileName, FilePath As String
    Dim Errs As Long
    Dim Warnings As Long
    Const SW_SHOWNORMAL = 1

    Set swApp = CreateObject("SldWorks.Application")
    Set swModel = swApp.ActiveDoc
    Set swConf = swModel.GetActiveConfiguration
    Set swRootComp = swConf.GetRootComponent
    Set swAssy = swModel

    'get file info
    FileName = swModel.GetTitle 'gets name
    FilePath = "C:\Documents and Settings\All Users\Desktop\"

    'Resolve Assy & All Components
    swAssy.ResolveAllLightweight

    ' Recursively traverse the component
    If Not swRootComp Is Nothing Then
    TraverseComponent 1, swRootComp
    End If

    retval = ShellExecute(1, "Open", FilePath & FileName & ".txt", "",
    FilePath, SW_SHOWNORMAL) 'opens results

    End Sub
    Private Function TraverseComponent(Level As Integer, Component As
    Object)
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim i As Integer
    Dim Children As Variant
    Dim Child As Object
    Dim ChildCount As Integer
    Dim Start, Finish, TotalTime

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

    ' Traverse the children
    Children = Component.GetChildren ' Get the list of children

    ChildCount = UBound(Children) + 1

    For i = 0 To (ChildCount - 1) ' For each Child in this subassembly
    Set Child = Children(i) ' Get Child component object

    Start = Timer 'start a timer

    swModel.ForceRebuild3 (False) 'rebuilds component

    Finish = Timer 'stop the timer
    TotalTime = Finish - Start 'calculate total time

    docname = Child.Name 'get part name
    DocNameWithPath = Child.GetPathName 'get path of part
    RefConfig = Child.ReferencedConfiguration() 'get part
    configuration

    'outputs info to a txt file on the desktop
    MyChannel = FreeFile
    Open "C:\Documents and Settings\All Users\Desktop\" &
    swModel.GetTitle & ".txt" For Append As MyChannel
    Print #MyChannel, docname
    Print #MyChannel, DocNameWithPath
    Print #MyChannel, RefConfig
    Print #MyChannel, TotalTime & " Seconds"
    Print #MyChannel, Text
    Close #MyChannel

    'Debug.Print docname
    'Debug.Print DocNameWithPath
    'Debug.Print RefConfig
    'Debug.Print TotalTime & " Seconds"
    'Debug.Print Text
    Next i

    End Function
     
    inthepickle, Mar 19, 2007
    #1
  2. First, in

    swModel.ForceRebuild3 (False) 'rebuilds component

    your comment is wrong, the code is right (as always ;-) : this command
    rebuilds the swModel, which is the ActiveDoc, i.e. your main assembly.
    As you cannot rebuild "components" (no Component:Rebuild method, and
    no Feature:Rebuild, that would be nice...), you must retrieve the
    document corresponding to each component : Component2:GetModelDoc is
    what you need. So change the line above in

    Component.GetModelDoc.ForceRebuild3 (False) 'rebuilds component

    Note that there are several other things that you'll need to do before
    your macro works :
    1) call TraverseComponent recursively to handle multiple levels of
    subassemblies. make sure you recurse before traversing the children,
    to ensure rebuilding the parts before the subassemblies
    2) at some point you'll need a test to check wether your component is
    a part or a sub-assembly, because Children might be empty, and this
    will crash the for loop. IsEmpty(Children) is what you'll need.
    3) do some optimization to avoid rebuilding parts twice if they are
    used twice in assembly (SolidWorks rebuilds parts only once when
    rebuilding a full assembly)
    4) put swapp as a global variable that you initialize only once.
    CreateObject('SolidWorks.Application') is very slow. You'd better use

    Set swApp=application.application

    as application is predefined in VBA as the calling application...
    5) and some more I did'nt notice yet.

    I'll fix your macro entirely if you allow me to publish it on
    http://swapi.wordpress.com ...

    Welcome to the Wonderful World of API Programming !
     
    Philippe Guglielmetti, Mar 19, 2007
    #2
  3. inthepickle

    inthepickle Guest

    Philippe

    Thanks for all of the great advice. I will try to correct my macro,
    and see if I can get it to work properly. In the meantime, you can
    correct it, and publish it anywhere, as long as I have access to the
    final code. Please let me know.

    Thanks
    David
     
    inthepickle, Mar 19, 2007
    #3
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.