Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations SSS148 on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

VB program to list parts in an Assm? 2

Status
Not open for further replies.

ScottWisker

Mechanical
Jan 31, 2007
15
Does anyone know of code that will list the components within an assembly without having to open the file?

Thanks
 
Replies continue below

Recommended for you

The following didn't give any definitive answers but may help;
Importing BOM from .SLDASM into Excel thread559-182457

[cheers]
SW07-SP3.1
SW06-SP5.1
 
[smartass comment]
It's not possible to view any contents of any file without opening it. I guess you just don't want to open it in SolidWorks?
[/smartass comment]

You can view the external references of a file using the SwDocumentMgr dll. The following code will list the external references of any SW document. However, it only goes one level deep (doesn't list parts of subassemblies), and it will list external references other than parts (such as in-context references to a parent or other assembly).

This stuff isn't exactly straightforward. Depending on which version of SW you have, you may need a license key string from Solidworks API support to get this to work. If you're running SW'07 you should be fine. Any string passed for the key will be ignored. For earlier SW versions you'll need to contact API support.

Code:
Const DOCMGRLICENSEKEYSTRING As String = "Replace this string with your key for SW<'07"
Const PATHNAME As String = "Replace this with your file path"


Sub main()
Dim myDocMgrClassFactory As SwDocumentMgr.SwDMClassFactory
Dim myDocMgr As SwDocumentMgr.SwDMApplication
Dim mySwDoc As SwDocumentMgr.SwDMDocument7
Dim extRefs As Variant
Dim i As Long
Dim SrchOptions As SwDocumentMgr.SwDMSearchOption
Dim RefString As String
Dim MsgString As String
    
Set myDocMgrClassFactory = CreateObject("SwDocumentMgr.SwDMClassFactory")
On Error Resume Next
Set myDocMgr = myDocMgrClassFactory.GetApplication(DOCMGRLICENSEKEYSTRING)
On Error GoTo 0

Set mySwDoc = myDocMgr.GetDocument(PATHNAME, swDmDocumentUnknown, True, Empty)
Set SrchOptions = myDocMgr.GetSearchOptionObject
extRefs = mySwDoc.GetAllExternalReferences(SrchOptions)
RefString = (UBound(extRefs) + 1) & " External References Found:" & vbCrLf
For i = 0 To UBound(extRefs)
    RefString = RefString & vbCrLf & extRefs(i)
Next i

If Len(RefString) > 1024 Then
    MsgBox Left(RefString, 950) & vbCrLf & vbCrLf & "Number of characters exceeds MsgBox capacity"
Else
    MsgBox RefString
End If
End Sub
 
Impressive 1 hour and 6 minutes later the exact code I needed.

Thanks
 
Hope this isn't too late....

If you use this code recursively you will need to do some type of circular reference checking. Otherwise you'll overflow the stack. For example, say you have Assembly A and Part B in it. Part B has an in-context reference to Assembly A. Assembly A will show up in Part B's references, and Part B will show up in Assembly A's references. Here is some code that will return an indented reference list by calling this functionality recursively.


Code:
Const DOCMGRLICENSEKEYSTRING As String = "Replace this string with your key for SW<'07"
Const PATHNAME As String = "Replace this with your file path" 

Sub main()
Dim myDocMgrClassFactory As SwDocumentMgr.SwDMClassFactory
Dim swDocMgr As SwDocumentMgr.SwDMApplication
Dim myDoc As SwDocumentMgr.SwDMDocument7
Dim ParentDoc As SwDocumentMgr.SwDMDocument7
Dim i As Long
Dim RefString As String
Dim MsgString As String
Dim myCollection As Collection
Dim eachRef As Variant
Dim ParentString As String


Set myCollection = New Collection
    
Set myDocMgrClassFactory = CreateObject("SwDocumentMgr.SwDMClassFactory")
On Error Resume Next
Set swDocMgr = myDocMgrClassFactory.GetApplication(DOCMGRLICENSEKEYSTRING)
On Error GoTo 0

Set myDoc = swDocMgr.GetDocument(PATHNAME, swDmDocumentUnknown, True, Empty)
If Nothing Is myDoc Then
    myCollection.Add PATHNAME & "  [NOT FOUND]"
Else
    myCollection.Add myDoc.FullName
    ParentString = myDoc.FullName
    GetRefs myCollection, myDoc, swDocMgr, ">", ParentString
End If

''''''''''''''''''''''''
'At this point, myCollection is essentially a 1-dimensional array containing
'structured reference data.  For large assemblies this data will not fit
'in the immediate window.
''''''''''''''''''''''''

For Each eachRef In myCollection
    Debug.Print eachRef
Next eachRef

End Sub

Sub GetRefs(ByRef AddTo As Collection, ByVal ParentDoc As SwDocumentMgr.SwDMDocument7, ByRef myDocMgr As SwDocumentMgr.SwDMApplication, ByVal NumIndent As String, ByVal Parents As String)

Dim mySwDoc As SwDocumentMgr.SwDMDocument7
Dim SrchOptions As SwDocumentMgr.SwDMSearchOption
Dim extRefs As Variant
Dim i As Long

Set SrchOptions = myDocMgr.GetSearchOptionObject
extRefs = ParentDoc.GetAllExternalReferences(SrchOptions)

If IsEmpty(extRefs) Then
    'do nothing
Else
    For i = 0 To UBound(extRefs)
        Set mySwDoc = myDocMgr.GetDocument(extRefs(i), swDmDocumentUnknown, True, Empty)
        If Nothing Is mySwDoc Then
            AddTo.Add Left(NumIndent, Len(NumIndent) - 1) & "x" & extRefs(i) & "  [NOT FOUND]"
        ElseIf InStr(1, Parents, mySwDoc.FullName, vbTextCompare) > 0 Then
            'Don't add - circular.
        Else
            AddTo.Add NumIndent & mySwDoc.FullName
            GetRefs AddTo, mySwDoc, myDocMgr, "-" & NumIndent, mySwDoc.FullName & Parents
        End If
    Next i
End If

End Sub
 
Fortunately as a general rule we don't use in-context references here . . . at least not in the files I'm dealing with right now. Thanks for the catch though, I'll incorporate that as well.

The only thing I've changed at this point is using a multi-dimensional array for parsing out the filenames and displaying those in a listbox (rather than the full paths). I'd like to add some custom property manipulation to this as well such as displaying the description next to the filename/partnumber. I'm not sure how far I can get before I actually have to open the file, but this has been a great help.

Thanks
 
You can certainly access custom properties (configuration-specific ones as well) with the same swDocumentMgr interface. I posted code on here to do that some time ago. Hopefully you have the help documentation. All I have is what you can see in the object browser, so it's been trial-and-error for me.
 
I'm prolly just forgetting something, but I'm getting unidentified type error on this line:

Sub GetRefs(ByRef AddTo As Collection, ByVal ParentDoc As SwDocumentMgr.SwDMDocument7, ByRef myDocMgr As SwDocumentMgr.SwDMApplication, ByVal NumIndent As String, ByVal Parents As String)

Matt
CAD Engineer/ECN Analyst
Silicon Valley, CA
 
You probably need to load the relevant type library in the macro references (dll) list.

[cheers]
SW07-SP3.1
SW06-SP5.1
 
Will this work on "06"? Does this spit out the path for indented subs?

Here is the reason for my questions. We have alot of designs that are made up of parts and subs from other designs. Everytime we get an order we print out the entire drawing package (excluding hardware and such). The problem is that with a typical BOM of 80 parts spread throughout 5 directories this takes some serious time and there always seems to be that one drawing that gets missed. The other problem is i end up doing this and taking the heat everytime. I know i should spend more time and make sure its all there but @#it happens. Even if i can get a list of all the refences that would be great. Thanks
 
Yes, it'll work with '06 (that's what I'm running). However, you will need to contact SolidWorks API support and obtain a license key string for the dll. I have a key, but it's not permitted to share it outside the company it was issued to.

That said, this will only return referenced parts and assemblies. It will not find drawing files.
 
handleman,

In an effort to learn, why was a method using the swDocumentMgr.dll employed in this case? Are other methods available to accomplish the tasks in this macro?



Matt
CAD Engineer/ECN Analyst
Silicon Valley, CA
 
Yes, there are other methods available through the standard SolidWorks API. However, the OP specified that the document should not be opened in SolidWorks. This code will run as a macro in any VBA environment (Excel, etc) without opening SolidWorks either in the foreground or the background. It'll spit out the complete list well before the assembly could be opened in SolidWorks.
 
So help me understand this. If i take the code posted by handleman and paste it into a blank excel macro and click run it will open up (in the backround) the listed file and spit out the data needed. Now will i need to run this for each assembly listed in my top assembly? Also what is the liscence key string? Is this not my solidworks number?

Also if this at least list out the parts then i can identify which parts i need drawing for then either manually print them or set up some custom task or macro.

Thanks
 
Russell:
This code isn't really a functional macro per se. As-is, it's really just a "stub", if you will, to demonstrate the syntax and usage for the swDocumentMgr dll. Its intended audience is people who are familiar enough with VB/VBA to read it, understand it, and integrate it into their own macros/applications. It does "spit out" some output to the immediate window of the VBA editor, but even that is limited because the immediate window only holds a limited amount of text. It will work if pasted into a blank Excel macro as long as you include the reference to the swDocumentMgr.dll file under Tools->References. Solidworks will not open, either in the background or the foreground.

To save you the trouble of going back and reading my previous posts, I'll answer your other questions again.

The first macro I posted will only get the first level of references - that is, parts or assemblies directly referenced by the file it's run on.

The second macro will get all references as many levels deep as your memory stack will handle.

Neither macro will "spit out" or "list out" anything other than the few lines that fit in the immediate window of the VBA editor.

The license key string must be obtained from SolidWorks API support. It is not your SolidWorks serial number, registration code, purchase order number, zip code, social security number, credit card number, or ATM PIN.
 
In support of handleman's comments, all add that any code offered on this or any message board or website should always be used with caution. Code may be intentially incomplete, not fully debugged, not cleaned up, etc. Often, to use the code for one's own purposes, modifications are necessary.



Matt
CAD Engineer/ECN Analyst
Silicon Valley, CA
 
Thanks for the clarification. I have used VB with excel to do some data work but not too extensively, so there is some level of understanding. What i really need is some help, some fairly easy way that i can enter an SLDASM number and path into a field and it will generate a list of all the indented components of that. From that list i will have at least something to check off as we go thru these projects to ensure stuff does not get missed either as a printed drawing but also if the item is excluded from the BOM.

I am stuck in the middle of this as the 3rd or 4th person to occupy this chair. Scarry thing is that there could be 2 or 3 drawings of a part with the same number in different directories all with different finish callouts. You can imagine the frustration when you get a black part for a green assembly.

I need something that the people ordering parts can work with and possibly print via e-drawings the correct referenced part to the latest revision.

Sorry to ramble and all help and solutions are greatly appreciated. Thanks
 
So i have figured out how to generate a list of my parts within and assembly, included indented assemblies, showing the part locations.

Seems like a long process but when set-up will do the job.

First i use a macro from Lenny called PropertyEditorGlobal and enter a property called "Location" to all my part files, with a field text of $PRP:"SW-Folder Name"$PRP:"SW-File Name". Of course i need to do this for each directory, but it goes quick.

Then i modify an excel bom template and add the column Location. Now for my assemblies i create a new drawing and add the BOM and bingo parts, quatities and locations.

Now when we run the job at least we can make sure we get all the drawings from the right locations.

Now to figure out how to use task scheduler to run a custom task over and over so once i get all my drawing together i can just print and go.

 
Russell,
Are your using SolidWorks Professional 2006 sp5.1?


Bradley
SolidWorks Professional x64 2007 SP3.1
Intel(R) Pentium(R) D CPU
3.00 GHz, 3.93 GB of RAM
Virtual memory 12577 MB
NVIDIA Quadro FX 3400
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor