| | |
 | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für SolidEdge |
| | |
 | Durchgängige CAD/CAM-Prozesse für maximale Fertigungstiefe: Wie die FLAIG GmbH eine papierlose CNC-Fertigung realisierte, ein Anwenderbericht
|
|
Autor
|
Thema: Makros mit Delphi (1197 mal gelesen)
|
UweD Mitglied
 Beiträge: 6 Registriert: 04.02.2004
|
erstellt am: 04. Feb. 2004 11:31 <-- editieren / zitieren --> Unities abgeben:         
Hi, ich versuche gerade SolidEdge-Makros mit Delphi zu programmieren und die meisten Dinge funktionieren auch ganz prima. Nur die folgende Zeile aus dem SDK kriege ich nicht übersetzt: Set objModel = objDoc.Models.AddFiniteExtrudedProtrusion(NumberOfProfiles:=1, _ profileArray:=objProfile, profileplaneSide:= _ igRight, ExtrusionDistance:=0.05) Wie muss ich die Variable für das Array "objProfile" deklarieren? Falls jemand schon Erfahrungen mit SolidEdge und Delphi hat, bitte melden - Danke! MfG Uwe Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 04. Feb. 2004 12:04 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
|
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 04. Feb. 2004 12:07 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
|
UweD Mitglied
 Beiträge: 6 Registriert: 04.02.2004
|
erstellt am: 04. Feb. 2004 12:44 <-- editieren / zitieren --> Unities abgeben:         
Hi modeng, danke für die Antwort, aber die Definition in VB steht ja schon im SolidEdge-SDK. Ich bekomme sie nur nicht korrekt in Delphi umgesetzt. Bisher sieht es in Delphi so aus: var SeProfile: variant; SeModel: variant; begin SeProfile := VarArrayCreate([1,2], varVariant); SeProfile[1] := SeDoc.ProfileSets.Add.Profiles.Add(SeDoc.RefPlanes.Item(3)); SeModel := SeDoc.Models.AddFiniteExtrudedProtrusion(1, SeProfile, igRight, 0.05);
Im letzten Befehl (AddFinite...) bekomme ich zur Laufzeit immer die Fehlermeldung 'Typkonflikt'.
Gruß Uwe Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 04. Feb. 2004 13:58 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
Hi, sicher Type conflict weil das return Object ein Object des Typs Dim objModel As SolidEdgePart.Model ist. Variants (im Sinne von VB) sind so ich weiss im API nicht vorgesehen -- neutral waere Typ Object Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 04. Feb. 2004 14:07 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
also objProfile als Variant geht definitiv nicht, als objModel ja Typ Object geht in beiden faellen. Bekommst Du die Typlib denn nicht zugeordent, denn dann kannst du die richtigen Typklassen angeben, oder ist das in Delphi nicht moeglich? Klaus
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
UweD Mitglied
 Beiträge: 6 Registriert: 04.02.2004
|
erstellt am: 04. Feb. 2004 14:53 <-- editieren / zitieren --> Unities abgeben:         
Mit der Typlib habe ich es auch schon ausprobiert. Ich kann sie zuordnen und es funktioniert auch so ziemlich alles. Profile mit Definitionen und Bemaßungen kann ich problemlos erstellen. Nur die Übergabe des Arrays beim Erzeugen der Extrusion macht Probleme. Mit den richtigen Typklassen sieht es übrigens so aus: var SeDoc: SolidEdgePart_TLB.PartDocument; SeModel: SolidEdgePart_TLB.Model; SeProfile: array[1..2] of SolidEdgePart_TLB.Profile; begin SeDoc := PartDocument(SeApp.ActiveDocument); SeProfile[1] := SeDoc.ProfileSets.Add.Profiles.Add(SeDoc.RefPlanes.Item(3)); // Hier wird das Profil gezeichnet (das klappt auch noch!) SeLines := SeProfile[1].Lines2d; SeLines.AddBy2Points(0, 0, 0.08, 0); SeLines.AddBy2Points(0.08, 0, 0.08, 0.06); SeLines.AddBy2Points(0.08, 0.06, 0.064, 0.06); usw... // Hier soll die Extrusion erzeugt werden (das klappt nicht mehr) SeModel := SeDoc.Models.AddFiniteExtrudedProtrusion(1, SeProfile, igRight, 0.05, 0, 0, 0, 0); Jetzt meldet schon der Compiler einen Fehler (der Typ von SeProfile würde nicht stimmen nicht) ??? Uwe
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 04. Feb. 2004 16:25 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
Hi, hmm, also wenn ich die Schluesselworte weglasse bekomme ich auch in VB 'Type mismatch array or user defined ...)' versuchs mal so: SeModel= SeDoc.Models.AddFiniteExtrudedProtrusion(NumberOfProfiles:=1,ProfileArray:=SeProfile, ProfilePlaneSide:=igRight,ExtrusionDistance:=0.05) die Zuweisung an ein Keyword in Delphi ist mir nicht gelaeufig; die Angabe der optionalen Operanden kannst Du weglassen); die LAenge muss ein Double sein. vergiss nicht auf den Status abzufragen (vor setModel): lngStatus = objProfile(1).End(ValidationCriteria:=igProfileClosed) (Staus als Long def.) Ansonsten: weiss ich auch nicht weiter .... Klaus
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 04. Feb. 2004 16:42 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
Hi, ist ja manchmal 'shooting in the dark' also: SeProfile: array[1..2] of Object; <-- als Objekt definieren dann sollte auch dies klappen: SeModel := SeDoc.Models.AddFiniteExtrudedProtrusion(1, SeProfile, igRight, 0.05, 0, 0, 0, 0); Zumindest gings so in VB. Ohne Keyword moechte er dort ein Typ Object sehen. So etwas aehnliches gibt es auch bei ...TextBox.AttributeSets.Add String: Obwohl als String definiert musste ich dort explizit CStr(abc) angeben ... Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
UweD Mitglied
 Beiträge: 6 Registriert: 04.02.2004
|
erstellt am: 05. Feb. 2004 07:53 <-- editieren / zitieren --> Unities abgeben:         
Moin, danke für die Tipps! Ich habe sie alle ausprobiert, leider ohne Erfolg. In der Typlib verlangt Delphi den Typ OleVariant, was auch bei allen anderen Parameterübergaben prima funktioniert. Nur nicht bei der Übergabe eines Arrays. So sieht übrigens die Definition in der Typlib aus: function AddFiniteExtrudedProtrusion(NumberOfProfiles: Integer; var ProfileArray: {??PSafeArray}OleVariant; ProfilePlaneSide: FeaturePropertyConstants; ExtrusionDistance: Double; KeyPointOrTangentFace: OleVariant; KeyPointFlags: OleVariant; FromSurfOrRefPlane: OleVariant; ToSurfOrRefPlane: OleVariant): Model; dispid 233; Der Kommentar "{??PSaveArray}" stammt übrigens nicht von mir, er wurde bei der Übernahme automatisch erzeugt - keine Ahnung warum. Also weiterforschen... Uwe Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 05. Feb. 2004 08:47 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
Hi, ...Hmm, in der Tat komisch aber mir faellt auf das es nur beim Array heisst: {??PSafeArray}OleVariant; also in extra Klammern Waer es moeglich das hier ein Variant gemeint ist, welcher einen Pointer zum Array enthaelt, So: In VB: Dim ABC as Variant dim profile(1 to 2) as .... ABC = Profile() Moeglich ist natuerlich auch das bei der Ubernahme ein Fehler im Delphi ist -- dass sie falsch ist Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 05. Feb. 2004 12:39 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
Hi, mit dem Bug lag ich wohl garnicht soweit daneben. Vieelicht hilft Dir dies (Fuer ACAD) weiter: Using Delphi 3 to write AutoCAD R14 Automation Clients Here's an example which draws a circle using late binding When using Late binding with the initial release of R14, you must use the VarArrayRef() function to pass a variant array when AutoCAD requires an array of 3 doubles (a 3D coordinate). In R14.01, you do not need to use VarArrayRef(), and you can just pass the variant array instead. var Acad, Circle, vPoint, Mspace : OleVariant; begin // Create the point array and assign values to it vPoint := VarArrayCreate([0,2], VT_R8); vPoint[0] := 2.0; vPoint[1] := 4.0; vPoint[2] := 0.0; // Get the AutoCAD application object Acad := GetActiveOleObject('AutoCAD.Application.14'); // Get the ActiveDocument's model space object Mspace := Acad.ActiveDocument.Modelspace; // call the AddCircle() method to create the // circle with a radius of 10 units: Circle := Mspace.AddCircle(VarArrayRef(vPoint), 10.0); // R14.00 only Circle := Mspace.AddCircle(Vpoint, 10.0); // R14.01 only // Update the circle Circle.Update; end; Using early binding is a bit more complicated. Delphi has a bug that incorrectly declares SafeArray's as OleVariants in the imported type library (and generates a warning for each, but even the warning is incorrect - these parameters must be declared as const PSafearray (a constant pointer to a TSafeArray). So, for the AddCircle() method used in the above example, this would be the correct declaration that must appear in AutoCAD_TLB.pas: function AddCircle(const center: PSafeArray; radius: Double): IDispatch; safecall; Assuming you correct the declaration to read like the above, to use Early binding you must pass the safearray pointer. You can use this helper function to convert a variant array to a PSafeArray: Function SafeArrayRef(V : OleVariant): PSafeArray; begin Result := PSafeArray(TVarData(V).VArray);| end; Here is the same example from above, only using early binding: var Acad, vPoint: OleVariant; Mspace : IAcadModelSpace; Circle : IAcadCircle; begin vPoint := VarArrayCreate([0,2], VT_R8); vPoint[0] := 2.0; vPoint[1] := 4.0; vPoint[2] := 0.0; Acad := GetActiveOleObject('AutoCAD.Application.14'); Mspace := IDispatch(Acad.ActiveDocument.ModelSpace) as IAcadModelspace; Circle := IDispatch(Mspace.AddCircle(SafeArrayRef(vPoint), 10.0)) as IAcadCircle; Circle.Update; end; Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 05. Feb. 2004 13:04 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
Hi, falls alles nichts hilft, schau' doch mal bei google vorbei: Suchstring: delphi+PSafeArray da hast Du dann reichlich Auswahl <g> und troestlich: Du bist nicht der Einzige der sagen kann: ich hab' ja nichts gegen SafeArrays, nein sie haben was gegen mich <bg> Hier nochmals eine definition Safearrays are most easily handled in Delphi with variants. You can create a variant array so: VA := VarArrayCreate([1, 2, 3]); Then assign it to a PSafeArray variable so: PSA := PSafeArray(TVarData(VA).VArray); However because variants are reference counted you may need to use SafeArrayCopy, so: { Stuff the variant into a psafearray } SafeArrayCopy(PSafeArray(TVarData(VA).VArray), PSA); And the operation can be done in reverse: TVarData(VA).VType := varArray or varInteger; SafeArrayCopy(PSA, PSafeArray(TVarData(VA).VArray)); Klaus
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
UweD Mitglied
 Beiträge: 6 Registriert: 04.02.2004
|
erstellt am: 05. Feb. 2004 13:13 <-- editieren / zitieren --> Unities abgeben:         
Hi Klaus, sieht ja sehr interessant aus! Diesen Beitrag über ACAD habe ich vorhin auch gefunden und experimentiere gerade damit (bisher noch nicht sehr erfolgreich). Die anderen Sachen werde ich auch gleich mal testen. Das muss doch hinzukriegen sein... Uwe Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
modeng Ehrenmitglied V.I.P. h.c.
     
 Beiträge: 7061 Registriert: 10.12.2003
|
erstellt am: 06. Feb. 2004 15:22 <-- editieren / zitieren --> Unities abgeben:          Nur für UweD
|
UweD Mitglied
 Beiträge: 6 Registriert: 04.02.2004
|
erstellt am: 05. Mrz. 2004 08:03 <-- editieren / zitieren --> Unities abgeben:         
Hi Klaus, habe inzwischen Unterstützung von mehreren SE-Usern bekommen die sich mit diesem Problem herumschlagen. Leider hat noch keiner die Lösung. Vielen Dank erstmal für die Hilfe! Wenn ich weitergekommen bin, melde ich mich nochmal. Uwe Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |