| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Parameterübergabe bei Autodesk Inventor AddIn-Nutzung (3785 mal gelesen)
|
qwer.beet Mitglied
Beiträge: 12 Registriert: 25.02.2011 Inventor 2011 VB 2008 Express
|
erstellt am: 17. Dez. 2011 17:52 <-- editieren / zitieren --> Unities abgeben:
Hallo Community. Mein Problem: Ich habe vor gut einem Jahr ein kleines AddIn für Inventor geschrieben - jedoch unter Zuhilfenahme der in Inventor integrierten iLogic-Funktionen. Soll heißen, ich habe den Aufruf meines Eingabeformluars und die Bereitstellung der in Inventor verwendeten Namen über iLogic gesteuert, den Rest in VB programmiert. iLogic-Code:
Code: AddReference "Foerderband.dll"Parameter.UpdateAfterChange = True ' automatische Aktualisierung MultiValue.UpdateAfterChange = True iLogicVb.UpdateWhenDone = True localTrigger = iTrigger0 Using dlg as New Foerderband.foerderband ' VB-Name = INV-Name dlg.Parameter = Parameter dlg.MultiValue = MultiValue dlg.Component = Component dlg.iProperties = iProperties dlg.gurt_list = MultiValue.List("Foerdergurt") ' Foerdergurtarten uebergeben dlg.ShowDialog() ' Dialog wird aufgerufen End Using
Hierdurch war es mir möglich, in VB durch die einfache Codezeile
Code: Parameter("Bauteil", "Parametername") = Textbox.text
dem entsprechenden Parameter eines Bauteils den neuen Wert der in der Textbox steht zuzuordnen.Da ich das AddIn jetzt mit dem von Inventor zur Verfügung gestellten "Autodesk Inventor AddIn" komplett in VB erstellen möchte, fällt der iLogic-Teil weg, wodurch mir die Inventornamen fehlen und meine einfache Parameterübergabe nicht mehr funktioniert. Nun zu meiner Frage: Muss ich einfach nur einen neuen Verweis anlegen? Oder muss ich die Zuordnung der Parameter ganz anders angehen? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
qwer.beet Mitglied
Beiträge: 12 Registriert: 25.02.2011 Inventor 2011 VB 2008 Express
|
erstellt am: 19. Dez. 2011 13:29 <-- editieren / zitieren --> Unities abgeben:
Problem gelöst - oder zumindest einen Ansatz gefunden... Der Beitrag von GeorgK Parameter verknüpfen scheint die Lösung für mein Problem zu enthalten. Ändere ich den Code für meine Zwecke ab, hagelt es jedoch eine Fehlermeldung nach der anderen Schon bei der Übertragung (copy&paste) des Codes bekomme ich die Fehlermeldung, dass ThisApplication nicht deklariert wurde. Gehe ich richtig in der Annahme, dass
Code: Dim ThisApplicatian as Inventor.Application
mein Problem löst? Danach verschwindet die Fehlermeldung.Nach der Anpassung sieht der Code wie folgt aus.
Code: Imports InventorPublic Class InsertBoltForm Dim ThisApplication As Inventor.Application Private Sub InsertBoltForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub BTN_ok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_ok.Click ' Get the Parameters object. Assumes a part or assembly document is active. Dim oParameters As Parameters oParameters = ThisApplication.ActiveDocument.ComponentDefinition.Parameters ' Get the parameter. Dim oParam As Parameter oParam = oParameters.Item("d1") ' Write the equation of the parameter in the textbox. TB_breite.Text = oParam.Expression ' Update the document. 'ThisApplication.ActiveDocument.Update() End Sub End Class
AddIn lässt sich jetzt ohne Probleme erstellen und registrieren. Auch der Aufruf in INV funktioniert noch immer einwandfrei. Nach einem Klick auf den OK-Button kommt jedoch eine Fehlermeldung (siehe Anhang - bei Bedarf auch gerne den kompletten Fehlertext. Ich werde daraus einfach nicht schlau :(). Kommentiere ich - von unten nach oben - eine Codezeile nach der anderen aus um den Fehler zu finden, bleibt zu Schluss nur noch
Code: oParameters = ThisApplication.ActiveDocument.ComponentDefinition.Parameters
stehen und die Fehlermeldung erscheint trotzdem... Liegt der Fehler in
Code: Dim ThisApplication As Inventor.Application
oder doch inCode: oParameters = ThisApplication.ActiveDocument.ComponentDefinition.Parameters
?Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
rkauskh Moderator Dipl.-Ing. (FH) Versorgungstechnik
Beiträge: 2166 Registriert: 15.11.2006 Windows 10 x64, AIP 2022
|
erstellt am: 19. Dez. 2011 19:18 <-- editieren / zitieren --> Unities abgeben: Nur für qwer.beet
Hi Du deklarierst zwar eine Variable ThisApplication (würde ich wegen Verwechslungsgefahr anders nennen, z.B. myInventor), aber du weist ihr keinen Wert zu. Setz mal in deine BTN_ok_Click-Sub folgendes: Code:
Imports InventorPublic Class InsertBoltForm Public myInventor As Inventor.Application = Nothing Private Sub BTN_ok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_ok.Click 'Zuerst Inventorinstanz kapern If InventorLoad(myInventor) Is Nothing Then Exit Sub End If ' Get the Parameters object. Assumes a part or assembly document is active. Dim oParameters As Parameters oParameters = myInventor.ActiveDocument.ComponentDefinition.Parameters ' Get the parameter. Dim oParam As Parameter oParam = oParameters.Item("d1") ' Write the equation of the parameter in the textbox. TB_breite.Text = oParam.Expression ' Update the document. 'MyInventor.ActiveDocument.Update() End Sub End Class
Und dann fügst du in deine Klasse noch diese Funktion mit ein: Code: Private Function InventorLoad(ByRef myInventor As Inventor.Application) As Inventor.Application Try ' Try to get an active instance of Inventor Try myInventor = System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application") Catch ex As Exception End Try ' If not active, create a new Inventor session If myInventor Is Nothing Then Dim inventorAppType As Type = System.Type.GetTypeFromProgID("Inventor.Application") myInventor = System.Activator.CreateInstance(inventorAppType) End If myInventor.Visible = True myInventor.SilentOperation = True ' Inventor läuft und wir sind verbunden Return myInventor Catch ex As Exception Return Nothing End Try End Function
Alles aus'n Kopf, also eventuell nicht ganz fehlerfrei. ------------------ MfG RK Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
qwer.beet Mitglied
Beiträge: 12 Registriert: 25.02.2011 Inventor 2011 VB 2008 Express
|
erstellt am: 21. Dez. 2011 11:48 <-- editieren / zitieren --> Unities abgeben:
Vielen Dank, funktioniert einwandfrei! Kann ich in meiner Baugruppe auch eine Etage tiefer gehen? Ich kann doch sicherlich statt
Code: Dim oDocs as myInventor._Documents oDocs = myInventor.ActiveDocument
auch
Code: oDocs = myInventor.Documents
schreiben, oder? In oDocs stand dann meine geöffnete Baugruppe. Mein nächster Gedankengang war, dass ich von hieraus auch irgendwie die Parameter der einzelnen Bauteile in meiner Baugruppe ansprechen können muss. Leider ist es mir auch nach unzähligen Versuchen nicht gelungen, eines der Bauteile in meine Variable oPart zu schreiben :( Ich habe mich an der Autodesk Inventor 2011 API Object Model.pdf orientiert. Das gewünschte Bauteil müsste dann doch durch
Code: Dim oPart as myInventor._PartDocument oPart = myInventor.Documents.PartDocument
zu bekommen sein?[Diese Nachricht wurde von qwer.beet am 21. Dez. 2011 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
rkauskh Moderator Dipl.-Ing. (FH) Versorgungstechnik
Beiträge: 2166 Registriert: 15.11.2006 Windows 10 x64, AIP 2022
|
erstellt am: 21. Dez. 2011 19:15 <-- editieren / zitieren --> Unities abgeben: Nur für qwer.beet
|
qwer.beet Mitglied
Beiträge: 12 Registriert: 25.02.2011 Inventor 2011 VB 2008 Express
|
erstellt am: 22. Dez. 2011 19:48 <-- editieren / zitieren --> Unities abgeben:
Also Code: Dim oRefDoc As XXX oRefDoc = oMyInv.ActiveDocument.ReferencedDocuments
? Aber wie deklariere ich dann? SuFu bringt mich nur auf DocumentsEnumerator (Link), was aber in einer Fehlermeldung endet. Stundenlanges ausprobieren hat mich auch nicht weiter gebracht [Diese Nachricht wurde von qwer.beet am 22. Dez. 2011 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
rkauskh Moderator Dipl.-Ing. (FH) Versorgungstechnik
Beiträge: 2166 Registriert: 15.11.2006 Windows 10 x64, AIP 2022
|
erstellt am: 22. Dez. 2011 21:42 <-- editieren / zitieren --> Unities abgeben: Nur für qwer.beet
Hi Steht doch im verlinkten Thread mit drin: Code:
Dim oRefDocs As DocumentsEnumerator Set oRefDocs = oAssemblymDoc.AllReferencedDocumentsDim oRefDoc As Document For Each oRefDoc In oRefDocs ... Next
Oder du schaust dir im selben Thread meinen Beitrag mit dem rekursiven Durchlaufen aller Suboccurrences an. Die Occurrences haben nur den "Nachteil", das du mehrfach verbaute Teile dann auch mehrfach greifst. ------------------ MfG RK Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
qwer.beet Mitglied
Beiträge: 12 Registriert: 25.02.2011 Inventor 2011 VB 2008 Express
|
erstellt am: 18. Jan. 2012 12:26 <-- editieren / zitieren --> Unities abgeben:
Problem gelöst - wenn auch, mMn, sehr umständlich Vielen, vielen Dank für die Hilfe Im Code des Buttons steht eine Aufruf einer Sub. In der Sub werden alle in oRefDocs enthaltenen Bauteile durch eine Schleife nach einem bestimmten durchsucht. Bei jedem Durchlauf der Schleife wird ein Zähler erhöht, mit dem - sobald das gesuchte Teil gefunden wurde - über oRefDocs.Item(Zähler) das gewünschte Bauteil erhalten und zurückgeben wird. (Wer einen direkteren Weg kennt, möge ihn mir doch bitte mitteilen ) Code: Private Sub BTN_ok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_ok.Click Call FindPart("Grundgeruest.ipt") ' Suche Beuteilnummer oPartPara = oPart.ComponentDefinition.Parameters ' Schreibe in oPartPara alle im Bauteil vorhandenen Parameter oPartPara.Item("breite").Expression = TB_breite.Text oPartPara.Item("Abstand_Stuetze").Expression = TB_abstand.Text End Sub Private Sub FindPart(ByRef PartName As String) Dim oRefDoc As Document PartCounter = 0 ' Suche in allen Bauteilen For Each oRefDoc In oRefDocs PartCounter = PartCounter + 1 ' Zähler der internen Nummer If oRefDoc.DisplayName = PartName Then ' Stimmt gesuchter Name mit aktuellem überein, dann Schleife verlassen Exit For End If Next oPart = oRefDocs.Item(PartCounter) ' Setzte Bauteil mit Nummer = PartCounter aktiv End Sub
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
daywa1k3r Moderator Softwareentwickler
Beiträge: 3497 Registriert: 01.08.2002 Desktop: 3.3GHz;8GB;SSD OCZ Vertex 3;Gainward Phantom GTX570 Laptop: Alienware m17x Win7, Inventor2012
|
erstellt am: 18. Jan. 2012 13:05 <-- editieren / zitieren --> Unities abgeben: Nur für qwer.beet
Ist Dein Nick auf Deinen Programmierstil bezogen? Naja Abgesehen davon, dass Deine Daten (Part, RefDocs,…) überall verstreut sind, beinhaltet Dein Code keinerlei Fehlerbehandlung. Für die Funktion reicht im Prinzip das: Code:
private Inventor.Document FindPart(string SearchDisplayName) { Inventor.AssemblyDocument oAsm = null; foreach (Inventor.Document oDoc in oAsm.AllReferencedDocuments) { if (oDoc.DisplayName == SearchDisplayName) return oDoc; } return null; // Nichts gefunden... }
Deine alte Funktion liefert immer entweder 0 oder max zurück. Und das muss nicht unbedingt richtig sein, z.B. wenn dein Bauteil nicht gefunden wurde. Und glaube mir, da gibt es genug Fälle wie Benutzer-Tippfehler, oder einfach der tägliche Inventor API Wahnsinn, die es dazu führen werden, dass deine Funktion nur scheinbar richtige Ergebnisse liefert. Den Aufruf würde ich dann in etwa so gestalten: Code:
if (FindPart("Grundgeruest.ipt") != null) { oPartPara = oPart.ComponentDefinition.Parameters; oPartPara.Item("breite").Expression = TB_breite.Text; oPartPara.Item("Abstand_Stuetze").Expression = TB_abstand.Text; } else { // Bauteil nicht gefunden - behandeln... }
Viel Glück damit! PS: Ah ja, ist C# - dürfte aber nachvollziehbar sein? ------------------ Grüße Igor FX64 Software Solutions - Inventor Tools FX64 LambdaSpect - Lichtsimulation mit Autodesk Inventor Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
qwer.beet Mitglied
Beiträge: 12 Registriert: 25.02.2011 Inventor 2011 VB 2008 Express
|
erstellt am: 12. Feb. 2012 19:07 <-- editieren / zitieren --> Unities abgeben:
Oh Mann! Da warte ich wochenlang auf eine Antwort und dabei steht sie schon die ganze Zeit da Bei der Fehlerbehandlung muss ich dir zustimmen. War noch nie meine Stärke... Aber was meinst du damit, dass meine Daten überall verstreut sind? Nachdem ich die Suche zu Testzwecken mit einem anderen Bauteil gestartet habe, bekomme ich nicht mehr die richtige Antwort - zu früh gefreut Habe deinen C#-Code in
Code: Private Sub FindPart(ByRef vPartName As String) Dim oAsm As Inventor.AssemblyDocument Dim oDoc As Inventor.Document oAsm = oMyInv.ActiveDocument vPartCounter = 0 For Each oDoc In oAsm.AllReferencedDocuments vPartCounter = vPartCounter + 1 If oDoc.DisplayName = vPartName Then oPart = oRefDocs.Item(vPartCounter) Exit Sub End If Next End Sub
verwandelt. oAsm = oMyInv.ActiveDocument habe ich verwendet, da ich nicht weiß, wie ich eine Variable vom Typ AssemblyDocument auf Null setze. Der Zähler und die Übergabe oPart = oRefDocs.Item(vPartCounter) sind auch wieder vorhanden, weil ich einen dem return entsprechenden Befehl nicht finden konnte. Leider bringt mich das bei meiner Fehlermeldung nicht weiter.Die Private Sub FindPart wird ohne Fehler durchlaufen - frage ich nach dem letzten Durchlauf mein aktives Dokument ab, bekomme ich das richtige Ergebnis. Auch bei der Suche nach anderer Bauteilen. Danach ist aber Schluss mit Lustig. oPartPara = oPart.ComponentDefinition.Parameters funktioniert noch ohne Fehlermeldung - leider weiß ich da nicht, wie ich überprüfen könnte, ob die richtigen Werte in oPartPara stehen. Bei oPartPara.Item("breite").Expression = TB_breite.Text und oPartPara.Item("Abstand_Stuetze").Expression = TB_abstand.Text gibt es dann die besagte Fehlermeldung. Edit: Hm... tausche ich die Zuweisung - also TextBox = Parameter - geht's. Wo ist der Fehler? Ist TextBox.Text vllt String und die Parameter müssen in Integer übergeben werden? [Diese Nachricht wurde von qwer.beet am 12. Feb. 2012 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |