| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Liste erstellen, ergänzen und Elemente hinzufügen und sortierensortieren (3002 mal gelesen)
|
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 15. Aug. 2017 14:37 <-- editieren / zitieren --> Unities abgeben:
Hallo, ich stehe mit meinen lange nicht genutzten LISP-Kenntnissen auf dem Schlauch. Es geht um den Datenaustausch von AutoCAD zu MegaCAD. Genauer gesagt, die Filterfunktionen von AutoCAD zu übertragen. Die AutoCAD-Layerliste sieht so aus: 0 0_GB_xyz... 0_GB_xyz...... 1_RA_xyz.. 0_GB_xyz... 2_ED_xyz.... ich vermute mal eine Reihenfolge, wie die Layer in AC erzeugt wurden. Genauso wird sie in MC eingelasen. MC setzt eine Zeichenfolge voran: 00000: 0 00001: 0_GB_x usw. Eine derartige Textdatei habe ich per LISP erzeugt und kann MC auch einlesen. Mein Problem ist es nun die komplette Text-Zeile nach der ersten AutoCAD-Zeichenfolge also "0_", "1_" usw. zu sortieren, die Zeichen "| " dem AutoCAD-Namen und eine Gruppen-Kopfzeile voranzustellen. Das Ergebnis sollte dann so aussehen: 00001: 0 00100: 0_GB_Gebäude 00001: | 0_GB_xyz... 00002: | 0_GB_xyz...... 00004: | 0_GB_xyz... 00102: 1_RA_Rohstoffannahme 00003: | 1_RA_xyz.. 00103: 2_ED_Einlagern und Dosieren 00005: | 2_ED_xyz.... Die von MC erzeugte und vorangestellte Zeichfolge muss bei dem zugehörigem Layernamen bleiben. Ich hoffe es ist verständlich ausgedrückt. Kann mir jemand so weit helfen, dass ich mit meinen beschränkten Mittel dies umsetzen kann?
------------------ strukturiertes Zeichnen mit Werner-Maahs Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
spider_dd Mitglied
Beiträge: 1111 Registriert: 27.11.2003 Win 10Pro Intel(R) Core(TM) i7-7700 NVIDIA Quadro P1000 ACAD, Civil-3D 2018
|
erstellt am: 15. Aug. 2017 14:52 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hallo Werner, so ganz kann ich noch nicht folgen, da ich nicht wirklich erkennen kann, wann Du welche Liste hast. Aber ich werfe mal den Lisp-Befehl vl-sort bzw. vl-sort-i in den Raum. Damit kannst Du Dir schon mal die ACAD-Layerliste sortieren bzw. indizieren und dann nachfolgend die neue Liste mit den zusätzlichen Einträgen basteln. HTH Thomas Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 15. Aug. 2017 15:43 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hallo Werner, ich habe mich mal probiert, sieht schlimmer aus als es ist, das Kernstück sind die zu Beginn definierten Listen AcList und McList. In der McList habe ich als 2. Element die Suchnummer für den AutoCAD-Layer eingetragen. Vielleicht kannst Du es ja verwenden, bei der Princ-Anweisung kann auch ein write-line verwendet werden, wenn es in eine Datei soll.
Code:
(defun JB_test:Praefix (str /) (while (< (strlen str) 5) (setq str (strcat "0" str)) ) str ) (defun c:test ( / ACLIST MCLIST N X Y) (setq AcList '("0" "0_GB_xyz1" "0_GB_xyz2" "1_RA_xyz1" "0_GB_xyz3" "2_ED_xyz1" ) McList '((100 0 "0_GB_Gebäude") (102 1 "1_RA_Rohstoffannahme") (103 2 "2_ED_Einlagern und Dosieren") ) ) ;;;Nummer aus Layer ziehen, z.B. ((0 "0_GB_Gebäude")... (setq acList (mapcar '(lambda (X) (if (vl-string-search "_" X) (list (atoi (substr X 1 (vl-string-search "_" X))) X) (list -1 X) ) ) acList ) ) (setq n 0)
(mapcar '(lambda (X) (princ (strcat "\n" X)) ;;;an dieser Stelle kann auch in Datei geschrieben werden ) (cons (strcat (JB_test:Praefix "1") ": 0") (apply 'append (mapcar '(lambda (X) (append (list (strcat (JB_test:Praefix (itoa (car X))) ": " (caddr X) ) ) (mapcar '(lambda (Y) (strcat (JB_test:Praefix (itoa (setq n (+ n 1)))) ": | " (cadr Y) ) ) ;;;alle Elemente aus AcList entfernen, die nicht der ;;;Suchnummer der Gruppe entsprechen (vl-remove-if '(lambda (Z) (/= (car Z) (cadr X))) acList ) ) ) ) McList ) ) ) ) (princ) )
Allerdings ist in der Unternummerierung ein Unterschied zu Deiner Nummerierung, mir ist aber auch nicht hundertprozentig klar, wie es wirklich sein soll. Nimm es es Gedankenansatz.
00001: 0 00100: 0_GB_Gebäude 00001: | 0_GB_xyz1 00002: | 0_GB_xyz2 00003: | 0_GB_xyz3 00102: 1_RA_Rohstoffannahme 00004: | 1_RA_xyz1 00103: 2_ED_Einlagern und Dosieren 00005: | 2_ED_xyz1 ------------------ viele Grüße Jörn http://www.bosse-engineering.com Liniensignaturen Youtube Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 15. Aug. 2017 16:23 <-- editieren / zitieren --> Unities abgeben:
Oh Ihr seid prima!!!! Ich kann die Routine von Björn erst morgen probieren, aber es liest sich schon mal toll. Nur zur Erklärung: Meine erste Liste sieht in so aus, wie ich sieh mit LISP aus AC herauslesen kann. Im Layer-Manager wird sie ja immer Alphabetisch sortiert, daher kann ich sie nicht einfach markieren und z.B. in EXCEL ergänzen und sortieren. MC liest die Layer-Liste vermutlich so aus, wie sie in der Zeichnungs-DB gespeichert wurde und auch durch auslesen mit LISP erzeugt wird. Filtereinstellungen werden von MC nicht übernommen. Ich kann aber in MC eine Layer-Struktur nachträglich per TXT-Datei einlesen und kann damit die Reihenfolge und auch Gruppierungen erzeugen. Eine Bedingung ist, dass die Layer-Namen identisch sind. Eine Gruppierung erreiche ich durch die Zeichen "| ", die ich dem Layer-Namen voranstelle. Einen Gruppierungskopf erzeuge ich, indem ich einen Layer, der nicht verwendet wurde nehme, benenne und der Gruppe vorstelle. Ich hoffe MegaCAD-Kenner werden mich nicht zerreißen. Habe nur MegaCAD-Kenntnisse durch spielen mit der 14-Tage-Testversion. Da ich an meiner Zeichnung arbeite und immer wieder einen Zwischenstand an dem MC-Mann geben muss, ist es ideal, wenn die Liste per LISP erstellt würde. ------------------ strukturiertes Zeichnen mit Werner-Maahs Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
spider_dd Mitglied
Beiträge: 1111 Registriert: 27.11.2003 Win 10Pro Intel(R) Core(TM) i7-7700 NVIDIA Quadro P1000 ACAD, Civil-3D 2018
|
erstellt am: 16. Aug. 2017 08:32 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hallo Werner, dann könnte vielleicht folgendes Vorgehen helfen: 1) Layernamenliste in ACAD erzeugen 2) mit vl-sort-i eine Indexliste der Layernamenliste erzeugen, für die spätere Reihenfolge. 3) den Layernamen in der Layernamenliste die MC-Zeichenfolge voranstellen 4) mit Hilfe der Indexliste eine neue Liste erzeugen, die die Layernamen mit MC-Vorsatz in der richtige Reihenfolge und die Gruppierungskopfdaten enthält. Wann ein neuer Gruppenkopf kommen muss, kannst Du ja über das entsprechende Zeichen im Layernamen mit MC-Vorsatz ermitteln. HTH Gruß Thomas Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 16. Aug. 2017 08:44 <-- editieren / zitieren --> Unities abgeben:
Hallo Björn, danke nochmals für Deinen Einsatz. Leider hattest Du recht, die MC-Nummerierung passt nicht zu den Layern. Was ja auch mein eigentliches Problem darstellt. Ich habe mal 2 Textdateien heruntergeladen die dieses Problem vielleicht verdeutlichen. Die erste Datei habe ich mit meiner schon vorhandenen Routine erstellt. Hier stimmt zwar die Zuordnung der MC-Nummerierung aber die Zeilen sind nicht sortiert und es sind keine Gruppenköpfe eingefügt. Die 2. Datei habe ich mit Deiner Routine geschrieben, in der ich nur das Auslesen der AC-Layerliste und das Schreiben in einer Datei geändert habe. Hier fehlen auch die Layer, die nicht in die Gruppen passen. Mein eigentliches Problem liegt darin, bei der Sortierung die MC-Nummerierung mitzunehmen! Mit meinem begrenzten LISP-Wissen bin ich aber nicht in der Lage Deine Routine so gut zu verstehen, dass ich diese sinnvoll anpassen kann. Vielleicht kannst Du mir noch einmal auf die Sprünge helfen wo was gemacht wird: Als Sortierungsgrundlage sollte eine Layerliste sein, in der AC und MC bereits vereint wurden. ------------------ strukturiertes Zeichnen mit Werner-Maahs [Diese Nachricht wurde von Werner-Maahs.de am 16. Aug. 2017 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 16. Aug. 2017 18:19 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hallo Werner, ich habe für die Layer, die nicht mit einer Nummer (die der Gruppe entspricht) und einem Unterstrich beginnt in der AcList eine Markierung mit -1 gesetzt. Dann kann als erstes die Liste mit allen Layern erstellt werden, bei denen durch die -1 kenntlich gemacht ist, daß es keine Gruppenlayer sind. Zur Erstellung der 2. Liste wird die McList durchlaufen, und zu jedem Gruppeneintrag werden die Layer mit der entsprechenden Suchnummer hinzugefügt. Die Nummerierung der Layer wird durch die Variable n gesteuert, bei den Haupteinträgen der Gruppe wird n nicht verwendet oder geändert. Ich habe noch ein paar Kommentarzeilen in den Code eingefügt, und den Code durch Verwendung von einzelnen Variablen für die verschiedenen Listen vielleicht etwas mehr Klarheit reingebracht, Du kannst es ja nochmal ausprobieren. Code:
(defun JB_test:Praefix (str /) (while (< (strlen str) 5) (setq str (strcat "0" str)) ) str )(defun c:test (/ ACLIST LISTMITGRUPPE LISTOHNEGRUPPE MCLIST N X Y) (setq AcList '("0" "0_GB_xyz1" "0_GB_xyz2" "1_RA_xyz1" "0_GB_xyz3" "2_ED_xyz1" "123" "willi" "otto" "99_layer1" "99_layer2" ) McList '( (100 0 "0_GB_Gebäude") (102 1 "1_RA_Rohstoffannahme") (103 2 "2_ED_Einlagern und Dosieren") (199 99 "99_Testlayer") ) ) ;;;Zähler, der nur für die Layer, nicht für die Gruppenzeilen verwendet wird (setq n 0) ;;;Nummer aus Layer ziehen, z.B. ((0 "0_GB_Gebäude")... ;;;wenn keine Nummer im Layer gefunden wird, dann -1 als Makierung (setq acList (mapcar '(lambda (X) (if (vl-string-search "_" X) (list (atoi (substr X 1 (vl-string-search "_" X))) X) (list -1 X) ) ) acList ) ) ;;;Liste ohne Gruppenzuordnung (alle Einträge mit -1 werden aus der ;;;AcList entfernt (setq ListOhneGruppe (mapcar '(lambda (X) (strcat (JB_test:Praefix (itoa (setq n (+ n 1)))) ": | " (cadr X) ) ) (vl-remove-if '(lambda (X) (/= (car X) -1)) acList) ) )
;;;Jetzt die McListe durchlaufen lassen, und pro Gruppe die ;;;zugehörigen ;;;Layer mit einfügen (setq ListMitGruppe (apply 'append (mapcar '(lambda (X) (append ;;;Hauptgruppen-Eintrag (list (strcat (JB_test:Praefix (itoa (car X))) ": " (caddr X) ) ) ;;;alle Layer, deren Gruppennummer aktuell ist (mapcar '(lambda (Y) (strcat (JB_test:Praefix (itoa (setq n (+ n 1))) ) ": | " (cadr Y) ) ) ;;;alle Elemente aus AcList entfernen, die nicht der ;;;Suchnummer der Gruppe entsprechen (vl-remove-if '(lambda (Z) (/= (car Z) (cadr X))) acList ) ) ) ) mcList ) ) ) ;;;Jetzt werden beide Liste mit Append zusammengefasst und ;;;in Schleife mit PRINC ausgegeben (mapcar '(lambda (X) (princ (strcat "\n" X)) ) (append ListOhneGruppe ListMitGruppe ) ) (princ) )
00001: | 0 00002: | 123 00003: | willi 00004: | otto 00100: 0_GB_Gebäude 00005: | 0_GB_xyz1 00006: | 0_GB_xyz2 00007: | 0_GB_xyz3 00102: 1_RA_Rohstoffannahme 00008: | 1_RA_xyz1 00103: 2_ED_Einlagern und Dosieren 00009: | 2_ED_xyz1 00199: 99_Testlayer 00010: | 99_layer1 00011: | 99_layer2 ------------------ viele Grüße Jörn http://www.bosse-engineering.com Liniensignaturen Youtube Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 16. Aug. 2017 21:20 <-- editieren / zitieren --> Unities abgeben:
WOW Mit dem '-1' habe ich auch noch erkannt. Aber im 2. Teil, wo Du diese herausgenommen hast, wollte ich eine extra Liste machen indem ich 'vl-remove' ersetze. Hat mich 6 Stunden unbezahlter Arbeit gekostet. Hat mich so was von gereizt, Deine Routine zu verstehen, aber ich bin vermutlich zu alt, um das mit 'lambda' und den X- Y- Z- zu verstehen. Es hat jedenfalls nicht geklappt Ich hoffe, ich kann Dir morgen wieder sagen es hat geklappt. Der MegaCAD-Mann fand meine vorherigen manuellen Bemühungen jedenfalls sehr hilfreich. Vielleicht hilft es ja auch anderen, die von AutoCAD etwas nach MegaCAD übergeben müssen. Bis Dato erst mal vielen vielen Dank. Werner Maahs ------------------ strukturiertes Zeichnen mit Werner-Maahs Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 21533 Registriert: 03.06.2002 Alles
|
erstellt am: 16. Aug. 2017 21:50 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hoffentlich nimmt dies jetzt niemand so genau unter die Lupe, aber mir würde es helfen auf diese Art der Erklärung: Lambda ist zu vergleichen mit defun, nur bei defun gibt man der Funktion einen Namen (defun MYFUNC (X)(apply 'strcat X)) (lambda (X)(alert X)) X ist ein Symbolname, könnte ebensogut MySymb genannt werden. Wie bei Defun dürfen es auch mehrere sein. Mit eingesprungenem Mapcar wäre es dann sowas in der Art: (Foreach Unterliste Gesamtliste (eval (cons 'MyFunc Unterliste)) ) Anstatt (mapcar '(lambda (Unterliste)(apply 'strcat Unterliste))Gesamtliste) Jetzt habe ich ein blödes Beispiel gewählt, denn das foreachBeispiel würde nichts produktives machen, die Mapcar variante würde jedoch eine Liste zurückliefern mit der man was anfangen könnte. Aber egal. (Setq Gesamtliste '(("12" "34")("56" "78"))) Der Profi beschreibt es so: http://www.autolisp.info/listen5.html ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 17. Aug. 2017 08:06 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hallo Werner, ich habe mal versucht Dir ein einfaches Beispiel zu geben, um die Funktionen MAPCAR und VL-REMOVE-IF näher zu beleuchten, und um auch die Nutzung der Rückgabe dieser Funktionen direkt zu nutzen. Ist aber nur schnell hingetippt, vielleicht hilft es, die anderen Info's dazu unter dem Link von cadffm Code:
(defun c:test (/ LISTE RETLISTMAPCAR RETVLREMOVELIST X) (setq liste '((1 . "wert1") (2 . "wert2") (3 . "wert3") (4 . "wert4") ) );;;Listenwerte als Rückgabewert einer Mapcar-Schleife (setq RetListMapcar (mapcar '(lambda (X) (cdr X);;;entspricht z.B. (cdr (1 . "wert1")) ) liste ) ) ;;;Liste RetListMapcar über PRINC in Befehlszeile, wieder in einer ;;;MAPCAR-Schleife, diesesmal wird aber der Rückgabewert nicht verwendet (princ "\nRückgabe aus der Variablen RetListMapcar:") (mapcar '(lambda (X) (princ (strcat "\n" X)) ) RetListMapcar ) ;;;die beiden Schleifen ineinander verschachtelt ohne zusätzliche Variablem (princ "\nRückgabe direkt aus der MAPCAR-Schleife:") (mapcar '(lambda (X) (princ (strcat "\n" X)) ) (mapcar 'cdr liste) ) ;;;wenn nur eine Funktion ohne Argument innerhalb ;;;von MAPCAR verwendet wird, dann kann diese direkt ohne "Lambda" verwendet ;;;werden. ;;;Mit vl-remove-if Listenelemente entfernen, die bestimmten Kriterien entsprechen (setq RetVlRemoveList (vl-remove-if '(lambda (X) (and (>= (car X) 2) (<= (car X) 3) ) ;;;wenn 1. wert größergleich 2 und kleinergleich3 ;;;dann, werden diese entfernt. ) liste ) ) ;;;Liste RetVlRemoveList über Mapcar-PRINT in Befehlszeile (princ "\nRückgabe aus der Variablen RetVlRemoveList:") (mapcar 'print RetVlRemoveList ) ;;;Ausgabe einer reduzierten Liste mit vl-remove-if, über mapcar 'cdr das ;;;2. Element
(princ "\nRückgabe reduzierte Liste:") (mapcar '(lambda (X) (princ (strcat "\n" X)) ) (mapcar 'cdr (vl-remove-if '(lambda (X) (and (>= (car X) 2) (<= (car X) 3) ) ) liste ) ) ) (princ) )
PS: um den Code zu erörtern öffne diesen bitte im VLIDE (falls Du es nicht schon machst), durch die Farblichen Hervorhebungen wird der Code viel einfacher lesbar und Du kannst Haltepunkte setzen und Dich Stück für Stück durch den Code bewegen und dabei die Variablen überwachen. http://www.bosse-engineering.com/JB_Data/Bosse-engineering/090501_VisualLISP-Editor.pdf
------------------ viele Grüße Jörn http://www.bosse-engineering.com Liniensignaturen Youtube Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 17. Aug. 2017 08:43 <-- editieren / zitieren --> Unities abgeben:
Hallo und vielen Dank auch an CADFFM. Zunächst: Es ist noch nicht das gewünschte Ergebnis. Die wichtigste Bedingung ist nicht erfüllt: Die Reihenfolge der MegaCAD-Zeichenfolge passt nicht zu den AutoCAD-Layernamen. Ich erzeuge eine AC-Layerliste mit Code: (while (setq row (tblenext "Layer" f)) (setq f nil) (setq AcList (cons ( cdr (assoc 2 row)) AcList)) )
So wie es scheint liest auch MegaCAD die Layer so aus und setzt ihre eigene fortlaufende Zeichenfolge davor. Diese Zuordnung muss auch bei der Sortierung bestehen bleiben. Alles andere ist für mich zwar schwierig zu lesen aber liest sich toll. Ich versuche jetzt die AC-Liste zuerst um die MC-Zeichenfolge mit meinen Mitteln zu ergänzen und dann diesen Teil aus Björns Routine zu entfernen. Bin gespannt ob ich es schaffe. Die Erklärungen zu Lambda usw. habe ich u.a. auch aus dem 'Kochbuch'. Aber nur lesen reicht da wohl nicht. Ich muss es Punkt für Punkt erarbeiten. Und mit der Zeit würde ich es wohl auch hinbekommen. Nur schreibe ich zu selten LISP-Routinen um es zu verinnerlichen. Meine bisherigen sehen so aus wie der obige Ausschnitt. Vermutlich für die Profis allenfalls zum schmunzeln. Für mich war es bisher ausreichend. Werner Maahs ------------------ strukturiertes Zeichnen mit Werner-Maahs Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
spider_dd Mitglied
Beiträge: 1111 Registriert: 27.11.2003 Win 10Pro Intel(R) Core(TM) i7-7700 NVIDIA Quadro P1000 ACAD, Civil-3D 2018
|
erstellt am: 17. Aug. 2017 09:41 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Ich habe mal in Jörns Lisp die Nummernzuweisung zu den Layer etwas vorgezogen. Passt das Ergebnis jetzt? Code:
(defun JB_test:Praefix (str /) (while (< (strlen str) 5) (setq str (strcat "0" str)) ) str )(defun c:test (/ ACLIST LISTMITGRUPPE LISTOHNEGRUPPE MCLIST N X Y) (setq AcList '("0" "0_GB_xyz1" "0_GB_xyz2" "1_RA_xyz1" "0_GB_xyz3" "2_ED_xyz1" "123" "willi" "otto" "99_layer1" "99_layer2" ) McList '( (100 0 "0_GB_Gebäude") (102 1 "1_RA_Rohstoffannahme") (103 2 "2_ED_Einlagern und Dosieren") (199 99 "99_Testlayer") ) ) ;;;Zähler, der nur für die Layer, nicht für die Gruppenzeilen verwendet wird (setq n 0) ;;;Nummer aus Layer ziehen, z.B. ((0 "0_GB_Gebäude")... ;;;wenn keine Nummer im Layer gefunden wird, dann -1 als Makierung ;;; und den Layernamen schon den Praefix mitgeben (spider_dd) (setq acList (mapcar '(lambda (X) (if (vl-string-search "_" X) (list (atoi (substr X 1 (vl-string-search "_" X))) (strcat (JB_test:Praefix (itoa (setq n (+ n 1)))) ": | " X) ) (list -1 (strcat (JB_test:Praefix (itoa (setq n (+ n 1)))) ": | " X)) ) ) acList ) )
;;;Liste ohne Gruppenzuordnung (alle Einträge mit -1 werden aus der ;;;AcList entfernt (setq ListOhneGruppe (mapcar '(lambda (X) ; (strcat (JB_test:Praefix (itoa (setq n (+ n 1)))) ;; auskommentiert (spider_dd) ; ": | " ;; auskommentiert (spider_dd) (cadr X) ; ) ;; auskommentiert (spider_dd) ) (vl-remove-if '(lambda (X) (/= (car X) -1)) acList) ) ) ;;;Jetzt die McListe durchlaufen lassen, und pro Gruppe die ;;;zugehörigen ;;;Layer mit einfügen (setq ListMitGruppe (apply 'append (mapcar '(lambda (X) (append ;;;Hauptgruppen-Eintrag (list (strcat (JB_test:Praefix (itoa (car X))) ": " (caddr X) ) ) ;;;alle Layer, deren Gruppennummer aktuell ist (mapcar '(lambda (Y) ; (strcat (JB_test:Praefix ;; auskommentiert (spider_dd) ; (itoa (setq n (+ n 1))) ;; auskommentiert (spider_dd) ; ) ; ": | " ;; auskommentiert (spider_dd) (cadr Y) ; ) ;; auskommentiert (spider_dd) ) ;;;alle Elemente aus AcList entfernen, die nicht der ;;;Suchnummer der Gruppe entsprechen (vl-remove-if '(lambda (Z) (/= (car Z) (cadr X))) acList ) ) ) ) mcList ) ) ) ;;;Jetzt werden beide Liste mit Append zusammengefasst und ;;;in Schleife mit PRINC ausgegeben (mapcar '(lambda (X) (princ (strcat "\n" X)) ) (append ListOhneGruppe ListMitGruppe ) ) (princ) )
00001: | 0 00007: | 123 00008: | willi 00009: | otto 00100: 0_GB_Gebäude 00002: | 0_GB_xyz1 00003: | 0_GB_xyz2 00005: | 0_GB_xyz3 00102: 1_RA_Rohstoffannahme 00004: | 1_RA_xyz1 00103: 2_ED_Einlagern und Dosieren 00006: | 2_ED_xyz1 00199: 99_Testlayer 00010: | 99_layer1 00011: | 99_layer2 Gruß Thomas Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 17. Aug. 2017 17:36 <-- editieren / zitieren --> Unities abgeben:
ups, schon wieder eine Lösung! Danke, werde ich morgen probieren. Ich habe es aufgegeben! Nach fast 3 Stunden herumprobieren habe ich, mit meinen bisherigen Kenntnissen (vielleicht fortgeschrittener Anfänger) und einem Teil von Jörns Codezeilen, meine frühere Version bearbeitet. Das Ergebnis ist befriedigend. Muss noch einen Weg finden, um die Liste zeilenweise als eine Textdatei zu drucken. Ist sicherlich nicht das, wie Ihr Euch eine Lisp-Datei vorstellt, aber Sie funktioniert. ------------------ strukturiertes Zeichnen mit Werner-Maahs Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 18. Aug. 2017 06:52 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hallo Werner, das sieht doch gut aus (habe aber nur kurz rübergeschaut). Finde ich jedenfalls gut, daß Du Dir Deine eigenen Gedanken machst anstatt nur Copy'nPaste zu verwenden. Und um Deine Zeilen zu "WRITEN" komme ich wieder mit einen MAPCAR-Vorschlag um die Ecke;-)
Code:
(mapcar '(lambda(X)(write-line X file))ls)
Damit müßte Deine Liste LS zeilenweise in die Datei geschrieben werden. ------------------ viele Grüße Jörn http://www.bosse-engineering.com Liniensignaturen Youtube Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 18. Aug. 2017 08:53 <-- editieren / zitieren --> Unities abgeben:
Danke , für die 'writen'-Zeile, wäre ich nie drauf gekommen. Genauso für den Prefix-defun. Hatte es früher sehr umständlich gelöst und Deines ist so elegant und einfach nachvollziehbar. Aber bitte erkläre mir, wofür steht das (X) in der lambda-Funktion? Ich habe doch X nicht definiert. Wenn lambda eine namenlose (defun-)Funktion ist, dann steht in der ersten Klammer vor einem möglichen Schrägstrich eine Variable die mit dem Funktionsaufruf übergeben werden muss !?. ------------------ strukturiertes Zeichnen mit Werner-Maahs Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 18. Aug. 2017 09:37 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
|
cadffm Moderator 良い精神
Beiträge: 21533 Registriert: 03.06.2002 Alles
|
erstellt am: 18. Aug. 2017 09:57 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
"Wenn lambda eine namenlose (defun-)Funktion ist, dann steht in der ersten Klammer vor einem möglichen Schrägstrich eine Variable die mit dem Funktionsaufruf übergeben werden muss !?."GENAU SO! Und Mapcar ist in dem Moment derjenige der ein Listenelement nacheinander an die Funktion übergibt, egal ob es eine benannte oder unbenannte ist. Code: (progn (setq LISTE '("A" "B" "C")) ; mapcar/lambda - keine gespeicherte/benannte Funktion (alert (vl-princ-to-string (mapcar '(lambda(Zeichen)(strcat "1=" Zeichen)) Liste) ) ) ; benannte Funktion erstellen, sollte diese Funktion aber nur einmal benötigt werden: ; Wozu speichern, das ist Verschwendung (defun testfun (Zeichen) (strcat "2=" Zeichen) ) (alert (vl-princ-to-string (mapcar 'testfun Liste) ) ) )
------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 823 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 18. Aug. 2017 13:43 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Zitat: Original erstellt von cadffm: [i]"Wenn lambda eine namenlose (defun-)Funktion ist, dann steht in der ersten Klammer vor einem möglichen Schrägstrich eine Variable die mit dem Funktionsaufruf übergeben werden muss !?."GENAU SO! Und Mapcar ist in dem Moment derjenige der ein Listenelement nacheinander an die Funktion übergibt, egal ob es eine benannte oder unbenannte ist. [/i]
Noch etwas genauer: DEFUN macht nichts anderes, als via LAMBDA eine Funktion zu definieren und diese an ein Symbol zu binden. Statt (defun fun1 () ...) kann man also auch genau so gut schreiben (setq fun1 (lambda () ...)). Man beachte, dass das LAMDA-Konstrukt hier nicht gequotet ist! Das LAMBDA Konstrukt ist also keineswegs nur eine unbenannte DEFUN-Funktion, sondern es ist genau anders herum: DEFUN ist ein an ein Symbol gebundenes LAMBDA-Konstrukt. Das LAMBDA Kalkül steht im Zentrum von Lisp. Und MAPCAR übergibt nacheinander ein oder mehrere Listenelemente an die genannte Funktion. Das Symbol, an das die Funktion gebunden ist, wird bei jedem Aufruf neu evaluiert (damit sie sich Lisp-gemäß selbst verändern kann!), und muss deshalb gequoted an MAPCAR übergeben werden: (defun fun1 (lst) (car lst)) FUN1 _$ (setq fun2 (lambda (lst) (car lst))) #<USUBR @0000000032004368 -lambda-> _$ (setq fun3 '(lambda (lst) (car lst))) (LAMBDA (LST) (CAR LST)) _$ (setq lst '(A 1) (B 2) (C 3) (D 4)) _$ (mapcar 'car lst (_> ) nil _$ (setq lst '(A 1) (B 2) (C 3) (D 4)) _$ lst nil _$ (setq lst '((A 1) (B 2) (C 3) (D 4))) ((A 1) (B 2) (C 3) (D 4)) _$ (mapcar 'car lst) (A B C D) _$ (mapcar 'fun1 lst) (A B C D) _$ (mapcar 'fun2 lst) (A B C D) _$ (mapcar 'fun3 lst) ; error: bad function: (LAMBDA (LST) (CAR LST)) _$ (mapcar fun3 lst) (A B C D) _$ In Visual Lisp werden LAMBDA (und damit auch DEFUN) Konstrukte nicht mehr im Quellcode immer wieder neu komplett interpretiert, sondern werden in einen Bytecode übersetzt, was den Ablauf deutlich beschleunigt. Der Interpreter kann dann auch noch zusätzliche Optimierungs- und Debuggingaufgaben übernehmen. Um alle Optimierungsmöglichkeiten auszuschöpfen, sollte man das LAMBDA Konstrukt nicht einfach gequoted an MAPCAR übergeben (also z.B. (mapcar (quote (lambda () ...))) lst) oder (mapcar '(lambda () ...)) lst)), sondern mit der speziellen Quotierung mit der Funktion FUNCTION: (mapcar (function (lambda () ...))) lst)
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 18. Aug. 2017 14:41 <-- editieren / zitieren --> Unities abgeben:
Vielen Dank Euch allen! Meine Routine hat gut funktioniert und ist aufgrund meines Wissenstandes für mich einfacher nach zu vollziehen. Trotzdem komme ich wohl nicht umhin mich mehr mit 'mapcar' und 'lambda' ausein ander zu setzen. Dafür habe ich ja zu euren Infos auch noch das 'Kochbuch'. Die oben angegebenen Links sind/waren so weit ich mich erinnern kann Basis für das Kochbuch. Oder handelt es sich dabei um eine Kurzfassung? Zu meiner Aufgabenstellung: Ich habe mich das ein wenig versehen. Wenn jemand etwas ähnliches vor hat, dann muss er das Zeichen "| " vor der Zahl setzen, damit sich eine Gruppierung in MegaCAD ergibt. Beipsiel: "00001: AutoCAD-Layername" -> normale Bezeichnung "| 00002: AutoCAD-Layername" -> als Untergruppe Eine Zusatzfrage habe ich dann aber doch noch! Kann ich einen eingestellten Layerfilter herauslesen ohne alzu tief in die Materie einsteigen zu müssen? ------------------ strukturiertes Zeichnen mit Werner-Maahs Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 18. Aug. 2017 17:34 <-- editieren / zitieren --> Unities abgeben: Nur für Werner-Maahs.de
Hallo Werner, Zitat:
Kann ich einen eingestellten Layerfilter herauslesen ohne alzu tief in die Materie einsteigen zu müssen?
Da müßtest Du Dir die Grundlagen von Dictionary's erarbeiten, und das sehe ich schon als tiefes Einsteigen in die Materie an. Über das Dictionary "ACAD_LAYERFILTERS" können alle Layerfilter ausgelesen werden, über das Dictionary "ACLYDICTIONARY" alle Gruppenfilter. Mit diesen Stichworten sollte Dich GOOGLE vielleicht auch schon weiterbringen, es gibt eine Menge Beiträge dazu. ------------------ viele Grüße Jörn http://www.bosse-engineering.com Liniensignaturen Youtube Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Werner-Maahs.de Mitglied CAD-Dozent + Konstrukteur + Autor
Beiträge: 626 Registriert: 04.05.2005 Win XP AC 2005/6 Manchmal AC 2011
|
erstellt am: 18. Aug. 2017 19:57 <-- editieren / zitieren --> Unities abgeben:
|