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
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 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