| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | | | PNY präsentiert die neue NVIDIA RTX A400 und die A1000 Grafikkarte, eine Pressemitteilung
|
Autor
|
Thema: setXData (2704 mal gelesen)
|
startrek Moderator Architekt
Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 22. Jul. 2005 19:14 <-- editieren / zitieren --> Unities abgeben:
Hallo Leute, hab' grade nen totalen Klemmer, er bringt mir bei untigem immer nen Error, aber irgendwie sitz ich total auf der Leitung gerade. Hoffe der Code ist selbstredend - also was ich machen möchte ..., wenn nicht, ich möchte einfach 5 Texte einfügen und diesen 5 Texten paar XDaten mit ins Handgepäck geben. ;-)
Code:
Public source$(4, 3) Public Sub demo() Const a% = 1000 Dim dtext As AcadText, insP#(2) Dim xType%(3), xDat(3) As Variant Dim i%, j% source(0, 0) = "eins": source(0, 1) = "one": source(0, 2) = "un": source(0, 3) = "un" source(1, 0) = "zwei": source(1, 1) = "two": source(1, 2) = "deux": source(1, 3) = "dos" source(2, 0) = "drei": source(2, 1) = "three": source(2, 2) = "trois": source(2, 3) = "tres" source(3, 0) = "vier": source(3, 1) = "four": source(3, 2) = "quattre": source(3, 3) = "cuartro" source(4, 0) = "fünf": source(4, 1) = "five": source(4, 2) = "cinq": source(4, 3) = "cinco" For i = LBound(source) To UBound(source) insP(1) = CDbl(i) Set dtext = ThisDrawing.ModelSpace.AddText(source(i, 0), insP, 0.5) For j = 0 To UBound(xType) xType(j) = a: xDat(j) = source(i, j) Next dtext.SetXData xType, xDat Next End Sub
Gruss 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: 22. Jul. 2005 20:37 <-- editieren / zitieren --> Unities abgeben:
Manman - bin auch schön beknackt ..., ich habs - ala it works better if you plug it in - so geht's: Code:
Public source$(4, 3) Public Sub demo() Const a% = 1000 Dim dtext As AcadText, insP#(2) Dim xType%(3), xDat(3) As Variant Dim i%, j% source(0, 0) = "eins": source(0, 1) = "one": source(0, 2) = "un": source(0, 3) = "un" source(1, 0) = "zwei": source(1, 1) = "two": source(1, 2) = "deux": source(1, 3) = "dos" source(2, 0) = "drei": source(2, 1) = "three": source(2, 2) = "trois": source(2, 3) = "tres" source(3, 0) = "vier": source(3, 1) = "four": source(3, 2) = "quattre": source(3, 3) = "cuartro" source(4, 0) = "fünf": source(4, 1) = "five": source(4, 2) = "cinq": source(4, 3) = "cinco" For i = LBound(source) To UBound(source) insP(1) = CDbl(i) Set dtext = ThisDrawing.ModelSpace.AddText(source(i, 0), insP, 0.5) For j = 0 To UBound(xType) if j=0 then xtype(j)=1001 else xtype(j)=a xDat(j) = source(i, j) Next dtext.SetXData xType, xDat Next End Sub
Vielleicht mal noch eine klitzekleine Frage zu den X-Dingern: 'Objekt hat 16367 Byte XDaten-Speicher verfügbar' also ich kann/Object ~16kb Speicher verprassen oder wie muss ich das interpretieren? Und was interpretiert der Interpeter dann wie, bytemäßig? mit 100 Strings ging's schonmal so:
Code:
Sub X_data_test() Dim i%, dtext As AcadText, insP#(2) Dim xType%(99), xDat(99) As Variant xType(0) = 1001: xDat(0) = "string 0" For i = 1 To UBound(xDat) xType(i) = 1000 xDat(i) = "string " & i Next Set dtext = ThisDrawing.ModelSpace.AddText("x_Text", insP, 0.5) dtext.SetXData xType, xDatEnd Sub
Hat schonmal jemand die Limits der XDatas ausgereizt, also stringbezogen, was wird da wie bewertet? Gruss Nancy Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Die Phönizier haben das Geld erfunden - aber warum so wenig? (Johann Nepomuk Nestroy)
|
erstellt am: 27. Jul. 2005 12:09 <-- editieren / zitieren --> Unities abgeben: Nur für startrek
Hi Nancy, in Lisp gibt es die Funktionen (XDSIZE ...) und (XDROOM ...), mit denen man feststellen kann, wieviel von den 16 kb verbraucht wurde bzw. noch frei ist. Die Hilfe sagt aber im Kapitel AxtiveX and VBA Developer's Guide -> VisualLisp and ActiveX Comparison, dass diese Methoden "not provided" sind, d.h. in VBA kann man das nicht ermitteln. Bleibt also nur, aus VBA heraus ein Lisp-Statement zu evaluieren (über die VLAX-Klasse, habe ich mal hier gepostet). Aber noch was anderes: Der GC 1001 ist für einen Applikationsnamen, du setzt da Werte rein. Der Applikationsname muss welt-eindeutig sein, damit sich Applikationen nicht ins Gehege kommen. Es wird empfohlen, mindestens die eigene Telefonnummer mit Landesvorwahl darin unterzubringen (weil die eben weltweit eindeutig ist). Eine korrekte Datenstruktur wäre in deinem Fall etwa das hier: Code:
1001 . "MyNumbersInAllLanguagesApplication_043_01234_0123456789" 1002 . "{" 1000 . "Deutsch" 1002 . "{" 1002 . "{" 1070 . 1 1000 . "Eins" 1002 . "}" 1002 . "{" 1070 . 2 1000 . "Zwei" 1002 . "}" ... 1002 . "}" 1000 . "Nederlands" 1002 . "{" 1002 . "{" 1070 . 1 1000 . "Een" 1002 . "}" ... 1002 . "{" 1070 . 17 1000 . "zeventien" 1002 . "}" ... 1002 . "}" ... 1002 . "}"
Die Klammerei ist absolut wichtig, weil man sonst kaum vernünftige Datenstrukturen hinkriegt. Aber den ganzen Klammerkram kann man ziemlich leicht automatisieren, da muss man sich einmal ein paar Funktionen schreiben und kann die dann benutzen. Gruß, Axel Strube-Zettler ------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 27. Jul. 2005 22:19 <-- editieren / zitieren --> Unities abgeben:
Hi Axel, okay, ist [teilweise] angekommen, Danke:-) Experimente hatte ich auch schon gestartet um in etwa eine Richtung des Vertretbaren rauszubekommen, was die XXX'er an geht. Hab ich blöderweise in etwa so getestet, Anwendungsname [Integer = 2 Byte] + String[2 Byte pro Zeichen] 16.000 / 2 / 2 = 4000 Ints a' 2Byte + 4000 strings 'a 1 Zeichen, hatter auch geschluckt. Naja okay, musst nix dazu sagen ;;-)) - ziemlicher Unfug - ich weiss- , wollt nur mal ein Gefühl dafür bekommen eben. Das mit dem eineindeutig hab ich noch nicht so recht verstanden, mir schlich im Kopf rum, reinen Texten X-Daten mitzugeben, um auf 'Knopfdruck' die Sprache umschalten zu können. Ohne auf externe Daten[banken] zuzugreifen, sondern direkt in der Zeichnung hinterlegt eben, sozusagen als Gimmick in der Zeichnung selber. Aber auch alles nebensächlich, mir gehts drum - ist das eher eine gute oder schlechte Idee - auf die Tour mit der Srachumschaltung, oder bekomme ich eines Tages wegen Missbrauchs der X-Datas lebenslänglich, weil einfach 'auf Sand gebaut' damit? [grober Code s.u. - sieht schlimmer aus, als er ist;-)] Wenn ich dich richtig verstehe, müsste ich dem Array nochmal eine Dimension vorschalten, die die Sprache eineindeutig identifiziert, ja? Also sowas:
Code:
source(0,0)=dt:source(1,0)=en:source(2,0)=fr:source(3,0)=sp
Ändert doch aber nix an der sache, oder? Hach irgendwie isses mir zu heftig heute mit der eineindeutigen Zweideutigkeit ..., auf jedenfall Danke erstmal:-) lg Nancy --
Code:
Option Explicit Public source$(4, 3) Public Sub fill_it() Const a% = 1000 Dim dtext As AcadText, insP#(2) Dim xType%(3), xDat(3) As Variant Dim i%, j% source(0, 0) = "eins": source(0, 1) = "one": source(0, 2) = "un": source(0, 3) = "un" source(1, 0) = "zwei": source(1, 1) = "two": source(1, 2) = "deux": source(1, 3) = "dos" source(2, 0) = "drei": source(2, 1) = "three": source(2, 2) = "trois": source(2, 3) = "tres" source(3, 0) = "vier": source(3, 1) = "four": source(3, 2) = "quattre": source(3, 3) = "cuartro" source(4, 0) = "fünf": source(4, 1) = "five": source(4, 2) = "cinq": source(4, 3) = "cinco"'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' **** nur für's erste Mal in test_blank_dwg;-) ************* '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ''' For i = LBound(source) To UBound(source) ''' insP(1) = CDbl(i) ''' Set dtext = ThisDrawing.ModelSpace.AddText(source(i, 0), insP, 0.5) ''' For j = 0 To UBound(xType) ''' If j = 0 Then xType(j) = 1001 Else xType(j) = a ''' xDat(j) = source(i, j) ''' Next ''' dtext.SetXData xType, xDat ''' Next End Sub Sub changeLan() Dim sset As AcadSelectionSet, oTxt Dim flag As Boolean, lan, xType, xDat Dim s%, i%, r%, c% Dim fType%(0), fData(0), newType%(3) fType(0) = 0: fData(0) = "TEXT" newType(0) = 1001: newType(1) = 1000: newType(2) = 1000: newType(3) = 1000 With ThisDrawing On Error Resume Next lan = .Utility.GetString(0, "dt | en | fr | sp :") If IsEmpty(lan) Then Exit Sub If IsError(.SelectionSets("myset")) Then Set sset = .SelectionSets.Add("myset") _ Else Set sset = .SelectionSets("myset") On Error GoTo 0 End With sset.Clear sset.Select acSelectionSetAll, , , fType, fData Select Case lan Case Is = "dt": s = 0 Case Is = "en": s = 1 Case Is = "fr": s = 2 Case Is = "sp": s = 3 Case Else: Exit Sub End Select Call fill_it For Each oTxt In sset oTxt.GetXData "", xType, xDat If Not IsEmpty(xType) Then If UBound(Filter(xDat, oTxt.TextString)) <> -1 Then For i = LBound(xDat) To UBound(xDat) If oTxt.TextString = xDat(i) Then oTxt.TextString = xDat(s) Exit For End If Next End If Else For r = LBound(source, 1) To UBound(source, 1) For c = LBound(source, 2) To UBound(source, 2) If oTxt.TextString = source(r, c) Then xDat = Array(source(r, 0), source(r, 1), source(r, 2), source(r, 3)) oTxt.SetXData newType, xDat oTxt.TextString = source(r, s) Exit For End If Next Next End If Next End Sub
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Die Phönizier haben das Geld erfunden - aber warum so wenig? (Johann Nepomuk Nestroy)
|
erstellt am: 28. Jul. 2005 12:52 <-- editieren / zitieren --> Unities abgeben: Nur für startrek
Hi Nancy! Ich will noch mal versuchen, dir (und jedem, den's interessiert), das mit dem Appname zu erklären: Jede Applikation, auch deine, sollte *einen* eindeutigen Namen haben. Das hat folgende Vorteile: 1. Man kann Entities danach filtern (z.B. mit Befehlen oder ssget in Lisp) 2. Man bringt nicht die AutoCAD-EEDs mit den eigenen durcheinander 3. Man bringt nicht die eigenen Daten mit denen einer anderen Applikation durcheinander Mit einer Zeile wie oTxt.GetXData "", xType, xDat tust du aber genau das: Du liest sämtliche XDaten aus, einschliesslich AutoCAD-Daten, die es ja noch immer gibt, und auch die Daten anderer Applikationen. Aber die brauchst du doch überhaupt nicht! Du musst dann in dem evtl. vorhandenen Datenwust erst deine eigenen Daten rausklauben und vor allem darauf achten, dass du die anderen Daten nicht versehentlich modifizierst. Stell dir einfach vor, du willst dein Tool irgendwo einsetzen, aber auf dem Zielrechner läuft sowas wie PitCup als Applikation: Du wirst das sehr wahrscheinlich abschiessen, weil du ständig die PitCup-Daten mit deinen durcheinanderbringst. Der Applikationsname dagegen schafft eine Art Namespace: Durch die Verwendung desselben werden die Daten voneinander getrennt. Dein Tool "sieht" nur noch seine Daten, PitCup "sieht" nur noch die PitCup-Daten, und AutoCAD selbst sieht sowieso nur die Daten, die unter dem Namen "ACAD" abgelegt sind. Dann bleibt alles schön sicher und damit unfallfrei - selbst eine Funktion, die ein "Alle EEDs löschen" ausführt, löscht nur die eigenen Daten - es ist einfach so, als seinen die anderen Daten gar nicht vorhanden! Damit nun keine Verwechslungen vorkommen können, muss der Applikationsname eindeutig sein. Es bringt nix, nur den Namen "Dingenskirchen" als Appname zu verwenden, denn wenn irgendein anderer auf die selbe Idee kommt, schiessen sich die beiden Dingenskirchens gegenseitig die Nüsse weg. Also muss Eindeutigkeit her: Der Applikationsname sollte sich zusammensetzen aus: 1. Dem Namen des Programms, also "Dingenskirchen" 2. Der Versionsnummer 3. Dem Eigennamen des Programmierers (unabhängig davon, ob es sich um eine natürliche oder juristische Person handelt) 4. Der Telefonnummer (bei Firmen aber ohne Durchwahl) Das mit der Telefonnummer ist einfach ein Standard, auf den man sich geeinigt hat, denn zwei Telefonnummern können (mit Landeskennziffer) weltweit nicht gleich sein - damit sind Querschläger ausgeschlossen. Ach ja, und ein Appname sollte nicht kürzer als 64(???) Zeichen sein. Für kommerzielle Produkte kann ein Appname übrigens bei A registriert werden. Ein Auslesen von XDaten mit "" als Appname sollte wirklich auf einen einzigen Fall beschränkt bleiben: Nur irgendwelche Tools zum Abschiessen von Daten benötigen das - irgendwelche Super-Mega-Purger, die eine Zeichnung bewusst auf einen Stand zurückstutzen sollen und dabei Applikationsdaten entfernen sollen (z.B. weil der Empfänger der Zeichnung die Applikation nicht benutzt). So, und nun noch mal konkret zu deiner Aufgabenstellung: Ein Textobjekt mit mehrsprachigen Textinhalten ist gar nicht kompliziert:
Code:
1001 . "Texttranslation_0.91a_build_4711_by_Startrek_043_01234_0123456789" 1002 . "{" 1070 . 1 1002 . "{" 1000 . "Eingang" 1002 . "}" 1000 . 2 1002 . "{" 1000 . "Entrance" 1002 . "}" 1000 . 3 1002 . "{" 1000 . "Entrèe" 1002 . "}" 1000 . 4 1002 . "{" 1000 . "Entrata" 1002 . "}" 1000 . 5 1002 . "{" 1000 . "Entrada" 1002 . "}" 1000 . 6 1002 . "{" 1000 . "Entrada" 1002 . "}" 1002 . "}"
Die Applikation müsste nur eine Liste in der Art Code:
1 = Deutsch 2 = Englisch 3 = Französisch 4 = Italienisch 5 = Spanisch 6 = Portugiesisch
vorhalten. Natürlich könnte man bei einer so einfachen Applikation die Klammerung weglassen und mit einem Daten-Dump leben, auf den nur über die Reihenfolge der Daten zugegriffen wird. Dann schreibst du dir für *diese* Aufgabe ein paar Zugriffsfuntionen, die du aber bei der nächsten Aufgabenstellung wieder in die Tonne trittst - da brauchst du dann andere. Ohne Klammerung lassen sich nur rechteckige Datenmatrizen verarbeiten. Aber stell dir vor, du hast jetzt alle deine Text-Beschriftungen internal, also in 27 Sprachen. Nur ein kleines Probem: Bei einer einzigen Textbeschriftung fehlt die die italienische Übersetzung: Code:
1001 . "Texttranslation_0.91a_build_4711_by_Startrek_043_01234_0123456789" 1002 . "{" 1070 . 1 1002 . "{" 1000 . "Ausgang" 1002 . "}" 1000 . 2 1002 . "{" 1000 . "Exit" 1002 . "}" 1000 . 3 1002 . "{" 1000 . "Sortie" 1002 . "}" 1000 . 5 1002 . "{" 1000 . "Salida" 1002 . "}" 1000 . 6 1002 . "{" 1000 . "Saída" 1002 . "}" 1002 . "}"
Mit Tags und Klammerung funktioniert das immer noch, auch wenn eine Übersetzung fehlt - ohne geht das sofort in die Hose, weil die Matrix jetzt nicht mehr rechteckig ist. Letztendlich ist es das alte Spiel: Arrays vs. Hashes, das man in fast allen Programmiersprachen kennt. VBA kennt Arrays und Collections ("item" ist hier der "tag"), in Lisp ist das etwas anders: Da gibt es völlig unstrukturierte Listen, die aber prima als Hash verwendet werden können. Arrays gibt es zwar in Lisp, aber in AutoLisp nur über COM (safearray). Langer Rede, kurzer Sinn: Du musst dir überlegen, ob du die Daten als (rechteckiges) Array ablegst der als (beliebiges) Hash, auf das du über tags zugreifen kannst. Da sich jedes Array auch als Hash darstellen lässt, nicht aber umgekehrt, halte ich das Hash immer für die bessere Lösung, es sei denn, es soll ein Numbercruncher werden. Arrays sind schneller, weil für den Zugriff auf eine Zelle kein Suchen notwendig ist. HTH, Axel Strube-Zettler <edit> Ein gutes Argument für eine ordentliche Klammerung ist auch die Tatsache, dass ein String in den EEDs nur 255 Zeichen lang sein darf. Bei irgendwelchen Textobjekten kann das ja mal überschritten werden, oder? Mit Klammerung kann man einem tag problemlos mehrere Teilstrings zuordnen, die dann von der Applikation zusammengeflickt werden. Ohne Klammerung, also im Array-Modell, ist dann der Ofen sofort aus. </edit> ------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 28. Jul. 2005 20:18 <-- editieren / zitieren --> Unities abgeben:
Hi Axel, nach deinem ersten Post dachte ich erst, das mit der Telefonnummer war ein symbolischer Gag. Ich mein, ich lese/verstehe dich ja ausschliesslich als todernste Type ;;-)) Aber jetzt, nachdem: > 4. Der Telefonnummer (bei Firmen aber ohne Durchwahl) wurde mir klar, dass du das durchaus ernst gemeint hast und ich habe denke auch die Tragweite bzw. das Ausmaß begriffen, was passieren kann, wenn man sich nicht an die 'Rules' hält. Guddi, bzgl. des Appli-Namens ist der Groschen entgültig gefallen. Man kann sogar - einem einmal eindeutig vergebenen Namen - später weitere Unterdaten hinzufügen, no Prob, habe ich heute festgestellt. Irgendwie war/bin ich da zu feldfixiert rangegangen, ich dachte die XDatas entsprächen [in etwa] einem Feld/Array. Scheint aber nicht so zu sein, weil zB. ua. ein Erweitern ohne Redim/Preserve geht. Andererseits bliebe in einem Array, wo italienisch fehlt, bei italienisch einfach ein False oder "" als Platzhalter, damit bleibt auch die 'Rechteckigkeit' erhalten, da das Element 'italienisch' nicht fehlt bzw. also es existiert schon, gibt aber einfach einen Nullstring oder False zurück. Alles in allem - die Gretchenfrage - geklammerte Listen/Hash's <> Matrix? Zu einer Entscheidung hab' ich mich noch nicht durchringen können, tendiere aber nach deiner Argumentation nun eher zu deiner Sichtweise. Sei's wie's sei, du hast mir jedenfalls ziemlich viel mit auf den Weg gegeben - Danke. :-) Gruss, eine 'verkappte' Miss Matrix ;-) [Diese Nachricht wurde von startrek am 28. Jul. 2005 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
mapcar Mitglied CADmin
Beiträge: 1250 Registriert: 20.05.2002 Die Phönizier haben das Geld erfunden - aber warum so wenig? (Johann Nepomuk Nestroy)
|
erstellt am: 28. Jul. 2005 21:24 <-- editieren / zitieren --> Unities abgeben: Nur für startrek
Ja, Nancy, mit einem italienischen Ausgang in Form von "" wären die Daten wieder rechteckig. Auch "" ist eine Übersetzung von "Ausgang", allerdings eine ziemlich schlechte;-) Aber das Leben ist nun mal nicht rechteckig, oder jedenfalls in den seltensten Fällen! In der Praxis sieht es jedenfalls so aus, dass an einem Entity nachher 100 verschiedene Datensätze dranhängen, am nächsten nur drei. Interessant wird die Geschichte allerdings erst wirklich, wenn die ganzen 1000er Gruppencodes ins Spiel kommen: 1007 z.B., ein Layer-Name. Was ist da, wenn der User den Layer umbenennt? Das wird ohne jedes Zutun in den EEDs korrigiert. Dann gibt es auch GCs, anhand derer man feststellen kann, ob ein Entity vom User gedreht oder verschoben wurde usw. Und schließlich gibt's auch noch die 'binary chunks' - da kann man z.B. alles drin unterbringen, was man sonst mit Pack&Go-Mechanismen zusammenschnüren würde. Ich hab's mal geschafft, die Acad.exe in eine Zeichnung einzupacken (als Test) - die lief hinterher sogar noch. Allerdings ist das alles sehr schwierig mit VBA zu handhaben, mit Lisp ist es viel, viel einfacher. Da braucht man einmal im Leben 50 Zeilen Code, und dann kann man eine Liste in EEDs verwandeln und wieder zurück (bestimmte Datentypen wie nil, file handle, exsubr usw. gehen allerdings nicht). In VBA gestaltet sich das alles sehr viel zäher und braucht meistens Unmengen von Codezeilen. Gruß, Axel ------------------ Meine AutoLisp-Seiten Mein Angriff auf dein Zwerchfell Mein Lexikon der Fotografie Mein gereimtes Gesülze Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|