| |
 | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
 | PNY: der unverzichtbare Partner für umfassende KI-Lösungen von Workstations bis zu Edge Computing und KI-Cluster-Bereitstellung, eine Pressemitteilung
|
Autor
|
Thema: Probleme ein dem Verstehen eines Codeabschnitts (1812 mal gelesen)
|
Gloem Mitglied Geoinformatiker
 
 Beiträge: 181 Registriert: 07.12.2007 Diverses PCs mit Windows 10/11 auf Basis von Intel-Prozessoren (i5-i9) Quadro oder Gaming-Grafikkarten AutoCAD normal, Map, Civil in den Varianten 2020-2025
|
erstellt am: 07. Dez. 2007 08:27 <-- editieren / zitieren --> Unities abgeben:         
Hallo, ich bin neu in der Programmierung von Autocad und soll ein bereits bestehendes Projekt erweitern. Leider ist in dem Code nicht kommentiert und eine ausführliche Beschreibung was das Programm machen soll hab ich auch nicht. Also muss ich aus dem Code den Sinn der Programms verstehen. An folgender Stelle versteh ich leider den Sinn nicht Code: Private Function Set_Block() As String Dim mPoint(0 To 2) As Double Dim Code As String Dim Pktnr As String Dim VarAttributes As Variant Dim m_AcadBlockReference As AcadBlockReference mPoint(0) = rs_Vermessung.Fields("Y") mPoint(1) = rs_Vermessung.Fields("X") mPoint(2) = rs_Vermessung.Fields("Z") Pktnr = rs_Vermessung.Fields("PktNr") Code = rs_Vermessung.Fields("Code") Set m_AcadBlockReference = ThisDrawing.ModelSpace.InsertBlock(mPoint, Code, 1, 1, 1, 0) If m_AcadBlockReference.HasAttributes Then VarAttributes = m_AcadBlockReference.GetAttributes VarAttributes(0).TextString = Pktnr End If Set_Block = m_AcadBlockReference.Handle End Function
rs_Vermessung ist ein ADODB.RecordsetMein Problem liegt nun in der if-Abfrage. Was passiert da genau und wird das VarAttributes wirklich benötigt? Die Variable ist ja lokal und kann außerhalb nicht weiterverwendet werden Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Carsten1210 Mitglied staatl. geprüfter Holztechniker
   
 Beiträge: 1360 Registriert: 24.07.2002
|
erstellt am: 07. Dez. 2007 08:44 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hi und Willkommen Gloem, Dein Code fügt Blöcke mit Punktnummern ein. In der If-Abfrage wird ermittelt, ob der Block Attribute enthält. Wenn Ja, dann wird das Attribut (0) mit dem Text "Pktnr" gefüllt. Gruß, Carsten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Gloem Mitglied Geoinformatiker
 
 Beiträge: 181 Registriert: 07.12.2007 Diverses PCs mit Windows 10/11 auf Basis von Intel-Prozessoren (i5-i9) Quadro oder Gaming-Grafikkarten AutoCAD normal, Map, Civil in den Varianten 2020-2025
|
erstellt am: 07. Dez. 2007 08:50 <-- editieren / zitieren --> Unities abgeben:         
Soweit hatte ich das schon verstanden. Aber wenn ich einen neuen Block hinzufüge, wie soll der denn schon Attribute haben? Warum speicher ich danach die Attribute in einer Variablen und weis dieser Variablen eine Punktnummer zu wenn ich die Variable gar nicht weiter verwende? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Stelli1 Moderator Verm.-Ing.
    
 Beiträge: 1526 Registriert: 17.08.2005 Map 2000-2014, Rasterdesign, MapGuide, Autodesk Topobase, VS6, VS.net 2013
|
erstellt am: 07. Dez. 2007 12:42 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hallo, ist doch eigentlich nicht so schwer. Der Block wird als Blockreferenz eingefügt. Damit hast du doch den Verweis auf den Bauplan (Blockdefinition) Mit HasAttributes wird geprüft ob der Bauplan auch über Attributdefinitionen verfügt. Wenn ja werden die 1 bis n Attribute in ein Array gespeichert. Dem ersten Attribut wird (komischerweise unabhängig vom Namen) der Wert PNR zugewiesen. Hierbei könnte das natürlich auch geprüft werden. Und als globale Variable brauchst du das doch nicht, da der Wert nur in das Attribut abgefüllt wird. Schau auch mal hier. Wilfried Stelberg
------------------ Warum lisp'eln wenn's auch anders geht. www.ib-stelberg.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin

 Beiträge: 2812 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2022 Plateia, Canalis Visual Basic
|
erstellt am: 07. Dez. 2007 15:44 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hallo, ist doch ganz klar. Aus einer Datenbank soll ein Punktauftrag erzeugt werden und wenn der Block (die Definition ist ja schon in der Zeichnung drin) ein Attributfeld bestitzt, soll in dem ersten Attribut die Punktnummer aus der Datenbank stehen. Da sieht man doch gleich was wo gemessen wurde. Eigendlich 'ne schöne Funktion. @Wilfried: Natürlich wäre es schöner wenn der Attributname auch noch überprüft würde, aber manchmal programmiert man manche Sachen weil man sie schnell braucht und dann hat man auch keine Zeit für eine vernünftige Dokumentation. Und das mit dem später ergänzen kenne ich aus eigener Erfahrung zu gut. Grüße an alle, Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Gloem Mitglied Geoinformatiker
 
 Beiträge: 181 Registriert: 07.12.2007 Diverses PCs mit Windows 10/11 auf Basis von Intel-Prozessoren (i5-i9) Quadro oder Gaming-Grafikkarten AutoCAD normal, Map, Civil in den Varianten 2020-2025
|
erstellt am: 07. Dez. 2007 17:30 <-- editieren / zitieren --> Unities abgeben:         
Mhmm, ich hatte zwar schon geantwortet aber irgendwie ist das weg. Also nochmal. Entweder drück ich mich falsch aus oder mein Verständnis von VB ist falsch:
Mit der Zeile
Code: VarAttributes = m_AcadBlockReference.GetAttributes
speichere ich mir doch eine Kopie des Feldes mit den Attributen in einer lokalen Variable. Wenn es ein Zeiger/Referenz wäre müsste da doch set hin oder etwa nicht?Wenn ich in der Zeile danach
Code: VarAttributes(0).TextString = Pktnr
dieser lokalen Variablen einen neuen Wert zuordne ist das doch total unnütz oder nicht?Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Stelli1 Moderator Verm.-Ing.
    
 Beiträge: 1526 Registriert: 17.08.2005 Map 2000-2014, Rasterdesign, MapGuide, Autodesk Topobase, VS6, VS.net 2013
|
erstellt am: 07. Dez. 2007 17:47 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hallo , 'VarAttrubutes ist vom Typ Variant daher nicht mit set zugewiesen VarAttributes = m_AcadBlockReference.GetAttributes Danach steht in VarAttributes ein Array von Attributreferenzen. Schau es die mal im Überwachungsfenster an. Du kannst es ja wie im Beispiel per Set an ein Attribu übergeben. Wilfried Stelberg ------------------ Warum lisp'eln wenn's auch anders geht. www.ib-stelberg.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Gloem Mitglied Geoinformatiker
 
 Beiträge: 181 Registriert: 07.12.2007 Diverses PCs mit Windows 10/11 auf Basis von Intel-Prozessoren (i5-i9) Quadro oder Gaming-Grafikkarten AutoCAD normal, Map, Civil in den Varianten 2020-2025
|
erstellt am: 07. Dez. 2007 18:04 <-- editieren / zitieren --> Unities abgeben:         
Da ist das nächste Problem, das Projekt läuft nicht wirklich. Also ist VarAttributes das identische Objekt zu m_AcadBlockReference.GetAttributes. Sprich wenn ich was in VarAttributes ändere wird es auch in meinem Block geändert. Also wäre der if-Kram identisch zu m_AcadBlockReference.GetAttributes(0).TextString = Pktnr Kann es Blöcke ohne Attribute geben?
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Stelli1 Moderator Verm.-Ing.
    
 Beiträge: 1526 Registriert: 17.08.2005 Map 2000-2014, Rasterdesign, MapGuide, Autodesk Topobase, VS6, VS.net 2013
|
erstellt am: 07. Dez. 2007 18:57 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hallo, Zitat: Original erstellt von Gloem: Also wäre der if-Kram identisch zu m_AcadBlockReference.GetAttributes(0).TextString = Pktnr
Nein. Zitat: Original erstellt von Gloem: Kann es Blöcke ohne Attribute geben?
Ja, natürlich kann es Blöcke ohne Attribute geben. Deshalb wird ja auch mit "If m_AcadBlockReference.HasAttributes Then" geprüft ob der Block Attribute hat. Ansonsten gibt es natürlich einen Fehler wenn man auf nicht vorhandene Attribute zugreift. Vielleicht solltest du das AutoCAD mal mit F1 befragen und schauen was zu den Methoden geschrieben steht. Grundsätzlich kann man bei AutoCAD VBA sagen, dass viele Rückgabewerte in Variants gespeichert werden. Diese müssen dann gegebenfalls in "normale" Datentypen überführt werden. Wilfried Stelberg ------------------ Warum lisp'eln wenn's auch anders geht. www.ib-stelberg.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Gloem Mitglied Geoinformatiker
 
 Beiträge: 181 Registriert: 07.12.2007 Diverses PCs mit Windows 10/11 auf Basis von Intel-Prozessoren (i5-i9) Quadro oder Gaming-Grafikkarten AutoCAD normal, Map, Civil in den Varianten 2020-2025
|
erstellt am: 07. Dez. 2007 19:16 <-- editieren / zitieren --> Unities abgeben:         
Entschuldigt wenn ich lästig werde aber wenn Code: m_AcadBlockReference.GetAttributes(0).TextString = Pktnr
nicht identisch mit Code: VarAttributes = m_AcadBlockReference.GetAttributes VarAttributes(0).TextString = Pktnr
ist, wobei VarAttributes eine lokale Variable ist die nicht weiter verwendet wird, warum sollte das ganze dann in der Variablen gespeichert werden? Wird doch eh verworfen sobald die Methode zuende ist. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
   
 Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 07. Dez. 2007 19:40 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hallo, Code: m_AcadBlockReference.GetAttributes(0).TextString = Pktnr
GetAttributes ist eine Methode welches ein Array liefert. Objektkatalog F2: Function GetAttributes() Element von AutoCAD.AcadBlockReference Gets Attributes in the block Mach doch einfach mal ein: Code:
for i=lbound(varAtt) to ubound(varAtt) debug.print varAtt(i).textstring,varAtt(i).Name next
Oder setz mal bitte ein F1 auf GetAttributes ab, Autocad hat eine sehr schöne VBA-Hilfe. lg Nancy Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin

 Beiträge: 2812 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2022 Plateia, Canalis Visual Basic
|
erstellt am: 07. Dez. 2007 21:11 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hallo Gloem, betrachte es doch mal so: Du bekommst von der Methode GetAttributes das Feld zurückgeliefert in dem alle Namen (TagString) und Inhalte (TextString) aller zu dem Block gehörigen Attribute stehen. In Deinem Programm weist Du jetzt dem ersten Attribut (0) einen neuen Inhalt zu, nämlich die Punktnummer aus der Datenbank. Dies wird direkt in die entsprechende AutoCAD Tabelle eingetragen. In AutoCAD gibt es öfters Daten die nicht direkt anzusprechen sind, beispielsweise werden von vielen Programmen XData Elemente zu Linien, Blöcken, Texten hinzugefügt um Zusammengehörigkeiten zu hinterlegen. Wenn in einer PolyLinie ein Bogen definiert ist kann der Radius nicht direkt ausgelesen werden. Hierzu werden die entsprechenden Methoden benötigt (GetXData bzw. GetBulge). Aber Du schreibst weiter oben dass das Programm nicht so richtig läuft. Könnte ich mir vorstellen wenn Du eine leere Zeichnung hast in der der Block noch nicht definiert ist der im AccessDB-Feld "Code" steht. Ansonsten würde ich in die IF - Schleife noch ein m_AcadBlockReference.update setzen, damit die Änderungen auch gleich zu sehen sind. Oder wo liegt das Problem? Schönes WE, Klaus
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
   
 Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 07. Dez. 2007 22:52 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Hallo nochmal, @Klaus: genau, sorry ich meinte auch varAtt(i).Tagstring statt .Name;-) Aber Gloem vielleicht kommst du weiter, wenn du Dir erstmal eine neue, leere Zeichnung nimmst, darin dann über Menü > Format > Blöcke > Attribute ein Attribut erstellst. Maske: Bezeichnung/Eingabeaufforderung/Wert eingeben und okay. Dann erstellst du aus dem einen Attribut einen Block und dann schaust du dir dieses einzige Element im Modell mal an mit zB:
Code:
dim o, att set o=thisdrawing.modelspace.item(0) att=o.getattributes stop
Und dann guckst du mal ins Lokalfenster. Der Bezeichner des Attributes ist der 'Tagstring', der Wert ist der zugehörige 'Textstring'.Stell' Dir ein Attribut eines Blockes vor wie ein zweidim. Feld Attribut(0,1), bestehend aus Attribut(0,0)==TagString und zugeordnetem Attribut(0,1)==TextString. Da Blöcke aber auch mehrere Attribute haben können, kann es sein dein Feld hat auch mal 10 Zeilen und zwei Spalten, also Attribute(9,1). Je Zeile == eine Einheit mit 2 Angaben, Tag und Text, Bezeichner und Wert. GetAttributes liefert dir also je Block (wenn dieser denn Attribute besitzt) eine beliebiges Sammelsurium an Attributen zurück. Die Indizierung erfolgt in der Erstellreihenfolge der Attribute, deswegen, es wurde schon angesprochen, ist es nicht immer 100% sicher, sich nur am Index zu orientieren, sondern man sollte auch den Tagstring prüfen um zu gewährleisten, dass auch das mit dem passenden Bezeichner den passenden Wert erhält und nicht nur einfach das Item(0) oder Item(5) in der Reihe, denn du darfst nicht davon ausgehen, dass immer alle Attribute die selbe Reihenfolge haben;-) Ich lese etwas heraus, dass du nicht weisst, was da passiert, deswegen wäre mein Vorschlag, beginne selbst erstmal testweise manuell einen Block mit Attributen zu erstellen und zu bearbeiten/verändern. Wenn die Funktion in der reinen Benutzeroberfläche vom reinen ACAD klar ist, dann versteht man die Automation leichter. Blockänderungen (Einlesen/Auslesen/Wertändern) sind nur eine Automation des Manuellen, oder anders, ich kann nur etwas automatisieren wollen, was ich selbst mal per Pedes gemacht habe. So, ich wollte jetzt eigentlich nicht so oberlehrerhaft klingen, mir kam nur so der Verdacht auf, da sitzt ein Programmierer der sein Handwerk versteht, aber nicht das eigentliche Programm;-) Deswegen der Ansatz, es einfach erstmal 'usen' und dann 'proggn'. Sollte ich mit der Vermutung schief liegen, winsel ich vorsorglich schonmal um Gnade, dann vergiss den letzten Teil. Andernfalls, wiegesagt, bin ich der Meinung, man kann nur etwas programmieren, was man auch versteht, um ehrlich zu sein, habe ich anfangs mal vor der fast selben Thematik gestanden;-) Viele Grüße, Nancy Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Gloem Mitglied Geoinformatiker
 
 Beiträge: 181 Registriert: 07.12.2007 Diverses PCs mit Windows 10/11 auf Basis von Intel-Prozessoren (i5-i9) Quadro oder Gaming-Grafikkarten AutoCAD normal, Map, Civil in den Varianten 2020-2025
|
erstellt am: 08. Dez. 2007 11:37 <-- editieren / zitieren --> Unities abgeben:         
Ersteinmal vielen Dank für eure Erklärungen. Aber so richtig weiter bin ich nocht nicht. Vielleicht leigt es auch daran, dass ich es momentan nicht ausprobieren kann, da ich Zuhause kein Autocad besitze. Vielleicht habe ich auch einfach zu viel Quellcode beigefügt aber ich dachte dann kann man mir eher helfen. Mein Problem ist eigentlich nur die lokale Variable und ob die unnütz ist. Wenn ich etwas einer lokalen Variablen zuweise und diese dann ändere ist das meiner Meinung nach unnütz wenn die zu deren Gültigkeit nicht wieder ausgelesen wird. Es sei des es handelt sich um einen Zeiger auf den Speicherbereich(C++ *, VB ByRef)
Ich versuch es mal mit Pseudocode(ohne Syntakprüfung ist schwer und soll auch nur als Beispieldienen)
Code: private sub a () dim array as variant array = irgendwasAusSystem.FeldMitWerten array(0) = "Hallo" end sub
Dann ist array doch unnütz oder etwa nicht, da es ja kein Zeiger auf das Feld ist und array nicht wieder ausgelesen wird Code: private sub a (b() as String) dim x as variant x = b x(0) = "Hallo" end sub
Hierbei wäre doch in b(0) auch nicht Hallo drin oder etwa doch
Vielleicht merkt man an der Frage, das ich eher aus der Java, C++-Ecke komme und nicht wirklich stark in VB bin.
[Diese Nachricht wurde von Gloem am 08. Dez. 2007 editiert.] [Diese Nachricht wurde von Gloem am 08. Dez. 2007 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
   
 Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 08. Dez. 2007 15:58 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Mal ein Beispiel für einen Block, der die Attribute X,Y und Z besitzt und denen die Attributwerte der XYZ Koordinaten zugeordnet werden sollen. Code:
'Lesen aller Attribute eines Blockes im Array blockattsblockAtts = myBlockRef.GetAttributes ' Durchlauf des Array und Suche nach Attributen mit Tagstring X,Y und Z For attIndex = LBound(blockAtts) To UBound(blockAtts) Select Case blockAtts(attIndex).TagString 'wenn X: dann überschreibe Textstring mit x-Koordinate, dito für Y,Z Case Is = "X": blockAtts(attIndex).TextString = "x:" & CStr(insPoint(0)) Case Is = "Y": blockAtts(attIndex).TextString = "y:" & CStr(insPoint(1)) Case Is = "Z": blockAtts(attIndex).TextString = "z:" & CStr(insPoint(2)) End Select Next
Das Array blockatts ist sicher temporärer Natur, aber du benötigst es um die Attributwerte eines Blockes einzulesen und verändern zu können (read/write). Damit hast du dann den Block bzw. dessen Attribute verändert. Das Array Blockatts verfällt, aber der Block selber mit den Attributen behält die Änderungen, wird sozusagen dauerhaft mit der Zeichnung gespeichert.[edit] Nachtrag: Und Nein ein direkter Zugriff auf Getattributes(Index) ist nicht möglich. Zum read/write brauchts ein Variantarray als Katalysator bzw. Mittel zum Zweck ;-) lg Nancy Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
   
 Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 09. Dez. 2007 01:12 <-- editieren / zitieren --> Unities abgeben:          Nur für Gloem
Zitat: Original erstellt von Gloem: Wenn ich etwas einer lokalen Variablen zuweise und diese dann ändere ist das meiner Meinung nach unnütz wenn die zu deren Gültigkeit nicht wieder ausgelesen wird. Es sei des es handelt sich um einen Zeiger auf den Speicherbereich(C++ *, VB ByRef)
Hallo nocheinmal  Du fragst eigentlich sehr hintergründig, meine Antwort war eher oberflächlich. Also Ja, es handelt sich um einen Zeiger (Pointer) auf ein Object, der mit der Methode 'Getattributes' erstellt wird und über diese Referenz kann das Objekt auch bearbeitet werden. lg Nancy Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Gloem Mitglied Geoinformatiker
 
 Beiträge: 181 Registriert: 07.12.2007 Diverses PCs mit Windows 10/11 auf Basis von Intel-Prozessoren (i5-i9) Quadro oder Gaming-Grafikkarten AutoCAD normal, Map, Civil in den Varianten 2020-2025
|
erstellt am: 10. Dez. 2007 07:13 <-- editieren / zitieren --> Unities abgeben:         
Vielen Dank für eure Hilfe. Die letzten beiden Antworten haben mir geholfen das ganze zu verstehen(Auch wenn ich es nicht plausibel finde warum das auf einmal ein Zeiger sein soll, aber egal) Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |