Bom Macro.

I am inurgent need of a macro. This macro needs to add a new bom then i have some other code to that will print this bom. Then i need the macro to delete the bom that was paced in the drawing, but not delete any other bom that was already in the drawing. Can anyone help me or point me in the right direction. I must say that i don't have a great deal of scripting ability. Cheers Damian.

Reply to
Dames
Loading thread data ...

Start by recording a macro while you do everything manually. This will build the skeletton of your macro. It probably won't play back, but it's a good start since it will contain many of the required API calls.

The big question then is : what changes between 2 runs of your macro, or between 2 drawings on which it will run ? Do you need to select items ? do you need to format bom columns differently ?

Programming the macro consists mostly in "generalizing" it, making it able to handle different cases on different documents. And this is generally the hard part.

Maybe you could post your recorded macro and answer the question above : what changes between your "temporary boms" on different drawings. Then we might give you some more help here.

Reply to
Philippe Guglielmetti

Q1. I am export an advanced BOM in an XML format. The drawings typicly have a BOM that only has about 6 feilds, but my advanced BOM will have about 15-20. I need this BOM only as an export not to be on the drawing..

I tried to record, but there dosn't reaaly seem to be anything of use in the code. See below.

' ****************************************************************************** ' C:\DOCUME~1\DGILLE~1\LOCALS~1\Temp\swx1256\Macro1.swb - macro recorded on 07/23/07 by dgillespie ' ****************************************************************************** Dim swApp As Object Dim Part As Object Dim SelMgr As Object Dim boolstatus As Boolean Dim longstatus As Long, longwarnings As Long Dim Feature As Object Sub main()

Set swApp = Application.SldWorks

Set Part = swApp.ActiveDoc Set SelMgr = Part.SelectionManager boolstatus = Part.Extension.SelectByID2("DetailItem147@Sheet2", "ANNOTATIONTABLES", -0.07991769230769, 0.08582843076923, 0, False, 0, Nothing, 0) Part.EditDelete End Sub

Anyway here is my code. '------------------------------------------------

'

' Preconditions:

' (1) Drawing document is open.

' (2) Drawing contains at least one BOM.

' (3) In VBA, add a reference to Microsoft Scripting Runtime using

' Tools, References (C:\windows\system32\scrrun.dll)

'

' Postconditions: XML file is saved to the same directory,

' overwriting any existing file of the same name.

'

' NOTES:

' (1) XML tags are based on BOM column headings.

' (2) Invalid characters must be removed from the

' column headings.

' (3) Microsoft Scripting Runtime reference must be selected in VBA.

' (4) XML schema is:

' ' '

' Sheet1

'

' Bill Of Materials1

' '

' 1

' 2004_Part

'

' 2

' '

' 2

' 2004_Part

'

' 1

' '

' 3

' 2004_Part

'

' 1

' '

' 4

' bead7

'

' 1

' ' ' ' '

' Sheet2

'

' Bill Of Materials2

' '

' 1

' Assem3

'

' 1

' ' '

' cylinder

'

' 1

' ' '

' cylinder

'

' 1

' ' '

' SimpleCube_A

'

' 1

' ' '

' JoinedCyl

'

' 1

' ' ' '

' Bill Of Materials3

' '

' 8

' 2004_Part

'

' 2

' ' ' '

' 9

' 2004_Part

'

' 1

' '

' 10

' 2004_Part

'

' 1

' ' ' '

' 11

' bead7

'

' 1

' ' ' '

' Bill Of Materials4

'

' BOM Table 2

'

' 1

' cylinder

'

' 1

' '

' 2

' cylinder

'

' 1

' ' '

' BOM Table 2

'

' 3

' SimpleCube_A

'

' 1

' '

' 4

' JoinedCyl

'

' 1

' ' ' ' ' ' '

'----------------------------------------------

Option Explicit

Public Enum swTableSplitDirection_e

swTableSplit_None = 0

swTableSplit_Horizontal = 1

swTableSplit_Vertical = 2

End Enum

Sub ProcessTableAnn(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2, swTableAnn As SldWorks.TableAnnotation, XMLfile As Scripting.TextStream)

Dim nNumRow As Long

Dim nNumCol As Long

Dim nNumHeader As Long

Dim sHeaderText() As String

Dim i As Long

Dim j As Long

Dim k As Long

Dim nIndex As Long

Dim nCount As Long

Dim nStart As Long

Dim nEnd As Long

Dim nSplitDir As Long

nNumHeader = swTableAnn.GetHeaderCount: Debug.Assert nNumHeader >=

1

nSplitDir = swTableAnn.GetSplitInformation(nIndex, nCount, nStart, nEnd)

If swTableSplit_None = nSplitDir Then

Debug.Assert 0 = nIndex

Debug.Assert 0 = nCount

Debug.Assert 0 = nStart

Debug.Assert 0 = nEnd

nNumRow = swTableAnn.RowCount

nNumCol = swTableAnn.ColumnCount

nStart = nNumHeader

nEnd = nNumRow - 1

Else

Debug.Assert swTableSplit_Horizontal = nSplitDir

Debug.Assert nIndex >= 0

Debug.Assert nCount >= 0

Debug.Assert nStart >= 0

Debug.Assert nEnd >= nStart

nNumCol = swTableAnn.ColumnCount

If 1 = nIndex Then

' Add header offset for first portion of table

nStart = nStart + nNumHeader

End If

End If

XMLfile.WriteLine " "

If swTableAnn.TitleVisible Then

XMLfile.WriteLine " " & swTableAnn.Title & ""

End If

ReDim sHeaderText(nNumCol - 1)

For j = 0 To nNumCol - 1

sHeaderText(j) = swTableAnn.GetColumnTitle(j)

' Replace invalid characters for XML tags

sHeaderText(j) = Replace(sHeaderText(j), ".", "")

sHeaderText(j) = Replace(sHeaderText(j), " ", "_") sHeaderText(j) = Replace(sHeaderText(j), "(", "_") sHeaderText(j) = Replace(sHeaderText(j), ")", "_")

Next j

For j = nStart To nEnd

XMLfile.WriteLine " "

For k = 0 To nNumCol - 1 XMLfile.WriteLine " " + "" + swTableAnn.Text(j, k) + ""

Next k

XMLfile.WriteLine " "

Next j

XMLfile.WriteLine " "

End Sub

Sub ProcessBomFeature(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2, swBomFeat As SldWorks.BomFeature, XMLfile As Scripting.TextStream)

Dim swFeat As SldWorks.Feature

Dim vTableArr As Variant

Dim vTable As Variant

Dim swTable As SldWorks.TableAnnotation

Set swFeat = swBomFeat.GetFeature

XMLfile.WriteLine " "

XMLfile.WriteLine " " & swFeat.Name & ""

vTableArr = swBomFeat.GetTableAnnotations

For Each vTable In vTableArr

Set swTable = vTable

ProcessTableAnn swApp, swModel, swTable, XMLfile

Next vTable

XMLfile.WriteLine " "

End Sub

Sub main()

Dim MyAppID As Long

Dim swApp As SldWorks.SldWorks

Dim swModel As SldWorks.ModelDoc2

Dim swDraw As SldWorks.DrawingDoc

Dim swSheet As SldWorks.Sheet

Dim swFeat As SldWorks.Feature

Dim swBomFeat As SldWorks.BomFeature

Dim sPathName As String

Dim nNumSheet As Long

Dim nRetval As Long

Dim i As Long

Dim bIsFirstSheet As Boolean

Dim bRet As Boolean

Dim fso As Scripting.FileSystemObject

Dim XMLfile As Scripting.TextStream

'Dim swApp As Object Dim Part As Object

Set swApp = Application.SldWorks

Set swModel = swApp.ActiveDoc

Set swDraw = swModel

bIsFirstSheet = True

' Strip off SolidWorks file extension (sldxxx)

' and add XML extension (xml)

sPathName = swModel.GetPathName

sPathName = Left(sPathName, Len(sPathName) - 6)

sPathName = sPathName + "xml"

Set fso = CreateObject("Scripting.FileSystemObject")

Set XMLfile = fso.CreateTextFile(sPathName, True) XMLfile.WriteLine "" XMLfile.WriteLine ""

XMLfile.WriteLine ""

Set swFeat = swModel.FirstFeature

Do While Not swFeat Is Nothing

If "DrSheet" = swFeat.GetTypeName Then

XMLfile.WriteLine " "

XMLfile.WriteLine " " + swFeat.Name + ""

bIsFirstSheet = False

End If

If "BomFeat" = swFeat.GetTypeName Then

Set swBomFeat = swFeat.GetSpecificFeature2

ProcessBomFeature swApp, swModel, swBomFeat, XMLfile

End If

Set swFeat = swFeat.GetNextFeature

If Not swFeat Is Nothing Then

If "DrSheet" = swFeat.GetTypeName And Not bIsFirstSheet Then

XMLfile.WriteLine " "

End If

End If

Loop

XMLfile.WriteLine " "

XMLfile.WriteLine ""

XMLfile.Close 'MyAppID = Shell("I:\PROPERTIES\Catten Output\SW_Output_Catten.exe",

1)

'AppActivate MyAppID

End Sub

'----------------------------------------------------

Cheers Damian

Reply to
Dames

Oh your project is much more advanced than I expected from your first post. Well you're on the right track, you know how to program, XML and such things, so what do you still need ? Oh ! How to delete the temporary table you just created ?

'since you have Dim swBomFeat As SldWorks.BomFeature 'then swBomFeat.GetFeature.Select2(false,0) ' to select it in the feature tree swDraw.EditCut ' the quick and dirty way OR swDraw.Extension.DeleteSelection2(0)' the clean way, with options to delete feature children.

I wrote a macro similar to yours some time ago... 2 comments:

1) If you export to XML, you don't really need to create a table, you could build a bom "internally" by traversing the assembly, which gives you even more flexibility than the SW BOM. 2) check the MSXML4 module to read/write XML files. You'll find plenty of tutorials on the net. It's much more efficient than handling XML as text files, as XML is more tricky than you expect. For example, your macro might have trouble with my french =E9=E0 accents or even worse, quotes in part names and such things. Normally you have to parse all strings you store in XML to convert them in a clean format with " for quotes ... MSXML takes all this pain out.

Regards

Reply to
Philippe Guglielmetti

Thanks for the vote of cofidence But i have nor really done this program. I think i got most of this from some examples. So some help would be great Cheers Damian

Reply to
Dames

Hello Damian,

Is the main goal to get a BOM out of SW? If so, I would look at this AssemblyBOM macro on Lenny's site

With any SW asm open, Run Macro. A window pops up, you select BOM columns (revision, configurations)...and then choose format to export.

formatting link
Macro: AssemblyBOM

-Blair

BTW, Lenny just did a real useful presentation on Macro's at our local Kansas City SWUG meeting. Thanks Lenny.

Reply to
Blair Sutton

Thanks Bliar. I have been using Lenny's macro for a while now. But i need all this exporting to happen in the background from a drawing when i use another macro to print our drawings. At present i use a macro that prints out our drawing a pdf, a tiff and a DXF of our parts (with a rev attached to the file name.) I may make a video of what i am looking for and upload to a site so people can get an idea of what we do and of what we want. Cheers Damian

Reply to
Dames

Here is a video of what i am trying to do. Keep in mind that i already have a bom in the drawing. And that i want to add a new Bom, write out the the file then delete the bom that i have just put in and keep the exsisting bom. Cheers Damian

formatting link

Reply to
Dames

loop through each sheet on the drawing then if the assumption can be made that all views are the same then you can grab the first view and use the insert bill of material function where you can specify a BOM template containing the properties you desire. (If the assumption cannot be made than you will have to think about how to recognize the correct view, perhaps the view that already has the BOM connected to it.) Next, when you insert the BOM you get the pointer to the BOM Object and from there you can get access to the rows and columns where you can then walk through the rows and columns generating you xml information.

You need to explain to me how much help you need. Do you have only the solidworks macro editor or do you have vb.net? Do you know how to create an xml file using VB? Do you need sample code to loop through the drawing sheets?

Also, you say this is urgent. Am I too late to help? Is this a short term thing or do you need this program for use down the road also? Just trying to find out how much time we should spend on this.

Reply to
Bill Briggs

Firstly its not to late, so help would be great.

1.The assumptions that you are talking about in the first paragraph are valid. My dealt view is in most cases is the one which has the BOM is attached. If this is not the case then I/we would rectify these as needed.
  1. How much help do I need? Well, I have a limited understanding of code and with time (not much of that these days) I can usually fudge my way through, but I would like if someone could step me through. This has been the only way I have learnt in the past.
  2. I only have the macro editor but I can download the VB.net if this would be the better way to go. I would much prefer to start learning VB.net as I could then use these skills in other areas within my job.

Thank Bill for your time and I hope to here back from you soon. Cheers Damian

Reply to
Dames

Well, I have been working on this for you this morning because I pretty much just "office space" it these days. I am almost done with it but I have to question your schema. First of all, I am not an expert on what a good schema is, I simply know how to create the xml file. So that said, are you sure this is the schema you want or are you open to some changes? If so, I will post back with some suggestions.

Another thing I need to know is when I insert the temporary BOM, what type do you want? Top Level Only, Parts Only, or Indented?

I will send you the complete program in VB.net and I will post the code here as well. It could be done with the macro editor but you would need to rewrite the xml creation stuff because mine uses vb.net libraries. Technically, you could write the xml file as a text document with a .xml extension. I do it with the libraries because it adds the formating for me automatically.

Bill

Reply to
Bill Briggs

This is a good start for you I think, I am using the "Custom Property View" as the view for the BOM. All you should have to change is the path to the BOM Template. This is set to work if a drawing is already open in SolidWorks. CreateBom is the main routine to start with. This code will run in VB.net with references to system.io, system.xml, SolidWorks Type Library, and SolidWorks Constant Library. I made a slight adjustment for now in your schema. After we discuss my previous post, I will make any adjustments you want and I will send you the compiled program so you can run it and I will send the entire solution so that if you get vb.net 2005 you can edit it and make it your own. The only thing I ask is that anyone who reads and this and likes what they see, remember me when you hear about job openings and/ or someone needing a custom application written.

Bill

---------------------------- Module modBom

Dim swApp As SldWorks.SldWorks Dim swModelDoc As SldWorks.ModelDoc2 Dim swDrawDoc As SldWorks.DrawingDoc Const strBomTemplate As String = "D:\Program Files\Common Files \Solidworks Data 2007\SWBOM.sldbomtbt"

Dim MyXmlDoc As New XmlDocument Dim MyRoot As XmlNode

Sub CreateBom()

Try

' Get Active Model swModelDoc = GetActiveModelDoc() ' Verify Found If Not swModelDoc Is Nothing Then ' Verify is Drawing If swModelDoc.GetType = SwConst.swDocumentTypes_e.swDocDRAWING Then ' Get Drawing Doc swDrawDoc = swModelDoc

' Build Bom File Name Dim strFileName As String = Path.GetDirectoryName(swModelDoc.GetPathName) & "\" & Path.GetFileNameWithoutExtension(swModelDoc.GetPathName) & ".xml" ' Verify File does not exist and delete if file does exist If DeleteExistingFile(strFileName) = False Then MsgBox("Cannot overwrite existing file: " & strFileName, MsgBoxStyle.Critical, "Failed") Exit Sub End If

' Create Xml Writer Dim writer As New XmlTextWriter(strFileName, Nothing) 'Use indenting for readability. writer.Formatting = Formatting.Indented ' Write Start of Document" writer.WriteStartDocument(True) ' Create Root node MyRoot = MyXmlDoc.CreateElement("Boms")

' Read Drawing Bom ReadBom()

' Write Root node MyRoot.WriteTo(writer) ' Write End Document writer.WriteEndDocument() ' Flush Writer writer.Flush() ' Close Writer writer.Close()

End If End If

Catch ex As Exception

End Try

End Sub

#Region " SolidWorks Document Tools "

Function GetSolidWorks() As Boolean

Try

Dim MyReturn As Boolean = False

If swApp Is Nothing Then swApp = GetObject("", "SldWorks.Application") End If

If Not swApp Is Nothing Then MyReturn = True End If

Return MyReturn Catch ex As Exception Return False End Try

End Function

Function GetActiveModelDoc() As SldWorks.ModelDoc2

Try

' Get SolidWorks Object GetSolidWorks()

' Get Active ModelDoc Object Dim SwModel As SldWorks.ModelDoc2 = swApp.ActiveDoc

Return SwModel Catch ex As Exception Return Nothing End Try

End Function

#End Region

#Region " Bom "

Private Sub ReadBom()

Try

' Get List Of Sheet Names Dim strSheets() As String = swDrawDoc.GetSheetNames() ' Process All Sheets For i As Integer = 0 To swDrawDoc.GetSheetCount - 1

Dim MySheetNode As XmlNode MySheetNode = MyXmlDoc.CreateElement("Sheet")

Dim MyNode As XmlNode MyNode = MyXmlDoc.CreateElement("Name") MyNode.InnerText = strSheets(i) MySheetNode.AppendChild(MyNode) Dim MyBomNode As XmlNode = MyXmlDoc.CreateElement("BOM")

' Activate Sheet By Name swDrawDoc.ActivateSheet(strSheets(i)) ' Get BOM Drawing View Dim MyDrawView As SldWorks.View = swDrawDoc.GetFirstView ' Get Current Sheet Dim swSheet As SldWorks.Sheet = swDrawDoc.GetCurrentSheet ' Get Custom Property View Dim strView As String = swSheet.CustomPropertyView ' If the custom property view is the Default, Get the First View If strView = "Default" Then MyDrawView = swDrawDoc.GetFirstView MyDrawView = MyDrawView.GetNextView Else ' Find Matching View by Name MyDrawView = swDrawDoc.GetFirstView ' Loop Through Views While Not MyDrawView Is Nothing If MyDrawView.Name = strView Then Exit While End If ' Next View MyDrawView = MyDrawView.GetNextView End While End If

' Create Custom Xml Bom CreateXmlBom(MyDrawView, MyBomNode)

' Append To Sheet MySheetNode.AppendChild(MyBomNode) ' Append to Root MyRoot.AppendChild(MySheetNode)

Next

Catch ex As Exception

End Try

End Sub

Sub CreateXmlBom(ByVal MyDrawView As SldWorks.View, ByRef MyBomNode As XmlNode)

Try

' Insert and Get Bom Table Annotation Dim swBomTable As SldWorks.TableAnnotation = InsertBom(MyDrawView) ' Verify If Not swBomTable Is Nothing Then ' Process Bom ProcessBom(swBomTable, MyBomNode) ' Remove Bom Dim swAnnotation As SldWorks.Annotation = swBomTable.GetAnnotation swAnnotation.Select3(False, Nothing) swModelDoc.DeleteSelection(False) End If

Catch ex As Exception

End Try

End Sub

Sub ProcessBom(ByVal swBomTable As SldWorks.TableAnnotation, ByRef MyBomNode As XmlNode)

Try

' Ensure Header is at Top swBomTable.SetHeader(SwConst.swTableHeaderPosition_e.swTableHeader_Top,

1) ' Process each Row For r As Integer = 1 To swBomTable.RowCount - 1 ' Create Row Node Dim MyRowNode As XmlNode = MyXmlDoc.CreateElement("ROW") ' Process each Column For c As Integer = 0 To swBomTable.ColumnCount - 1 ' Get Cell Value Dim strValue As String = swBomTable.DisplayedText(r, c) ' Get Header (Replace Spaces with "_", also the title cannot contain characters that are not allowed in xml node names) Dim strHeader As String = swBomTable.GetColumnTitle(c).Replace(" ", "_") ' Create Item Node Dim MyItemNode As XmlNode = MyXmlDoc.CreateElement(strHeader) ' Add Value MyItemNode.InnerText = strValue ' Append To Row MyRowNode.AppendChild(MyItemNode) Next ' Append to Bom MyBomNode.AppendChild(MyRowNode) Next Catch ex As Exception

End Try

End Sub

Function InsertBom(ByVal MyDrawView As SldWorks.View) As SldWorks.TableAnnotation

Try

Dim MyReturn As SldWorks.TableAnnotation = Nothing

' Insert Bom Dim swBom As SldWorks.BomTableAnnotation = MyDrawView.InsertBomTable2(True, 0, 0, SwConst.swBOMConfigurationAnchorType_e.swBOMConfigurationAnchor_BottomLeft, SwConst.swBomType_e.swBomType_TopLevelOnly, MyDrawView.ReferencedConfiguration, strBomTemplate)

' Verify Bom If Not swBom Is Nothing Then ' Get Bom Feature Dim swBomFeature As SldWorks.BomFeature = swBom.BomFeature ' Verify If Not swBomFeature Is Nothing Then Dim MyVisibleConfigs As Object = Nothing Dim strConfigNames() As String = swBomFeature.GetConfigurations(False, MyVisibleConfigs) For i As Integer = 0 To strConfigNames.Length - 1 If strConfigNames(i) = MyDrawView.ReferencedConfiguration Then MyVisibleConfigs(i) = True swBomFeature.SetConfigurations(True, MyVisibleConfigs, strConfigNames) Exit For End If Next ' Get Bom Table For Each swBomTable As SldWorks.TableAnnotation In swBomFeature.GetTableAnnotations MyReturn = swBomTable Exit For Next End If End If

Return MyReturn Catch ex As Exception Return Nothing End Try

End Function

Function DeleteExistingFile(ByVal strFileName As String) As Boolean

Try Dim MyReturn As Boolean = False

' Check if File Exists If File.Exists(strFileName) = True Then ' Delete File File.Delete(strFileName) End If

MyReturn = Not File.Exists(strFileName)

Return MyReturn Catch ex As Exception Return False End Try

End Function

#End Region

End Module

Reply to
Bill Briggs

Where are you located?

WT

Reply to
Wayne Tiffany

I am in Vassar, Michigan and you can see more info if you click on "view profile" by my name. Thanks for asking.

Reply to
Bill Briggs

Thanks Bill. You have done a lot more than i thought anyone would do. Yes bill i am open to any ideas to make it better. Also idented assembly bom would be the best. It is Saturday arvo here so i will get back to this Monday morning my time.

Cheers Bill. Damian

Reply to
Dames

PS Bill . Do you know of the ERP system M1. As my main goal is to link Solidworks Bom to a build in M1. Cheers Damian

Reply to
Dames

No, sorry I do not know that system. You need to find out what import capabilities the erp system has and then we can build the export file or files accordingly. I would expect that the erp system would want individual files showing the top level only for each of the sub assemblies.

Reply to
Bill Briggs

Hi Bill. I have to admit, i am not in a hurry to link it with the ERP system as yet. I downloaded VB 2005 Express. Is this the same as VB.NET. Cheers DAmian

Reply to
Dames

As far as I know, VB 2005 Express is the latest free version of VB.net =========================================================================== Chris

Reply to
Chris Dubea

Thanks for that . Now i will download at work and try and build the code with Bills code. Cheers Damian

Reply to
Dames

PolyTech Forum website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.