| |
| 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: Attribute aus Excel einlesen (3344 mal gelesen)
|
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 16. Jun. 2014 07:11 <-- editieren / zitieren --> Unities abgeben:
Hallo Leute Ich habe wiedermal eine Frage. Ich lese zur Zeit die Attribute aus meinen exportierten Listen folgendermaßen ein: Das Lisp Programm such nach dem Handle und dann liest er einfach von links nach rechts (bis zu einer bestimmten Spalte) alle Spalten aus und schreibt sie in der selben Reihenfolge in die Blockattribute. Nun gibt es das Problem, dass der Benutzer vielleicht Spalten löscht oder verschiebt. Wenn dann importiert wird erhalten Attribute die falschen Werte. Ich möchte die Abfrage nun so gestalten: Erst sucht das Programm nach dem Handle um den richtigen Block zu finden. Dann soll es nicht einfach von links nach rechts einlesen sondern auch den Spaltenkopf auslesen und über diesen den Wert an das richtige Attribut übergeben. Also ein check Attributname = Spaltenheader Es handelt sich hier um max. 25 Attribute pro Block. Das heißt, die Lösung sollte effektiv sein und nicht für jedes Attribut eine if Funktion enthalten. Ich habe zum einlesen aus Excel sehr wenig im Netz gefunden. Vielleicht könnt ihr mir helfen. Lg. Kurt [Diese Nachricht wurde von kurt.trattner am 16. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 16. Jun. 2014 07:21 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Hallo kurt.trattner, dein Problem hat nichts mit Excel zu tun, sondern betrifft die Programmlogik und das Datenhandling. Du musst zunächst die Zeile ermitteln, in der die Spaltenüberschriften stehen. Dass kannst du aber nicht über die Excel-Eigenschaften auslesen, denn dass eine Zeile die Überschriften enthält, liegt alleine im Auge des Betrachters. Also entweder die Zeilennummer der Spaltenüberschriften vom Benutzer abfragen oder anhand der Inhalte (falls möglich) automatisch ermitteln. Wenn du das hast, kannst du ja das Auslesen der folgenden Zeilen gleich in eine Assoziationsliste durchführen '(("HANDLE" . "A01") ("SPALTENÜBERSCHRIFT-1" . "WERT-1") ("SPALTENÜBERSCHRIFT-2" . "WERT-2") ("SPALTENÜBERSCHRIFT-3" . "WERT-3") ... ("SPALTENÜBERSCHRIFT-X" . "WERT-X") ) Wenn du allerdings davon ausgehst, dass der Anwender Spalten löscht, dann musst du auch davon ausgehen, dass der Anwender die Spaltenüberschriften ändert ... was nun? (dies aber nur als Gedankenanstoß! -- Excel ist zwar ein beliebtes, aber auch das für den Programmierer am schlechtesten zu Programmierende Exportprogramm) Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 16. Jun. 2014 07:31 <-- editieren / zitieren --> Unities abgeben:
Schonmal danke für deine Antwort. Ich habe daran gedacht, dass ich dem Programm die Zeilennummer so mitteile, dass er nach der Zelle Handle sucht, also nach der Spaltenüberschrift für die Handles. Das mit dem Spaltenheader umbenennen ist so eine Sache ja da hast du recht. Aber, da ich eine Anleitung für das Programm schreiben werde, werde ich das einfach verbieten. Das Spalten löschen ist leider nötig, da nicht jeder alle Attribute in den Listen benötigt. (Detailgrad) Wenn ich das richtig verstehe, muss ich für diese Lösung bei "WERT-1" usw. immer die richtige Spalte einfügen. Diese weiß ich aber nicht sicher da ja zwischendrin Spalten gelöscht werden können. Und es gibt ja viele Einträge in der Liste. Da können auch leere Zeilen dabei sein. Diese soll er so wie er es jetzt auch tut überspringen, da ja kein Handle vorhanden. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 16. Jun. 2014 07:47 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
... (1) Auslesen der Spaltenüberschriften '((Spalte . Wert)..) ==> '((0 . "HANDLE")(1 . "ATTRIBUTNAME-2")(2 . "ATTRIBUTNAME-3")) (2) Auslesen der Datenzeilen '((Spalte . Wert ..) ==> '((0 . "4ABCD")(1 . "ATTRIBUTWERT-2")(2 . "ATTRIBUTWERT-3")) (3) für jede Datenzeile Spaltenheader mischen '((Spaltenbezeichnung/Attributbezeichnung . WERT)..) ==> '(("HANDLE" . "4ABCD")("ATTRIBUTNAME-2" . "ATTRIBUTWERT-2")(ATTRIBUTNAME-3 . "ATTRIBUTWERT-3"))
Code:
;(1) Auslesen der Spaltenüberschriften (setq HEADER '((0 . "HANDLE")(1 . "ATTRIBUTNAME-2")(2 . "ATTRIBUTNAME-3"))) ;(2) Auslesen der Datenzeilen (setq ZEILEN '( ((0 . "4ABC")(1 . "ATTRIBUTWERT-2")(2 . "ATTRIBUTWERT-3")) ((0 . "5EFG")(1 . "VALUE-2")(2 . "VALUE-3")) ((0 . "6HIJ")(1 . "ATTRIB-2")(2 . "ATTRIB-3")) ) ) ;(3) für jede Datenzeile Spaltenheader mischen ;'((Spaltenbezeichnung/Attributbezeichnung . WERT)..) (setq DATEN (mapcar '(lambda (ZEILE) (mapcar '(lambda (SPALTE) (cons (cdr(assoc (car SPALTE) HEADER)) (cdr SPALTE) ) ) ZEILE ) ) ZEILEN ) ) ;|====> '((("HANDLE" . "4ABC") ("ATTRIBUTNAME-2" . "ATTRIBUTWERT-2") ("ATTRIBUTNAME-3" . "ATTRIBUTWERT-3") ) (("HANDLE" . "5EFG") ("ATTRIBUTNAME-2" . "VALUE-2") ("ATTRIBUTNAME-3" . "VALUE-3") ) (("HANDLE" . "6HIJ") ("ATTRIBUTNAME-2" . "ATTRIB-2") ("ATTRIBUTNAME-3" . "ATTRIB-3") ) ) |;
Bei Fragen ...
Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 16. Jun. 2014 09:05 <-- editieren / zitieren --> Unities abgeben:
OK das sieht sehr gut aus und ich verstehe es Aber ich weiß nicht wie ich die Werte ins richtige Blockattribut schreiben kann. Bis jetzt hat es ja so mit einem counter funktioniert: Code: (setq axss (vla-get-activeselectionset adoc)) (vlax-for a axss (if (setq data (assoc (vla-get-handle a) blkinfo)) (progn (setq blkobj (vlax-ename->vla-object (handent (car data)))) (setq atts (vlax-invoke blkobj 'GetAttributes)) (setq attvalues (cddr data)) (if (and atts attvalues (= (length attvalues) (length atts))) (progn (setq cnt 0) (repeat (length atts) (setq at (nth cnt atts)) (vla-put-textstring at (nth cnt attvalues)) (setq cnt (1+ cnt)) ) ) ) )
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 16. Jun. 2014 09:17 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
... mir scheint, als wüßtest du nicht, was du tust. Du hast in deinem Code bereits Zugriff auf die jeweiligen Attribute. Du musst also nur die Attributsbezeichnung vergleichen und dann erst den Wert setzen. Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 16. Jun. 2014 09:22 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Soll das so über einen Auswahlsatz laufen ? Aber das ist ja nicht die Frage.. Also: (foreach ATT ATTS (if (setq DAT (assoc(strcase(vla-get-TagString ATT)) (cdr DATA))) (vla-put-TextString ATT (cdr DAT)) ) ) "Gehe alle ausgelesenen Attribute für die Blockreferenze durch (foreach ATT ATTS.. Wenn in den ausgelesenen Daten ein Attribut ATT gefunden wird (assoc (vla-get-Tagstring ATT (cdr DATA) Dann schreibe den Textwert hinein der im Treffer (DAT) an zweiter Stelle steht (cdr DAT)" Nur zum nachdenken: Wenn man das gedanklich durchgeht fällt einem auf das mit dieser Lösung alle gleichnamigen Attribute den gleichen Wert erhalten werden. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 16. Jun. 2014 09:44 <-- editieren / zitieren --> Unities abgeben:
@Brischke Ich kenne Lisp erst seit ein paar Wochen. Und den Grundcode habe ich aus Code teilen zusammengebaut, die ich im Internet gefunden habe. Ich bin schon froh, dass es so funktioniert wie es jetzt ist (was ohne die Hilfe aus dem Forum hier nicht so wäre) Das ist also noch eine Art Lernprojekt für mich Da es funktioniert soll ich jetzt immer mehr Erweiterungen und Verbesserungen programmieren. Dabei stoße ich leider hin und wieder auf kleine Schwierigkeiten. Ich hoffe ich nerve hier niemanden mit meinen Noob Fragen. @cadffm Baut dein Code auf dem auf was Brischke gepostet hat oder ist das eine andere Lösung? Das Programm soll zusätzlich auf den Handle achten. Somit sollte er Attribute mit gleichen Namen in verschiedenen Blöcken unterscheiden können oder? [Diese Nachricht wurde von kurt.trattner am 16. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 16. Jun. 2014 10:23 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Es ist ehren und liebenswert das du diese Dinge angehst, aber so ein wenig Basics wären schon nicht schlecht. (nach ein paar Wochen solltest du lieber Zeichenketten und zahlen manipulieren können anstatt dich mit der Blockstruktur zu quälen ) Du mußt einfach erst mal mit Messer und Gabel umgehen können, erst danach geht die Nahrungsaufnahme richtig los Wie man addiert, vergleicht und Zeichenketten manipuliert ==> Klick! Wie das Spiel weiter geht, das steht dort auch beschrieben. Wie die Datenstruktur in Lisp/VisualLisp aussieht, das steht dort aber nicht im Vordergrund. Wenn du wirklich Interesse hast, dann fange noch mal ganz in Ruhe bei Null an und lerne die Addition (als einfachsten Beispiel für den Anfang), danach hast du die Basis Probleme selbst zu lösen (weil du es verstehst und handeln kannst). PS: -Mein Code baut auf dem Posting von Brischke auf. -Zur Zeit merkst du dir das Handle der Blockreferenz, eine Blockreferenz kann aber 3 Attribute mit dem gleichen Namen haben (gehört verboten, ist aber so)
------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 16. Jun. 2014 10:31 <-- editieren / zitieren --> Unities abgeben:
Da stimme ich dir voll und ganz zu aber wie es in der Arbeitswelt so ist, ist Zeit = Geld. Deswegen muss ich schauen, dass ich schnell bin. Ich habe bereits Erfahrung in anderen Programmiersprachen (C++, C, Phyton, usw.) Aber ich werde mir die Zeit nehmen und die Seite anschauen. Danke dafür Vielleicht kann ich das Problem dann selbst lösen. Wegen den gleichen Attributen: Ich erstelle auch selbst die vordefinierten Blöcke die der Anwender dann Verwenden muss. Also ist das mit dem selben Namen kein Problem Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 16. Jun. 2014 16:33 <-- editieren / zitieren --> Unities abgeben:
Ich habe mir jetzt die ganze Seite durchgelesen. Die Seite ist wirklich sehr gut. Aber leider ist das mit mapcar, lambda usw noch ein bisschen zu schwer. Leider brauche ich es hier. Ich weiß jetzt ca wie es funktioniert aber auf mein Beispiel hier anwenden ist doch etwas ganz anderes. Und leider gibt es nichts vergleichbares mit auslesen von Blöcken und schreiben von Variablen. Ich habe mich beim Code etwas ausgetobt aber er funktioniert so leider nicht :/ Ich habe Kommentare hinzugefügt. Vielleicht kann sich das jemand anschauen und mir etwas weiterhelfen. Es scheitert denke ich nur an der Zuweisung an einzelne Attribute.
Code: (defun EXD (/ ExcelApp ExcData FilePath Sht ShtNum UsdRange Wbk) (or (vl-load-com)) (setq FilePath (getfiled "Select file to read data :" "C:\\TEMP\\" "xlsx" 16 ) ) (setq ShtNum (getint "\nEnter sheet number : \n" )) (setq ExcelApp (vlax-get-or-create-object "Excel.Application" )) (vlax-put-property ExcelApp "DisplayAlerts" :vlax-false) (vla-put-Visible ExcelApp :vlax-true) (setq Wbk (vl-catch-all-apply 'vla-open (list (vlax-get-property ExcelApp "WorkBooks" ) FilePath) ) ) (setq Sht (vl-catch-all-apply 'vlax-get-property (list (vlax-get-property Wbk "Sheets" ) "Item" ShtNum ) ) ) (vlax-invoke-method Sht "Activate" ) ;;; (setq UsdRange (vlax-get-property Sht 'UsedRange) (setq UsdRange (vlax-get-property Sht "Range" "A1:M1006") ExcData (vlax-safearray->list (vlax-variant-value (vlax-get-property UsdRange 'Value2) ) ) ) (setq ExcData (mapcar (function (lambda (x) (mapcar 'vl-princ-to-string (mapcar 'vlax-variant-value x)))) ExcData ) ) (vlax-put-property ExcelApp "DisplayAlerts" :vlax-true) (mapcar (function (lambda (x) (vl-catch-all-apply (function (lambda () (progn (if (not (vlax-object-released-p x)) (progn (vlax-release-object x) (setq x nil) ) ) ) ) ) ) ) ) (list UsdRange Sht Wbk ExcelApp) ) (gc) (gc) ExcData ) ;; main programm (defun C:LISTIN (/ adoc at atts attvalues axss blkinfo blkobj cnt data OSM ss HEADER ZEILE DATEN SPALTE DAT ZEILEN) (vl-load-com) (setq adoc (vla-get-activedocument (vlax-get-acad-object) ) ) (vla-endundomark adoc) (vla-startundomark adoc) (setq blkinfo (exd)) (setq blkinfo (mapcar (function (lambda (x) (vl-remove-if (function (lambda (y) (eq nil y)) ) x))) (cdr blkinfo);<--remove headers ) )
(setq blkinfo (vl-remove-if (function (lambda(x) (or (not x)(wcmatch (car x) "T*"))));<-- remove 'TOTAL' row blkinfo ) ) (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 66 1)))) ;;Auswahlsatz für alle Blöcke in der Zeichnung (setq HEADER '((0 . "HANDLE")(1 . "ATTRIBUTNAME-2")(2 . "ATTRIBUTNAME-3")(3 . "ATTRIBUTNAME-4"))) ;;Erzeugen der Headerliste (setq ZEILEN '( ;;Erzeugen der Listen für die einzelnen Zeilen ... Muss man hier wirklich jede einzeln definieren? Bis zu 1000! ((0 . "4ABC")(1 . "ATTRIBUTWERT-2")(2 . "ATTRIBUTWERT-3")(3 . "ATTRIBUTWERT-4")) ((0 . "5EFG")(1 . "VALUE-2")(2 . "VALUE-3")(3 . "VALUE-4")) ((0 . "6HIJ")(1 . "ATTRIB-2")(2 . "ATTRIB-3")(3 . "ATTRIB-4")) ) ) (setq DATEN (mapcar '(lambda (ZEILE) ;;Diese Funktion verstehe ich nicht 100%ig (mapcar '(lambda (SPALTE) (cons (cdr(assoc (car SPALTE) HEADER)) (cdr SPALTE) ) ) ZEILE ) ) ZEILEN ) ) '((("HANDLE" . "4ABC") ;; Listenzuordnung von Header und Werten ... Muss das auch alles händisch geschrieben werden? ("ATTRIBUTNAME-2" . "ATTRIBUTWERT-2") ("ATTRIBUTNAME-3" . "ATTRIBUTWERT-3") ) (("HANDLE" . "5EFG") ("ATTRIBUTNAME-2" . "VALUE-2") ("ATTRIBUTNAME-3" . "VALUE-3") ) (("HANDLE" . "6HIJ") ("ATTRIBUTNAME-2" . "ATTRIB-2") ("ATTRIBUTNAME-3" . "ATTRIB-3") ) ) (setq axss (vla-get-activeselectionset adoc)) (vlax-for a axss (setq data (assoc (vla-get-handle a) blkinfo)) ;;Auslesen der Handle aus der Zeichnung (setq blkobj (vlax-ename->vla-object (handent (car data)))) ;;Reduzierung der Attributliste auf den ersten Eintrag (Handle) (setq atts (vlax-invoke blkobj 'GetAttributes)) ;;Auslesen der Attribute aus der Zeichnung ;;; (setq attvalues (cddr data)) (foreach ATT atts ;;Check ob Header und Attribut Tag gleich sind (if (setq DAT (assoc(strcase(vla-get-TagString ATT)) (cddr HEADER))) ;;Wenn ja soll der String in die Liste DAT geschrieben werden? (vla-put-TextString ATT (cddr DAT)) ) ) ) ;;; (if (and atts attvalues (= (length attvalues) (length atts))) ;;; (progn ;;; (setq cnt 0) ;;; (repeat (length atts) ;;; (setq at (nth cnt atts)) ;;; (vla-put-textstring at (nth cnt attvalues)) ;;; (setq cnt (1+ cnt)) ;;; ) ;;; ) ;;; ) ;;; ) ;;; ) ;;; ) (vla-endundomark adoc) (princ) ) (princ "\n\t\t***\tStart command with LISTIN...\t***") (princ) ;;;(C:LISTIN)
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 16. Jun. 2014 17:08 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Zitat: Original erstellt von kurt.trattner: ... Vielleicht kann sich das jemand anschauen und mir etwas weiterhelfen. ...
Auch meine Zeit kostet Geld .. und da aus deinen Kommentaren ersichtlich ist, dass du anhand des geposteten Beispiel-Code nicht die Herangehensweise erkannt hast, läuft es darauf hinaus, dass dir der Code komplett geschrieben werden müsste (was gleich viel Zeit .. folglich auch viel Geld bedeutet). So kommen wir hier nicht weiter. Du solltest in Stichpunkten darstellen, wie du denkst, dass der Programmablauf detailliert ausschauen soll. (und dann mal schauen, ob du diese Programmlogik in deinem Code wiederfindest) Grüße! Holger
------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 23. Jun. 2014 15:49 <-- editieren / zitieren --> Unities abgeben:
Ich denke ich bin nun schon etwas weiter. Vielen Dank für die Aufforderung mich mehr mit der Sprache im allgemeinen vertraut zu machen Ich denke ich verstehe es jetzt deutlich besser als vorher. Ich habe aber immer noch ein Problem. Ich habe den Header so erstellt, dass er sich an die jeweilige Liste anpassen kann. Das habe ich so gemacht: (Wahrscheinlich sehr umständlich aber es funktioniert)
Code: (setq Handle (cons 0 (nth 0 headerlist))) (setq Blockname (cons 1 (nth 1 headerlist))) (setq Att1 (cons 2 (nth 2 headerlist))) (setq Att2 (cons 3 (nth 3 headerlist))) (setq Att3 (cons 4 (nth 4 headerlist))) (setq Att4 (cons 5 (nth 5 headerlist))) (setq Att5 (cons 6 (nth 6 headerlist))) (setq Att6 (cons 7 (nth 7 headerlist))) (setq Att7 (cons 8 (nth 8 headerlist))) (setq Att8 (cons 9 (nth 9 headerlist))) (setq Att9 (cons 10 (nth 10 headerlist))) (setq Att10 (cons 11 (nth 11 headerlist))) (setq Att11 (cons 12 (nth 12 headerlist))) (setq Att12 (cons 13 (nth 13 headerlist))) (setq Att13 (cons 14 (nth 14 headerlist))) (setq Att14 (cons 15 (nth 15 headerlist))) (setq Att15 (cons 16 (nth 16 headerlist))) (setq Att16 (cons 17 (nth 17 headerlist))) (setq Att17 (cons 18 (nth 18 headerlist))) (setq Att18 (cons 19 (nth 19 headerlist))) (setq Att19 (cons 20 (nth 20 headerlist))) (setq Att20 (cons 21 (nth 21 headerlist))) (setq Att21 (cons 22 (nth 22 headerlist))) (setq Att22 (cons 23 (nth 23 headerlist))) (setq Att23 (cons 24 (nth 24 headerlist))) (setq Att24 (cons 25 (nth 25 headerlist))) (setq Att25 (cons 26 (nth 26 headerlist))) (setq Att26 (cons 27 (nth 27 headerlist))) (setq HEADER (list Handle Blockname Att1 Att2 Att3 Att4 Att5 Att6 Att7 Att8 Att9 Att10 Att11 Att12 Att13 Att14 Att15 Att16 Att17 Att18 Att19 Att20 Att21 Att22 Att23 Att24 Att25 Att26))
Die Ausgabe davon sieht so aus: Die nils sind noch leere Spalten die später aber gebraucht werden. ((0 . HANDLE) (1 . BLOCK NAME) (2 . EQUIPMENTNUMBER) (3 . CODE) (4 . NOMINAL SIZE) (5 . SCOPE) (6 . REMARK) (7 . REV) (8 . SUPPLIER) (9 . PRODUCT) (10 . TYPE) (11 . SPECIFICATION 1) (12 . SPECIFICATION 2) (13 . nil) (14 . nil) (15 . nil) (16 . nil) (17 . nil) (18 . nil) (19 . nil) (20 . nil) (21 . nil) (22 . nil) (23 . nil) (24 . nil) (25 . nil) (26 . nil) (27 . nil)) Danach kommt der Codeteil den ich hier bekommen habe. Hier weiß ich jedoch nicht wie ich auf einfachem weg meine Daten aus der Tabelle in die Attributwerte bekomme.
Enthalten sind sie hier in der Liste "data": (8A47 *U30 123 XXXXXX LOCATION PCS XXXXXX XXXXXX XXXXXX DETAIL DIMENSIONS MEDIUM CONSISTENCY OPERATING PRESSURE OPERATING TEMPERATURE PH MANUFACTURER FABRICATE DESIGN DATA2 DESIGN DATA2 DESIGN DATA3 MATERIAL DATA ACCESOIRS1 ACCESOIRS2 ACCESOIRS3 PURCHASING ERECTION - 0) Ich könnte sie natürlich auf die selbe Weiße zuordnen wie die Header aber da es beliebig viele Einträge sein können ist das keine Lösung. Ich habe schon daran gedacht eine cnt variable einzusetzen und dadurch eine nth funktion hochzuzählen. Aber ich habe keine Idee wie ich dann auf die nächste Zeile springen soll. Sonst wird er mir ja alles in einer Wurst zuweisen. Code: (setq ZEILEN '( ((0 . "HANDLE-1")(1 . "BLOCKNAME-1")(2 . "ATTRIBUTWERT-1")(3 . "ATTRIBUTWERT-2")) ((0 . "HANDLE-2")(1 . "BLOCKNAME-2")(2 . "ATTRIBUTWERT-3")(3 . "ATTRIBUTWERT-4")))) (setq DATEN (mapcar '(lambda (ZEILE) (mapcar '(lambda (SPALTE) (cons (cdr(assoc (car SPALTE) HEADER)) (cdr SPALTE)) ) ZEILE ) ) ZEILEN ) )
Die Ausgabe der Liste DATEN sieht so aus: (((HANDLE . HANDLE-1) (BLOCK NAME . BLOCKNAME-1) (EQUIPMENTNUMBER . ATTRIBUTWERT-1) (CODE . ATTRIBUTWERT-2)) ((HANDLE . HANDLE-2) (BLOCK NAME . BLOCKNAME-2) (EQUIPMENTNUMBER . ATTRIBUTWERT-3) (CODE . ATTRIBUTWERT-4)))
Wie man sieht wird alles richtig zugewiesen nur die Werte stimmen halt nicht. Er lädt hier immer nur die vorgegebenen. Weiter habe ich folgendes an Anlehnung an den oben geposteten Code versucht:
Code: (foreach Att atts (setq tag (vla-get-TagString Att)) (setq taglist (cons tag taglist)) (if (setq DAT (assoc tag HEADER)) (vla-put-TextString Att (car DAT)))) (setq taglist (reverse taglist)) ;; zum testen
Ich habe die Variable tag deswegen gesetzt um es für mich verständlicher zu machen. Die taglist ist nur ein Test um zu schauen ob der Befehl vla-get-TagString und die Schleife funktioniert. Es funktioniert und gibt mir die Attributtags in umgekehrter Reihenfolge aus deswegen des reverse zum Schluss. Leider kommt hier wenn er den assoc Befehl ausführ immer der Fehler: error: bad function: "EQUIPMENTNUMBER" Wäre nett wenn mir jemand bei letztgenanntem Fehler und bei der Zuordnung der Werte Helfen könnte. Ich will keinen ganzen Code sondern nur einen Denkanstoß damit ich wieder weiterkomme. Schon einmal vielen Dank Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 24. Jun. 2014 08:00 <-- editieren / zitieren --> Unities abgeben:
Ich bin nun noch ein Stück weiter Ich habe es geschafft meine Daten als "Zeilen" zu definieren. Mit folgendem Code: Code:
(setq cnt 0) (repeat (length data) (setq Attv (cons cnt (nth cnt data))) (setq cnt (1+ cnt)) (setq ZEILEN (cons Attv ZEILEN)) (if (= cnt (length headerlist)) (setq cnt 0) ) ) (setq ZEILEN (reverse ZEILEN))
Die Ausgabe sieht folgendermaßen aus: ((0 . 14471) (1 . *U20) (2 . 4) (3 . 4) (4 . 4) (5 . 4) (6 . 4) (7 . 4) (8 . 4) (9 . 4) (10 . 4) (11 . 4) (12 . 4) (13 . 4) (14 . 4) (15 . 4) (16 . 4) (17 . 4) (18 . 4) (19 . 4) (20 . 4) (21 . 4) (22 . 4) (23 . 4) (24 . 4) (25 . 4) (26 . 4) (27 . 4))((0 . 143A9) (1 . *U20) (2 . 3) (3 . 3) (4 . 3) (5 . 3) (6 . 3) (7 . 3) (8 . 3) (9 . 3) (10 . 3) (11 . 3) (12 . 3) (13 . 3) (14 . 3) (15 . 3) (16 . 3) (17 . 3) (18 . 3) (19 . 3) (20 . 3) (21 . 3) (22 . 3) (23 . 3) (24 . 3) (25 . 3) (26 . 3) (27 . 3))((0 . 142E1) (1 . *U20) (2 . 2) (3 . 2) (4 . 2) (5 . 2) (6 . 2) (7 . 2) (8 . 2) (9 . 2) (10 . 2) (11 . 2) (12 . 2) (13 . 2) (14 . 2) (15 . 2) (16 . 2) (17 . 2) (18 . 2) (19 . 2) (20 . 2) (21 . 2) (22 . 2) (23 . 2) (24 . 2) (25 . 2) (26 . 2) (27 . 2))((0 . 8A47) (1 . *U20) (2 . 1) (3 . 1) (4 . 1) (5 . 1) (6 . 1) (7 . 1) (8 . 1) (9 . 1) (10 . 1) (11 . 1) (12 . 1) (13 . 1) (14 . 1) (15 . 1) (16 . 1) (17 . 1) (18 . 1) (19 . 1) (20 . 1) (21 . 1) (22 . 1) (23 . 1) (24 . 1) (25 . 1) (26 . 1) (27 . 1)) Das Format der Liste müsste eigentlich so stimmen. Aber wenn ich jetzt den Code ausführe, der die Liste "DATEN" erzeugen soll bekomme ich immer den Fehler ; error: bad argument type: consp 0 Was bedeutet dieser Fehler? Im Internet habe ich nichts brauchbares gefunden zu diesem Fehler. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 24. Jun. 2014 08:11 <-- editieren / zitieren --> Unities abgeben:
Problem gelöst. Einfach die Liste in noch eine Liste packen und es funktioniert. Code: (setq ZEILEN (list (reverse ZEILEN)))
Die Ausgabe von DATEN sieht jetzt so aus: ( ((HANDLE . 14471) (BLOCK NAME . *U20) (EQUIPMENTNUMBER . 4) (CODE . 4) (NOMINAL SIZE . 4) (SCOPE . 4) (REMARK . 4) (REV . 4) (SUPPLIER . 4) (PRODUCT . 4) (TYPE . 4) (SPECIFICATION 1 . 4) (SPECIFICATION 2 . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4)) ) ( ((HANDLE . 143A9) (BLOCK NAME . *U20) (EQUIPMENTNUMBER . 3) (CODE . 3) (NOMINAL SIZE . 3) (SCOPE . 3) (REMARK . 3) (REV . 3) (SUPPLIER . 3) (PRODUCT . 3) (TYPE . 3) (SPECIFICATION 1 . 3) (SPECIFICATION 2 . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3) (nil . 3)) ) (((HANDLE . 142E1) (BLOCK NAME . *U20) (EQUIPMENTNUMBER . 2) (CODE . 2) (NOMINAL SIZE . 2) (SCOPE . 2) (REMARK . 2) (REV . 2) (SUPPLIER . 2) (PRODUCT . 2) (TYPE . 2) (SPECIFICATION 1 . 2) (SPECIFICATION 2 . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2) (nil . 2)) ) (((HANDLE . 8A47) (BLOCK NAME . *U20) (EQUIPMENTNUMBER . 1) (CODE . 1) (NOMINAL SIZE . 1) (SCOPE . 1) (REMARK . 1) (REV . 1) (SUPPLIER . 1) (PRODUCT . 1) (TYPE . 1) (SPECIFICATION 1 . 1) (SPECIFICATION 2 . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1) (nil . 1)) ) Jetzt geht es um das Zuweisen. [Diese Nachricht wurde von kurt.trattner am 24. Jun. 2014 editiert.] [Diese Nachricht wurde von kurt.trattner am 24. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1455 Registriert: 11.01.2006 WIN 10 ACAD 2022 BricsCAD V23
|
erstellt am: 24. Jun. 2014 09:01 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Hallo Kurt, ich hab mir das mal angeschaut. Manchmal etwas umständlich und etwas zu viel unnötige Arbeit reingesteckt. Ich hab zwar noch keine Exceldatei von dir gesehen aber ich denke ich weis wie die aussieht. Versuch doch mal das hier, ich denke damit kommst du weiter. Code von dir etwas umgebaut etwas gekürzt und etwas ergänzt. Code: (defun k_excel-usedrange (excelsheet art / startzeile zeilen startspalte spalten) ;;; Benutzten Bereich von Excel feststellen (setq startzeile (vlax-get-property (vlax-get-property (vlax-get-property excelsheet "UsedRange") "ROWS" ) "Row" ) zeilen (vlax-get-property (vlax-get-property (vlax-get-property excelsheet "UsedRange") "ROWS" ) "COUNT" ) startspalte (vlax-get-property (vlax-get-property (vlax-get-property excelsheet "UsedRange") "Columns" ) "COLUMN" ) spalten (vlax-get-property (vlax-get-property (vlax-get-property excelsheet "UsedRange") "Columns" ) "COUNT" ) ) (if art (strcat (k_dez->excel startspalte) (itoa startzeile) ":" (k_dez->excel (+ startspalte spalten -1)) (itoa (+ startzeile zeilen -1)) ) (list startzeile zeilen startspalte spalten) ) )(defun k_dez->excel (zahl / txt z) ;;; Zahl in alphanumerische Excel-Spaltenbezeichnung konvertieren (setq txt "") (while (> zahl 26) (setq z (rem zahl 26)) (if (= z 0) (setq z 26 zahl (- zahl 26) ) ) (setq zahl (fix (/ zahl 26)) txt (strcat (chr (+ z 64)) txt) ) ) (setq txt (strcat (chr (+ zahl 64)) txt)) ) (defun EXD (/ ExcelApp ExcData FilePath Sht ShtNum UsdRange Wbk) ;;; (or (vl-load-com)) (setq FilePath (getfiled "Select file to read data :" "C:\\TEMP\\" "xlsx" 16 ) ) (setq ShtNum (getint "\nEnter sheet number : \n")) (setq ExcelApp (vlax-get-or-create-object "Excel.Application")) (vlax-put-property ExcelApp "DisplayAlerts" :vlax-false) (vla-put-Visible ExcelApp :vlax-true) (setq Wbk (vl-catch-all-apply 'vla-open (list (vlax-get-property ExcelApp "WorkBooks") FilePath) ) ) (setq Sht (vl-catch-all-apply 'vlax-get-property (list (vlax-get-property Wbk "Sheets") "Item" ShtNum ) ) ) (vlax-invoke-method Sht "Activate") ;;; hier brauchst du nur den wirklich benutzten Bereich als usedrange (setq UsdRange (vlax-get-property Sht "Range" (k_excel-usedrange sht t)) ExcData (vlax-safearray->list (vlax-variant-value (vlax-get-property UsdRange 'Value2) ) ) ) (setq ExcData (mapcar (function (lambda (x) (mapcar 'vl-princ-to-string (mapcar 'vlax-variant-value x) ) ) ) ExcData ) ) (vlax-put-property ExcelApp "DisplayAlerts" :vlax-true) (mapcar (function (lambda (x) (vl-catch-all-apply (function (lambda () (progn (if (not (vlax-object-released-p x)) (progn (vlax-release-object x) (setq x nil) ) ) ) ) ) ) ) ) (list UsdRange Sht Wbk ExcelApp) ) ;;; Excel wieder "freigeben" (vlax-release-object ExcelApp) (vlax-release-object Wbk) (vlax-release-object Sht) (gc) (gc) ExcData ) ;; main programm (defun C:LISTIN (/ adoc at atts attvalues axss blkinfo blkobj cnt data OSM ss HEADER ZEILE DATEN SPALTE DAT ZEILEN ) (vl-load-com) (setq adoc (vla-get-activedocument (vlax-get-acad-object) ) ) (vla-endundomark adoc) (vla-startundomark adoc) (setq blkinfo (exd)) (setq kopfzeile (mapcar 'strcase (car blkinfo))) (setq blkinfo (cdr blkinfo))
;;; Position der Zeile "HANDLE" bestimmen (setq handle-pos (vl-position "HANDLE" kopfzeile)) ;;; Liste so bearbeiten dass mit (assoc handle ...) ein Eintrag gefunden werden kann ;;; und in der dann gefundenen Datenliste wieder mit assoc der Attributnamen gefunden werden kann (setq blkinfo (mapcar '(lambda (data) (cons (nth handle-pos data) (mapcar 'list kopfzeile data) ) ) blkinfo ) ) (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 66 1)))) ;;Auswahlsatz für alle Blöcke in der Zeichnung (setq axss (vla-get-activeselectionset adoc)) (vlax-for blkobj axss (if (setq data (assoc (vla-get-handle blkobj) blkinfo)) (progn ;; alle Attribute vom Block abarbeiten (foreach ATT (vlax-invoke blkobj 'GetAttributes) ;; wenn Attribut in Datenliste dann Inhalt übernehmen (if (setq DAT (assoc (strcase (vla-get-TagString ATT)) (cdr data)) ) (vla-put-TextString ATT (cadr DAT)) ) ) ) ) ) (vla-endundomark adoc) (princ) ) (princ "\n\t\t***\tStart command with LISTIN...\t***") (princ) ;;;(C:LISTIN)
------------------ Geht nicht, gibts nicht Gruß Andreas http://kraus-cad.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 24. Jun. 2014 09:12 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Gut, dann brauche ich ja nicht mehr erklären das zur Problemfindung "eine Klammer (unnütze) ergänzen" ganz gut ist, aber sicher nicht als Lösung. Dafür sollte man dann doch lieber schauen wo der Zugriff auf die Liste 'falsch' ist. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 24. Jun. 2014 10:42 <-- editieren / zitieren --> Unities abgeben:
Hallo. Zuerst einmal vielen Dank für den Code und für die Mühe die du dir gemacht hast Ich habe meinen Code jetzt versucht nach deiner Vorlage zu ändern. (außer dem Excel Teil) Leider kommt immer der Fehler "too few arguments" Wenn das mit deinem Code eigentlich so klappt habe ich ja im Kreis programmiert Ich hänge hier mal eine Beispielsliste und ein ein dwg mit den richtigen Blöcken (die Pumpen) an. Ich frage mich aber immer noch warum mein assoc nicht funktioniert. Kann es daran liegen, dass er den Tag als String ausliest? [Diese Nachricht wurde von kurt.trattner am 24. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 24. Jun. 2014 11:10 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Tag=String, Natürlich als was sonst ? (type irgenwas) zeigt dir um was für einen Datentyp es sich handelt.. und zu wenig Argumente sind weniger Argumente wie erwartet .. Habe mich schon die ganze Zeit gefragt was du hier postest, denn die Acadrückgabe war das nie.. dachte aber eher an ein Copy&Paste Problem bei dem die "" verloren gehen
------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 24. Jun. 2014 11:30 <-- editieren / zitieren --> Unities abgeben:
Das Problem ist, dass er mir immer den Fehler mit der Bad Function ausgibt zB -> bad function "NUMBERS" Mir ist klar, dass ein String keine Funktion sein kann. Deswegen verwirrt mich diese Fehlermeldung etwas. Wenn er keine Übereinstimmungen findet sollte assoc doch nil zurückgeben oder? Und die AutoCAD Ausgabe sieht bei mir so aus wenn ich (princ DATEN) eingebe da sind keine Anführungszeichen: ( ((HANDLE . 14471) (BLOCK NAME . *U20) (EQUIPMENTNUMBER . 4) (CODE . 4) (NOMINAL SIZE . 4) (SCOPE . 4) (REMARK . 4) (REV . 4) (SUPPLIER . 4) (PRODUCT . 4) (TYPE . 4) (SPECIFICATION 1 . 4) (SPECIFICATION 2 . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4) (nil . 4)) ) Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1455 Registriert: 11.01.2006 WIN 10 ACAD 2022 BricsCAD V23
|
erstellt am: 24. Jun. 2014 11:32 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
Ahh... du hast noch etwas über der Zeile mit den "Spaltenüberschriften" Das muss natürlich übersprungen werden. Nach (setq blkinfo (exd)) das hier einfügen, dann geht's. (while (not (member "HANDLE" (car blkinfo))) (setq blkinfo (cdr blkinfo)) ) Und dann natürlich: (setq headerlist (mapcar 'strcase (car blkinfo))) Der Fehler den du suchst ist hier:
(vla-get-TagString) mach mal (vla-get-TagString ATT) daraus Versuch mal weniger cddddr zu verwenden, das geht eleganter, strukturierter und außerdem verreckt dir irgendwann die "D"-Taste.
Wenn du fertig bist kommt sicher irgendeiner auf die Idee und fügt noch eine Zeile ein, und dann ? Besser wenn ein Programm für alle Schandtaten offen ist. (naja, alle schafft man nicht aber viele)
Code:
;;===========================================;; ;; local defun ;; read used range of Excel sheet ;; ========================================= ;; (defun EXD (/ ExcelApp ExcData FilePath Sht ShtNum UsdRange Wbk)
(or (vl-load-com)) (setq FilePath (getfiled "Select file to read data :" "C:\\TEMP\\" "xlsx" 16 ) ) (setq ShtNum (getint "\nEnter sheet number : \n")) (setq ExcelApp (vlax-get-or-create-object "Excel.Application")) (vlax-put-property ExcelApp "DisplayAlerts" :vlax-false) (vla-put-Visible ExcelApp :vlax-true) (setq Wbk (vl-catch-all-apply 'vla-open (list (vlax-get-property ExcelApp "WorkBooks") FilePath) ) ) (setq Sht (vl-catch-all-apply 'vlax-get-property (list (vlax-get-property Wbk "Sheets") "Item" ShtNum ) ) ) (vlax-invoke-method Sht "Activate") (setq UsdRange (vlax-get-property Sht 'UsedRange) ;;; (setq UsdRange (vlax-get-property Sht "Range" "A1:M1006") ExcData (vlax-safearray->list (vlax-variant-value (vlax-get-property UsdRange 'Value2) ) ) ) (setq ExcData (mapcar (function (lambda (x) (mapcar 'vl-princ-to-string (mapcar 'vlax-variant-value x) ) ) ) ExcData ) ) (vlax-put-property ExcelApp "DisplayAlerts" :vlax-true) ;;; (vl-catch-all-apply ;;; 'vlax-invoke-method ;;; (list Wbk "close" ) ;;; ) ;;; ;;; (vl-catch-all-apply ;;; 'vlax-invoke-method ;;; (list ExcelApp "quit" ) ;;; ) (mapcar (function (lambda (x) (vl-catch-all-apply (function (lambda () (progn (if (not (vlax-object-released-p x)) (progn (vlax-release-object x) (setq x nil) ) ) ) ) ) ) ) ) (list UsdRange Sht Wbk ExcelApp) ) (gc) (gc) ExcData ) ;; main programm (defun C:LISTIN (/ adoc at atts attvalues axss blkinfo blkobj cnt data osm ss ZEILE SPALTE ZEILEN DATEN HEADER DAT ) (vl-load-com) (setq adoc (vla-get-activedocument (vlax-get-acad-object) ) ) (vla-endundomark adoc) (vla-startundomark adoc) (setq blkinfo (exd))
(while (not (member "HANDLE" (car blkinfo))) (setq blkinfo (cdr blkinfo)) ) ;;; (setq headerlist (cadr(cddddr blkinfo))) (setq headerlist (mapcar 'strcase (car blkinfo))) ;;; (setq blkinfo (mapcar ;;; (function (lambda (x) ;;; (vl-remove-if (function (lambda (y) ;;; (eq "lululululululululululululul" y)) ) ;;; x))) ;;; (cdr blkinfo);<--remove headers ;;; ) ;;; ) (setq blkinfo (cdr blkinfo)) (setq handle-pos (vl-position "HANDLE" headerlist)) ;;; (setq blkinfo (vl-remove-if (function (lambda(x) ;;; (or (not x)(wcmatch (car x) "T*"))));<-- remove 'TOTAL' row ;;; blkinfo ;;; ) ;;; ) ;; (vl-cmdf "zoom" "a") ;; (vl-cmdf "zoom" ".85x") (setq blkinfo (mapcar '(lambda (data) (cons (nth handle-pos data) (mapcar 'list headerlist data) ) ) blkinfo ) ) (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 66 1)))) (setq axss (vla-get-activeselectionset adoc)) ;;; (vlax-for a axss (vlax-for blkobj axss (if (setq data (assoc (vla-get-handle blkobj) blkinfo)) (progn ;;; (setq blkobj (vlax-ename->vla-object (handent (car data)))) ;;; (setq atts (vlax-invoke blkobj 'GetAttributes)) ;;; (setq attvalues (cddr data)) (foreach ATT (vlax-invoke blkobj 'GetAttributes) (if (setq DAT (assoc (strcase (vla-get-TagString ATT)) (cdr data)) ) (vla-put-TextString ATT (cadr DAT)) ) ) ) ) ) (vla-endundomark adoc) (princ) ) ;;) (princ "\n\t\t***\tStart command with LISTIN...\t***") (princ) ;;;(C:LISTIN)
------------------ Geht nicht, gibts nicht Gruß Andreas http://kraus-cad.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 24. Jun. 2014 11:39 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
bad function "NUMBERS" Mir ist klar, dass ein String keine Funktion sein kann. Deswegen verwirrt mich diese Fehlermeldung etwas. Gut, denn offenbar wird Lisp dieser String an einer Stelle angeboten an dem Lisp eine Funktion erwartet (also nach einer öffnenden Klammer die ausgewertet wird) Wenn er keine Übereinstimmungen findet sollte assoc doch nil zurückgeben oder? ja Und die AutoCAD Ausgabe sieht bei mir so aus wenn ich (princ DATEN) eingebe da sind keine Anführungszeichen: ahhhhh , aber (princ irgendwas) gibt ja nicht den Wert von irgendwas wieder, sondern die Rückgabe von (PRINC irgendwas) Bitte mal in die Befehlszeile klöppeln: (setq test '("wer" . "wo"))<enter> (princ test)<enter> !test<enter> Siehst du den Unterschied zwischen Sein und Schein ?
------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 22275 Registriert: 03.06.2002 Alles
|
erstellt am: 24. Jun. 2014 11:44 <-- editieren / zitieren --> Unities abgeben: Nur für kurt.trattner
|
kurt.trattner Mitglied Mechanical Plant Engineer
Beiträge: 46 Registriert: 28.05.2014 AutoCAD Mechanical 2012
|
erstellt am: 24. Jun. 2014 12:03 <-- editieren / zitieren --> Unities abgeben:
@Andreas Kraus Vielen vielen Dank es funktioniert @cadffm Danke auch für deine Hilfe. Ich habe dadurch viel dazugelernt. Wenn ich Zeit habe werde ich auch den anderen Lösungsweg ausprobieren Jetzt kann ich mich wieder an das Exporttool machen. Das bekommt jetzt ein Fenster mit dlc um die gewünschten Attribute für die Liste auswählen zu können [Diese Nachricht wurde von kurt.trattner am 24. Jun. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |