Hallo
ich habe ein Problem, arbeite an einem Export von INventor inXML, das klappt auch ganz gut, aber ich bräuchte es noch einigermassen sortiert...
folgende aufgabenstellung:
ich interiere eine BOM und schreibe alle bauteile in eine xml, wenn eine unterbaugruppe gibt, soll diese natürlich auch interiert werden, aber diese Daten sollen nicht sofort eingefügt werden, sondern erst nachdem die erste baugruppe fertig "aufgenommen" wurde....
derzeit habe ich das problem, dass inventor einfach alle bom - so wie sie auftauchen - durchinteriert...
so kommt es raus:
<Parts>
<Part PartNo="987654">
<PartNoExt>ENG-200035</PartNoExt>
<Description>ENG-200035</Description>
<Note>Cideon Baugruppe</Note>
<Note2>mb</Note2>
<Version>mb</Version>
<WorkingPlan>
<WorkingStep OperationNo="10">
<Activity>Assembling</Activity>
<Workplace>Montage</Workplace>
<ActivityDescription></ActivityDescription>
<FeedbackFlag>1</FeedbackFlag>
<Resources>
<Resource>
<ArticleNo>999</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>666666</ArticleNo>
<Quantity>2</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>897456</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>Baugruppe1</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Part PartNo="987654">
<PartNoExt>ENG-200035</PartNoExt>
<Description>ENG-200035</Description>
<Note>Cideon Baugruppe</Note>
<Note2>mb</Note2>
<Version>mb</Version>
<WorkingPlan>
<WorkingStep OperationNo="10">
<Activity>Assembling</Activity>
<Workplace>Montage</Workplace>
<ActivityDescription></ActivityDescription>
<FeedbackFlag>1</FeedbackFlag>
<Resources>
<Resource>
<ArticleNo>ENG-025420</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>ENG-217358</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
</Resources>
</WorkingStep>
</WorkingPlan>
</Part>
<Resource>
<ArticleNo>9999</ArticleNo>
<Quantity>3</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>ENG-217358</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>111111</ArticleNo>
<Quantity>2</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>ENG-245596</ArticleNo>
<Quantity>3</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
so sollte es rauskommen:
<Part PartNo="987654">
<PartNoExt>ENG-200035</PartNoExt>
<Description>ENG-200035</Description>
<Note>Cideon Baugruppe</Note>
<Note2>mb</Note2>
<Version>mb</Version>
<WorkingPlan>
<WorkingStep OperationNo="10">
<Activity>Assembling</Activity>
<Workplace>Montage</Workplace>
<ActivityDescription></ActivityDescription>
<FeedbackFlag>1</FeedbackFlag>
<Resources>
<Resource>
<ArticleNo>999</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>666666</ArticleNo>
<Quantity>2</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>897456</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>Baugruppe1</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>9999</ArticleNo>
<Quantity>3</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>ENG-217358</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>111111</ArticleNo>
<Quantity>2</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>ENG-245596</ArticleNo>
<Quantity>3</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
</Resources>
</WorkingStep>
</WorkingPlan>
</Part>
<Part PartNo="987654">
<PartNoExt>ENG-200035</PartNoExt>
<Description>ENG-200035</Description>
<Note>Cideon Baugruppe</Note>
<Note2>mb</Note2>
<Version>mb</Version>
<WorkingPlan>
<WorkingStep OperationNo="10">
<Activity>Assembling</Activity>
<Workplace>Montage</Workplace>
<ActivityDescription></ActivityDescription>
<FeedbackFlag>1</FeedbackFlag>
<Resources>
<Resource>
<ArticleNo>ENG-025420</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
<Resource>
<ArticleNo>ENG-217358</ArticleNo>
<Quantity>1</Quantity>
<UnitOfQuantity>Stk</UnitOfQuantity>
</Resource>
</Resources>
</WorkingStep>
</WorkingPlan>
</Part>
mein derzeitiger Code der dieses xml erstellt:
Private Sub QueryBOM(compDef As ComponentDefinition, Level As Long)
Dim oDoc As AssemblyDocument
Dim i As Long
Dim oBOM As BOM
Dim oRow As BOMRow
Dim oBOMView As BOMView
Dim oPartNumProperty As Property
Dim oCompDef As ComponentDefinition
Dim PartNumber, ArtNumber, prtquanty, lName As String
MsgBox "Level: " & Level
' If Level > 0 Then
' MsgBox "levelneu:" & Level
' If ArtNumber.Value = "" Then
' lName = oPartNumProperty.Value
' Else
' lName = ArtNumber.Value
' End If
'MsgBox " PartNr: " & lName & vbCrLf & "PartNoExt :" & oPartNumProperty.Value & vbCrLf & "Description: " & invBezCustomProp.Value
XMLFileText = XMLFileText & vbTab & vbTab & "<Part PartNo=" & Chr(34) & strPartNo & Chr(34) & ">" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "<PartNoExt>" & invPartNumberProperty.Value & "</PartNoExt>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "<Description>" & invPartNumberProperty.Value & "</Description>" & vbNewLine 'Name
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "<Note>" & invBezCustomProp.Value & "</Note>" & vbNewLine 'Bemerkung
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "<Note2>" & strUserName & "</Note2>" & vbNewLine 'user
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "<Version>" & strUserName & "</Version>" & vbNewLine 'user
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "<WorkingPlan>" & vbNewLine 'Arbeitsplan
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & "<WorkingStep OperationNo=" & Chr(34) & "10" & Chr(34) & ">" & vbNewLine 'Arbeitsplan
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & "<Activity>Assembling</Activity>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & "<Workplace>Montage</Workplace>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & "<ActivityDescription></ActivityDescription>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & "<FeedbackFlag>1</FeedbackFlag>" & vbNewLine 'wird rückgemeldet
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & "<Resources>" & vbNewLine 'Beginn unterbauteile
' End If
'MsgBox "QueryBom"
Set oBOM = compDef.BOM
' muss nicht sein
oBOM.StructuredViewFirstLevelOnly = True
oBOM.StructuredViewEnabled = True
Set oBOMView = oBOM.BOMViews.Item("Strukturiert") ' je nach installation - kann auch englisch sein
For i = 1 To oBOMView.BOMRows.Count
Set oRow = oBOMView.BOMRows.Item(i)
Set oCompDef = oRow.ComponentDefinitions.Item(1)
lName = ""
If TypeOf oCompDef Is VirtualComponentDefinition Then
'MsgBox "VirtualComponentDefinition"
Debug.Print "VirtualComponent"
Set oPartNumProperty = oCompDef.PropertySets.Item("Design Tracking Properties").Item("Part Number")
'Set ArtNumber = oCompDef.PropertySets.Item("User Defined Properties").Item("MAR_Artikelnummer")
Debug.Print Tab(Level); oPartNumProperty
Else
'MsgBox "bauteile bom"
'Debug.Print "bauteile bom"
Set oPartNumProperty = oCompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number")
Set ArtNumber = oCompDef.Document.PropertySets.Item("User Defined Properties").Item("MAR_Artikelnummer")
Debug.Print Space(Level) & oRow.ItemNumber & "; " & oRow.ItemQuantity & "; " & oPartNumProperty.Value & "; " & ArtNumber.Value & "; (" & oCompDef.Document.DisplayName & "); "
' MsgBox "bauteilcheck"
' If invDocTyp = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then 'Prüfen ob blech
' MsgBox "blech"
' On Error Resume Next
' PartNumber = oCompDef.Document.PropertySets("{32853F0F-3444-11D1-9E93-0060B03C1CA6}")("Part Number").Value
' If oCompDef.Document.PropertySets("User Defined Properties")("Laser").Value <> "Flachbettlaser" Then
' MsgBox " kein Flachbettlaser"
' 'GoTo weiter
' Else
' End If
' On Error Resume Next 'Check ob Normteil - dann nicht export
' If oCompDef.PropertySets.Item("User Defined Properties").Item("Normteil").Value <> "Ja" Then
' MsgBox "Normteil"
' Else
' 'GoTo weiter 'Auskommentier 16.7.
' End If
' If oCompDef.PropertySets.Item("User Defined Properties").Item("Zukauf").Value <> "Ja" Then
' MsgBox "Zukaufteil"
' Else
' GoTo weiter
' End If
' If oCompDef.PropertySets.Item("User Defined Properties").Item("Lager").Value <> "Ja" Then
' MsgBox "Lagerteil"
' Else
' GoTo weiter
' End If
'
' On Error Resume Next
' 'ArtNumber = oCompDef.Document.PropertySets("User Defined Properties")("MAR_Artikelnummer").Value
''MsgBox " wertetest"
If ArtNumber.Value = "" Then
lName = oPartNumProperty.Value
'' 'If Len(Right(oPartNumProperty.Value, Len(oPartNumProperty.Value) - 5)) > 8 Then 'änderung 23.10.2019 wegen zu langen bauteilnummern
'' lName = Right(oPartNumProperty.Value, 0)
''' 'lName = Right(oPartNumProperty.Value, 8)
'' Else
'' lName = oPartNumProperty.Value 'seit 17.02.2018
''' 'lName = Right(oPartNumProperty.Value, Len(oPartNumProperty.Value) - 5) 'seit 8.8.18
'' End If
Else
lName = ArtNumber.Value
End If
MsgBox "wertetabelle"
prtquanty = oRow.ItemQuantity
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & "<Resource>" & vbNewLine '
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & "<ArticleNo>" & lName & "</ArticleNo>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & "<Quantity>" & oRow.ItemQuantity & "</Quantity>" & vbNewLine 'benötigte Stückzahl in Baugruppe
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & "<UnitOfQuantity>Stk</UnitOfQuantity>" & vbNewLine 'Artikelnummer Unterbauteil
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & "</Resource>" & vbNewLine
' End If
' XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & "</Resources>" & vbNewLine
' XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & "</WorkingStep>" & vbNewLine
' XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "</WorkingPlan>" & vbNewLine
' XMLFileText = XMLFileText & vbTab & vbTab & "</Part>" & vbNewLine
If oCompDef.Document.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
MsgBox "noch eine baugruppe"
Call QueryBOM(oCompDef, Level + 1)
End If
' If Level <> 0 Then
' End If
End If
weiter:
Next
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & vbTab & "</Resources>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & vbTab & "</WorkingStep>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & vbTab & "</WorkingPlan>" & vbNewLine
XMLFileText = XMLFileText & vbTab & vbTab & "</Part>" & vbNewLine
' oDef.RepresentationsManager.LevelOfDetailRepresentations.Item(myLOD_Name).Activate
MsgBox "raus aus queryBom"
End Sub
ich hatte gehofft, ich könnte im "XMLFileText" das Level mitgeben und am ende alle LEvel nach einander in die xml schreiben... leider finde ich nichts zu dem thema... xmlfiletext ist ein variant.
vielleicht hätte jemand eine idee...
vielen Dank.
Gelöst! Gehe zur Lösung
Gelöst von martin_winkler. Gehe zur Lösung
Hallo Michael, uih das ist ja erstmal alleine lesetechnisch ein Brocken.
Unabhängig von deiner eigentlichen Fragestellung würde ich dir gerne ein paar Tipps mitgeben.
1. Beschäftige dich im Zusammenhang mit lesen und schreiben von xml Dateien einmal mit der Microsoft XML Klasse. Damit kannst du xml Dateien strukturiert erstellen und lesen. Du kannst die XML Klasse über die Verweise in VBA einbinden.
Hier Codebeispiele wie man damit arbeiten kann:
Sub TestWrite()
Call Write_XML("C:\Temp\test.xml", "TestCode", "TestPartnumber", "TestDate")
End Sub
Public Sub Write_XML(Path As String, strCode As String, strPartnumber As String, strDate As String)
Dim oDoc As MSXML2.DOMDocument60
Dim oRoot As MSXML2.IXMLDOMElement
Dim oDataSet As MSXML2.IXMLDOMElement
Dim oDataSet1 As MSXML2.IXMLDOMElement
Dim oDataSet2 As MSXML2.IXMLDOMElement
Dim oDataSet3 As MSXML2.IXMLDOMElement
Dim oDataSet4 As MSXML2.IXMLDOMElement
Dim oDataSet5 As MSXML2.IXMLDOMElement
Set oDoc = New MSXML2.DOMDocument60
oDoc.async = False
oDoc.validateOnParse = False
oDoc.appendChild oDoc.createProcessingInstruction("xml", "version=""1.0"" encoding=""utf-8""")
Set oRoot = oDoc.appendChild(oDoc.createElement("root"))
Set oDataSet = oDoc.createElement("Codierung")
oRoot.appendChild oDataSet
Set oData1 = oDataSet.appendChild(oDoc.createElement("Code"))
Set oData2 = oDataSet.appendChild(oDoc.createElement("PartNumber"))
Set oData3 = oDataSet.appendChild(oDoc.createElement("Date"))
'Set oData4 = oDataSet.appendChild(oDoc.createElement("Erstellungsdatum"))
'Set oData5 = oDataSet.appendChild(oDoc.createElement("Freigabe"))
'Set oData6 = oDataSet.appendChild(oDoc.createElement("Freigabe_Datum"))
'Set oData7 = oDataSet.appendChild(oDoc.createElement("Status"))
oData1.Text = strCode
oData2.Text = strPartnumber
oData3.Text = strDate
'oData4.Text =
'oData5.Text =
'oData6.Text =
'oData7.Text =
oDoc.Save (Path)
End Sub
Sub TestRead()
Debug.Print (Read_XML_Codierung("C:\Temp\test.xml", "TestCode"))
End Sub
Public Function Read_XML_Codierung(Path As String, oCodierung As String) As Boolean
Dim oDoc As MSXML2.DOMDocument60
Dim oRoot As MSXML2.IXMLDOMNode
Set oDoc = New MSXML2.DOMDocument60
oDoc.async = False
oDoc.validateOnParse = False
oDoc.Load (Path)
Set oRoot = oDoc.DocumentElement
Dim oDataSet As MSXML2.IXMLDOMNode
Dim oDataSetElement As MSXML2.IXMLDOMNode
For Each oDataSet In oRoot.ChildNodes
If oDataSet.nodeType = NODE_ELEMENT Then
'Debug.Print oDataSet.baseName
For Each oDataSetElement In oDataSet.ChildNodes
'Debug.Print DataSetElement.nodeType
If oDataSetElement.baseName = "Code" Then
Debug.Print oDataSetElement.nodeTypedValue
If oDataSetElement.nodeTypedValue = oCodierung Then
Read_XML_Codierung = True
Exit Function
Else
Read_XML_Codierung = False
End If
End If
Next
End If
Next
End Function
2. In VBA würde ich eher Debug.Print("Meldung") verwenden an Stelle der vielen Msg Boxen.
Zu deiner Frage:
Was ist das Ziel des Exports? Wofür willst du die Daten später verwenden bzw. wo willst du sie einlesen?
Ist es hierfür erforderlich die Stücklistenstruktur zu verwenden?
Oder würde auch die Analyse der Baugruppe über die Occurrences möglich sein (Einträge im Browserbaum)?
Zu letzterem gibt es in der API Hilfe und im Netz Beispiele (Suchbegriff TraverseAssembly). Damit kann auch der Level bestimmt werden. Der Browserbaum wird dabei recursiv durchlaufen.
Hier der stark verkürzte Code:
Public Sub TraverseAssemblySample()
' Get the active assembly.
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument
Debug.Print oAsmDoc.DisplayName
' Call the function that does the recursion.
Call TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, 1)
End Sub
Private Sub TraverseAssembly(Occurrences As ComponentOccurrences, _
Level As Integer)
' Iterate through all of the occurrence in this collection. This
' represents the occurrences at the top level of an assembly.
Dim oOcc As ComponentOccurrence
For Each oOcc In Occurrences
' Print the name of the current occurrence.
Debug.Print Space(Level * 3) & oOcc.Name
' Check to see if this occurrence represents a subassembly
' and recursively call this function to traverse through it.
If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
Call TraverseAssembly(oOcc.SubOccurrences, Level + 1)
End If
Next
End Sub
Ich hoffe das hilft dir weiter.
hallo Martin
Vielen Dank erstmal für deine Antwort und den Input.
Verwendet wird die XML zum Importieren der Bauteile in unser Fertigungssystem, ich übergebe direkt vom Inventor auf unsere Trumpf-Maschinen-Steuerung.
Generell funktioniert das mit einzelbauteilen perfekt - wird auch schon seit ca. 2 Jahren so gelebt... aber jetzt haben wir eine neue funktion bei der Maschinensteuerung die auch Baugruppen verarbeiten kann...
daher die adaptierung des codes...
die strukturierung der XML habe ich generell schon heraussen, das problem wie gesagt ist, wenn ich in einer Baugruppe (roter kasten) mich befinde und diese auf die Maschine übertragen möchte, soll der als erstes nur die Bauteile (oranger kasten) dieser iam auflisten, ist darin eine weitere iam (gelbe markierung) enthalten, soll diese (grüner Kasten) dann nachstehend an die erste iam auch die einzelteile (blauer kasten) aufgelistet werden...
somit kenn das maschinensystem bei der beauftragung aus welchen unterbauteilen die baugrp besteht... und rechnet selbst die benötigten stückzahlen usw...
einzelteile übergeben ist auch kein problem, aber wie gesagt, ich muß erst die eine baugruppe (flache liste) dann die nächste usw. übergeben und nicht eine baugruppe und alle unterbauteile auch der unterbaugruppen....
ich hoffe ich konnte das einigermassen verständlich erklären... (wenn man damit arbeitet ist es ja selbstverständlich - das jemand anderes zu veranschaulichen, daran scheitere ich meist...) 😉
Lass doch mal das Traverse Assembly Beispiel über eine Baugruppe laufen und schau dir das Ergebnis im Direktfenster an. Ich denke schon, dass es das ist was du brauchst. Du kannst dann auf dem jeweiligen Level sehen was für Teile in den Unterbaugruppen drin stecken und das entsprechend verarbeiten.
Mich würde der Vorgang in sofern interessieren, da es eine schöne Erweiterung meiner Multi Export Tools sein könnte. Wenn du magst melde dich per PN bei mir.
hallo martin
hab jetzt deinen code mal laufen lassen, grundsätzlich ja, ABER, im ersten lauf sollen nur die bauteile der ersten baugruppe aufgelistet werden (keine unterebene) und dann erst - anschließend an die grundebene - sollen dann die nbauteile der unterbaugruppe aufgelistet werden...
pn ist kein problem... wenns dich interessiert können wir gerne darüber reden worums hier genau geht...
hallo martin
hab mal deinen Code laufen lassen, grundsätzlich macht der eh das was er soll, aber nicht ganz das was ich brauch... aber im prinzip das was ich schon habe... siehe letzen screenshot - das wäre quasi der output von deinem Code
er müsste die Basis - iam durcharbeiten und auflisten, dann erst in die unterbraugruppe und diese nachstehend auflisten...
wegen PN, kein problem, kann dir gerne mehr infos geben...
Über die Variable Level kannst du bestimmen auf welcher Ebene du dich gerade befindest.
Also müsste man den Programmablauf dahin gehend anpassen das zunächst alle Bauteile aus Level = 1 ausgegeben werden, im nächsten Schritt lässt du alle Bauteile aus Level 2 rausschrieben etc.
Stellt sich allerdings die Frage was passieren soll, wenn es mehrere Baugruppen z.B. in Level = 2 gibt.
Da wäre dann noch etwas Tüftelei nötig.
Weiter ist mir unklar wie gleiche Bauteile behandelt werden sollen. Also Bauteil A taucht in einer Baugruppe auf Level 2 auf und mehrfach in Baugruppen auf Level 3.
Ebenso ist mir unklar warum du die Bauteile in Bezug auf Baugruppen in die Trumpf Steuerung einlesen willst. Der einfachste Weg wäre doch über Assembly.AllReferencedDocuments alle Bauteile auszulesen und zu übergeben? (Assembly = oberste baugruppe)
Oder du gehst hin und schreibst mit ActiveAssembly.ReferencedDocuments nur die Bauteile der jeweilig gerade aufgerufenen Baugruppe raus. (ActiveAssembly = gerade aktive Baugruppe im jeweiligen Level).
Das setzt natürlich voraus das du deine XML Datei fortschreiben kannst. Das geht möglicherweise besser wenn du die Micorsoft XML Klasse verwendest.
hallo Martin
Danke für die Info..
Zu deinen Fragen:
Baugruppe und deren Unterbauteil deswegen, damit die Beauftragung einer Baugruppe direkt aus dem ERP erfolgen kann und sich trumpf die benötigten bauteile selbst zusammensucht und die quantity berechnet.
Wenn mehrfach vorkommende Bauteile auftauchen ist das kein problem, da wie gesagt immer die Baugruppe und derenen Unterbauteile eigenständig beauftragt wird... mehrfachteile werden hier berücksichtigt...
generell durchlaufe ich nach der BOM auch alle vorkommenden teile (alle ebenen ) und übergebe diese in die Stammmdaten bei trumpf....
das mit der Levelnummer hab ich schon mitbekommen, bin auch ncoh am tüfteln, derzeit harperts noch die an der richtigen stelle einzufügen. (auch bei tieferen strukturen aktualisiert sich die levelzahl selbst)
Hallo Martin,
Ich bin mittlerweile schon ein ganzes stück weiter, der code den du mir geschickt hast, war sehr hilfreich... es klappt dass ich mehrere Ebenen nacheinander entsprechend anfüge und das auch richtig, ABER jetzt ist das aufgepoppt, dass in einer ebene mehrere baugruppen sein können nicht nur in der 1. eine, dann in der 2. ebene eine usw..
und hier ist mein problem wieder...
ich starte quasi hier:
Public Sub BOM_auslesen() '(ByVal Document As Document)
Dim oDoc As AssemblyDocument
Dim oComp As ComponentDefinition
Set oDoc = ThisApplication.ActiveDocument
Set oComp = oDoc.ComponentDefinition
Debug.Print oDoc.DisplayName
On Error Resume Next
Set invDoc = ThisApplication.ActiveDocument
Set invProp = invDoc.PropertySets.Item("Design Tracking Properties")
Set invCProp = invDoc.PropertySets.Item("Inventor User Defined Properties")
Set invPropSubType = invProp.Item("Document SubType Name")
Set invPropSubTypeNo = invProp.Item("Document SubType")
Set invPartNumberProperty = invProp.Item("Part Number")
Set invBezCustomProp = invProp.Item("Description")
'Set oDef = invDoc.ComponentDefinition
'anfang gundbom
Debug.Print "Anfang von " & oDoc.DisplayName
Level = 0
LevelsCnt = 0
'Call RessourceStart(0, GetlNameProp(oDoc), invPartNumberProperty.Value, invBezCustomProp.Value, strUserName.Value)
Call RessourceStart(0)
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & "<Part PartNo=" & Chr(34) & strPartNo & Chr(34) & ">" & vbNewLine
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & "<PartNoExt>" & invPartNumberProperty.Value & "</PartNoExt>" & vbNewLine
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & "<Description>" & invPartNumberProperty.Value & "</Description>" & vbNewLine 'Name
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & "<Note>" & invBezCustomProp.Value & "</Note>" & vbNewLine 'Bemerkung
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & "<Note2>" & strUserName & "</Note2>" & vbNewLine 'user
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & "<Version>" & strUserName & "</Version>" & vbNewLine 'user
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & "<WorkingPlan>" & vbNewLine 'Arbeitsplan
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & vbTab & "<WorkingStep OperationNo=" & Chr(34) & "10" & Chr(34) & ">" & vbNewLine 'Arbeitsplan
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & vbTab & vbTab & "<Activity>Assembling</Activity>" & vbNewLine
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & vbTab & vbTab & "<Workplace>Montage</Workplace>" & vbNewLine
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & vbTab & vbTab & "<ActivityDescription></ActivityDescription>" & vbNewLine
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & vbTab & vbTab & "<FeedbackFlag>1</FeedbackFlag>" & vbNewLine 'wird rückgemeldet
' XMLFiletext(0) = XMLFiletext(0) & vbTab & vbTab & vbTab & vbTab & vbTab & "<Resources>" & vbNewLine 'Beginn unterbauteile
Debug.Print "einstieg in QueryBom"
Call QueryBOM(oComp, 0)
Call RessourceClose(0)
Debug.Print "zurück in BOM_Auslesen mit LevelsCnt: " & LevelsCnt
If LevelsCnt > 0 Then
Level = 1
For Level = 1 To LevelsCnt
Debug.Print "schreibe LEvel: " & Level & " in Level 0"
XMLFiletext(0) = XMLFiletext(0) & vbNewLine & XMLFiletext(Level)
Next
End If
If strProg = 1 Then GoTo Abbruch
GoTo Ende
fehler:
Call MsgBox("Error: " & Err.Description & vbNewLine & "Fehlernummer: " & Err.Number)
Abbruch:
Exit Sub
Ende:
End Sub
und springe dann in die unterbaugruppe (levels) mit dem hier:
Private Sub QueryBOM(compDef As ComponentDefinition, Level As Long)
Dim i As Long
Dim oBOM As BOM
Dim oRow As BOMRow
Dim oBOMView As BOMView
Dim oPartNumProperty As Property
Dim bomRowCompDef As ComponentDefinition
Set oBOM = compDef.BOM
oBOM.StructuredViewFirstLevelOnly = True
oBOM.StructuredViewEnabled = True
Set oBOMView = oBOM.BOMViews.Item("Strukturiert") ' je nach installation - kann auch englisch sein
Debug.Print "Level bei einstieg: " & Level
If Level > LevelsCnt Then
Debug.Print "Level: " & Level & " > LevelsCnt: " & LevelsCnt
LevelsCnt = Level
ReDim Preserve XMLFiletext(Level)
On Error Resume Next
Debug.Print "XML anfang schreiben Level: " & Level
Set invPartNumberProperty = compDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number")
Set invBezCustomProp = compDef.Document.PropertySets.Item("Design Tracking Properties").Item("Description")
'Anfang für Unterbaugruppen
Call RessourceStart(Level)
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & "<Part PartNo=" & Chr(34) & lname & Chr(34) & ">" & vbNewLine
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & "<PartNoExt>" & invPartNumberProperty.Value & "</PartNoExt>" & vbNewLine
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & "<Description>" & invPartNumberProperty.Value & "</Description>" & vbNewLine 'Name
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & "<Note>" & invBezCustomProp.Value & "</Note>" & vbNewLine 'Bemerkung
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & "<Note2>" & strUserName & "</Note2>" & vbNewLine 'user
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & "<Version>" & strUserName & "</Version>" & vbNewLine 'user
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & "<WorkingPlan>" & vbNewLine 'Arbeitsplan
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & vbTab & "<WorkingStep OperationNo=" & Chr(34) & "10" & Chr(34) & ">" & vbNewLine 'Arbeitsplan
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & vbTab & vbTab & "<Activity>Assembling</Activity>" & vbNewLine
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & vbTab & vbTab & "<Workplace>Montage</Workplace>" & vbNewLine
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & vbTab & vbTab & "<ActivityDescription></ActivityDescription>" & vbNewLine
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & vbTab & vbTab & "<FeedbackFlag>1</FeedbackFlag>" & vbNewLine 'wird rückgemeldet
' XMLFiletext(Level) = XMLFiletext(Level) & vbTab & vbTab & vbTab & vbTab & vbTab & "<Resources>" & vbNewLine 'Beginn unterbauteile
Else
Debug.Print "Level: " & Level & " <= LevelsCnt: " & LevelsCnt
End If
Debug.Print "Level: " & Level & " Levlscnt: " & LevelsCnt
On Error Resume Next
Debug.Print "xml anfang fertig Level: " & Level
For i = 1 To oBOMView.BOMRows.Count
Set oRow = oBOMView.BOMRows.Item(i)
Set bomRowCompDef = oRow.ComponentDefinitions.Item(1)
Set oPartNumProperty = bomRowCompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number")
Set ArtNumber = bomRowCompDef.Document.PropertySets.Item("User Defined Properties").Item("MAR_Artikelnummer")
Debug.Print "Level:"; Level & " Zeile: " & oRow.ItemNumber & " Stückzahl: " & oRow.ItemQuantity & " Bauteilnummer: " & oPartNumProperty.Value & " (" & bomRowCompDef.Document.DisplayName & ")" & "Artnr.: " & ArtNumber.Value & " LevelsCnt: " & LevelsCnt
lname = GetlNameProp(bomRowCompDef.Document)
'Start BOM auslesen
If TypeOf bomRowCompDef Is VirtualComponentDefinition Then
Set oPartNumProperty = bomRowCompDef.PropertySets.Item("Design Tracking Properties").Item("Part Number")
Debug.Print Tab(Level); oPartNumProperty
Else
If bomRowCompDef.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then 'Blechteile
Select Case True
Case GetPropertyValue(bomRowCompDef.Document, "User Defined Properties", "Laser") <> "Flachbettlaser" 'getPropertyValue
Case GetPropertyValue(bomRowCompDef.Document, "User Defined Properties", "Normteil") = "Ja" 'getPropertyValue
Case GetPropertyValue(bomRowCompDef.Document, "User Defined Properties", "Lager") = "Ja" 'getPropertyValue
Case GetPropertyValue(bomRowCompDef.Document, "User Defined Properties", "Zukauf") = "Ja" 'getPropertyValue- GetPropValue
Case Else
Call Ressource(Level, GetlNameProp(bomRowCompDef.Document), oRow.ItemQuantity) 'Ressource aus Bauteil schreiben
End Select
End If
If bomRowCompDef.Document.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then 'wenn baugruppe
'Baugruppe noch in Ressourcen in Parent schreiben
Call Ressource(Level, GetlNameProp(bomRowCompDef.Document), oRow.ItemQuantity)
Debug.Print "neue Baugruppe entdeckt!" & oRow.ItemNumber
Call QueryBOM(bomRowCompDef, Level + 1) 'neustart der QueryBOM mit Baugruppe als Parent
End If
End If
Next
Debug.Print "Ende schreiben Level: " & Level
If Level > 0 Then
Debug.Print "Ende schreiben Level>0: " & Level
Call RessourceClose(Level) 'Schliessen der Ressource
End If
GoTo Final:
fehler:
Call MsgBox("Error: " & Err.Description & vbNewLine & "Fehlernummer: " & Err.Number & vbNewLine & "Fehler-Bauteil: " & strErrPrt, vbCritical)
GoTo Final
Final:
End Sub
natürlich viel bla bla dabei...
ich müsste aber, jedesmal wenn ich aus der Baugruppe wieder in das ursprungslevel komme diese direkt abschließen... und in die xml schreiben.
Hallo Michael, bist du mit deinem Projekt weiter gekommen?
ja danke, habs hinbekommen, ich arbeite das ganze jetzt mit einer Liste ab, ich gehe quasi die Bom durch und jede Baugruppe wird in eine eigene "Scripting.Dictionary" liste geschrieben und nach der Baugruppe benannt, am ende setzte ich einfach eine liste nach der anderen in meine XML ein und voila... perfektes Ergebnis.
Aber danke für deine tips, haben mir unheimlich weitergeholfen....
Sie finden nicht, was Sie suchen? Fragen Sie die Community oder teilen Sie Ihr Wissen mit anderen.