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.
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.
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
' 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)
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.
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
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
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
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.
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.
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.
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
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.
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
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.
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.
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
As far as I know, VB 2005 Express is the latest free version of VB.net =========================================================================== Chris
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.