| |
 | 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: Schneller Excel lesen und daraus Liste erstellen (1366 / mal gelesen)
|
Archäologie Bubi Mitglied Archäologische Funddokumentation

 Beiträge: 68 Registriert: 09.03.2021 AutoCAD Map 3D 2024 / Raster Design AutoCAD Map 3D 2025 Faro AS-Built / TachyCAD Agisoft Metashape Professional 2.0
|
erstellt am: 24. Nov. 2021 15:50 <-- editieren / zitieren --> Unities abgeben:         
Hallo Forum Situation: Ich habe für meinen Betrieb ein LISP geschrieben, welches Informationen aus AutoCAD und einer Excel nimmt, sie verarbeitet und sie anschliessend zusammengefasst in einen Block und ebenfalls auch wider in die Excel schreibt. Für das Lesen der Excel habe ich mich an den Funktionen von GetExcel.lsp (https://autolisp-exchange.com) von Terry Miller und Gilles Chanteau bedient und diese leicht an unsere Bedürfnisse angepasst. Diese liest, bist zur letzten Zeile mit Inhalt, alle Zeilen durch und erstellt daraus eine verschachtelte Liste mit den Zelleninhalten. So weit so gut, so weit so Funktional. Problem: Solange die Excel nicht sehr lange ist (unter 100 Zeilen), wird die Liste innerhalb von einigen wenigen Sekunden erstellt. Wird die Excel nun aber länger (die Excel's können an die Tausend Zeilen lang sein), dann dauert das erstellen der Liste bis zu zwei Minuten. Frage: Auch wenn dies "Theoretisch" nur ein Schönheitsfehler ist, kann man das Lesen der Excel und/oder das Schreiben der Liste beschleunigen? Code: Hier noch den Schnipsel, der bei mir die Excel liest und die Liste schreibt: Code: (defun GetExData ( / CurRegion MaxRow MaxColumn Row Data Column ExValue ) (if ExSheet (vlax-for Worksheet (vlax-get-property ExApp "Sheets") (if (= (vlax-get-property Worksheet "Name") ExSheet) (vlax-invoke-method Worksheet "Activate") );end if );end vlax-for );end if (setq CurRegion (vlax-get-property (vlax-get-property (vlax-get-property ExApp "ActiveSheet") "Range" "A1" );end vlax-get-property "CurrentRegion" );end vlax-get-property );end setq (setq MaxRow (vlax-get-property (vlax-get-property CurRegion "Rows") "Count")) (setq MaxColumn (vlax-get-property (vlax-get-property CurRegion "Columns") "Count")) (setq Row 1) (repeat MaxRow (setq Data nil) (setq Column 1) (repeat MaxColumn (setq ExValue (vlax-variant-value (vlax-get-property (vlax-get-property ExApp "Range" (strcat (Number2Alpha Column)(itoa Row)) );end vlax-get-property 'Value );end vlax-get-property );end vlax-variant-value );end setq (setq ExValue (cond ((= (type ExValue) 'INT)(itoa ExValue)) ((= (type ExValue) 'REAL)(rtosr ExValue)) ((= (type ExValue) 'STR)(vl-string-trim " " ExValue)) ((/= (type ExValue) 'STR) "") );end cond );end setq (setq Data (append Data (list ExValue))) (setq Column (1+ Column)) );end repeat (setq ExData (append ExData (list Data))) (setq Row (1+ Row)) );end repeat );end defun (defun Number2Alpha ( Num / Val ) (if (< Num 27) (chr (+ 64 Num)) (if (= 0 (setq Val (rem Num 26))) (strcat (Number2Alpha (1- (/ Num 26))) "Z") (strcat (Number2Alpha (/ Num 26))(chr (+ 64 Val))) );end if );end if );end defun (defun rtosr (RealNum / DimZin ShortReal) (setq DimZin (getvar "DIMZIN")) (setvar "DIMZIN" 8) (setq ShortReal (rtos RealNum 2 8)) (setvar "DIMZIN" DimZin) ShortReal );end defun
Tipps oder Lösungen natürlich immer gern gesehen.
Besten Dank im Voraus Fabian ------------------ ___________________________________________ Bubi spiele, Bubi glücklich! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
    
 Beiträge: 1776 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 24. Nov. 2021 17:04 <-- editieren / zitieren --> Unities abgeben:          Nur für Archäologie Bubi
Hallo Fabian, vielleicht geht es schneller, wenn Du das ganze Tabellenblatt über die Funktion "UsedRange" liest. Im folgenden ein Codeschnipsel, es benötigt ein SheetObjekt eines geöffneten Excel-Objektes "ExcelWorkbook " und gibt eine Liste zurück, in der die Zeilen mit den Werten enthalten sind (wenn leere Zellen, dann NIL) Code:
(setq Sheets (vlax-get-property ExcelWorkbook 'Sheets)) (setq sheet (vlax-get-property Sheets 'Item "MeinTabellenblatt")) (setq ExcelSheetList (mapcar '(lambda(X) (mapcar 'vlax-variant-value X) ) (vlax-safearray->list (vlax-variant-value (vlax-get-property (vlax-get-property sheet 'UsedRange) 'Value) ) ) ) )
Das kannst Du ja mal ausprobieren, vielleicht ist es hilfreich. ------------------ viele Grüße Jörn http://www.bosse-engineering.com Bosse_tools-Überblick Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Archäologie Bubi Mitglied Archäologische Funddokumentation

 Beiträge: 68 Registriert: 09.03.2021 AutoCAD Map 3D 2024 / Raster Design AutoCAD Map 3D 2025 Faro AS-Built / TachyCAD Agisoft Metashape Professional 2.0
|
erstellt am: 25. Nov. 2021 08:52 <-- editieren / zitieren --> Unities abgeben:         
Guten Morgen Jörn Für die Geschwindigkeit ist dein Schnipsel sogar sehr Hilfreich! Vielen Dank schonmal dafür. Ich hätte aber gleich noch zwei weitere Fragen basierend auf deiner Antwort: 1. Es scheint als wäre meine UsedRange viel grösser als ich sie eigentlich nutze. Um Fehler und Leistung zu verringern, könnte man die UsedRange auch über den Code resetten oder geht das nur Manuel? 2. Wäre es auch möglich die nil Einträge direkt beim erstellen durch "" zu ersetzten? Oder geht das nur im Nachhinein mit z.B.:
Code: (setq Num -1) (foreach lst ExData (setq Num (1+ Num)) (setq ExData (LM:SubstNth (subst "" 'nil lst) Num ExData)) );end foreach
Wenn ich sie nicht ersetzte, dann wird am Ende nil Wörtlich in die Excel geschrieben. Besten Dank und einen Schönen Tag Fabian ------------------ ___________________________________________ Bubi spiele, Bubi glücklich! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
    
 Beiträge: 1776 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 25. Nov. 2021 09:17 <-- editieren / zitieren --> Unities abgeben:          Nur für Archäologie Bubi
Hallo Fabian, auf den "UsedRange" hast Du so wohl keine Einfluß, da must Du nehmen, was die Funktion zurückgibt (glaube ich), aber Du kannst die NIL's auch durch eine weitere MAPCAR-Schleife gleich in "" ändern: Code:
(setq ExcelSheetList (mapcar '(lambda(X) (mapcar '(lambda(Y) (if Y Y "")) (mapcar 'vlax-variant-value X) ) ) (vlax-safearray->list (vlax-variant-value (vlax-get-property (vlax-get-property sheet 'UsedRange) 'Value) ) ) ) )
Für die reine LISP-Auswertung ist das nicht notwendig, weil NIL ja auch eine gültige Information ist, aber für das zurückschreiben in Excel ist tauschen sicherlich hilfreich. ------------------ viele Grüße Jörn http://www.bosse-engineering.com Bosse_tools-Überblick [Diese Nachricht wurde von joern bosse am 25. Nov. 2021 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |

| Anzeige: | Infos zum Werbeplatz >> | isaleCAD CAD APP für Tiefbau, Umwelt Since 1985, AnkiSOFT Software developes software to design infrastructure projects.
isaleCAD has been developed for Water Transmission Line Design. It is for Drawing / Modelling / Planning / Design / Analyze the water transmission line.
The software works under AutoCAD or ZWCAD.
|
|
Archäologie Bubi Mitglied Archäologische Funddokumentation

 Beiträge: 68 Registriert: 09.03.2021 AutoCAD Map 3D 2024 / Raster Design AutoCAD Map 3D 2025 Faro AS-Built / TachyCAD Agisoft Metashape Professional 2.0
|
erstellt am: 25. Nov. 2021 10:51 <-- editieren / zitieren --> Unities abgeben:         
Ich bin absolut Fasziniert und Begeistert! Darum Nochmals vielen Dank Jörn. Zum Resett von der UsedRange habe ich auch nur VBA Beiträge gefunden, ABER: Ich habe die UsedRange nochmals mit der CurrentRegion begrenz. Somit werden wirklich nur die Zeilen, bis zur letzten Zeile mit Inhalt, gelistet und das innerhalb von einer Sekunde. Code: (defun GetExData ( / ) (if ExSheet (vlax-for Sheet (vlax-get-property ExApp "Sheets") (if (= (vlax-get-property Sheet "Name") ExSheet) (vlax-invoke-method Sheet "Activate") );end if );end vlax-for );end if (setq ExData (mapcar '(lambda (X) (mapcar '(lambda (Y) (if Y Y "") );end lambda (mapcar 'vlax-variant-value X) );end mapcar );end lambda (vlax-safearray->list (vlax-variant-value (vlax-get-property (vlax-get-property (vlax-get-property (vlax-get-property ExApp "ActiveSheet") "UsedRange" );end vlax-get-property "CurrentRegion" );end vlax-get-property "Value" );end vlax-get-property );end vlax-get-variant );end vlax-safearryx->list );end mapcar );end setq );end defun
Besten Dank für die schnelle und zuverlässige Hilfe. Das Forum ist wirklich super. Schönen Tag Fabian (Edit: An die Mods: Woran liegt es, dass meine Themen nicht als gelöst gekennzeichnet werden, wenn ich auf das 10Units + Haken klicke? Die Units werden aber überwiesen.) ------------------ ___________________________________________ Bubi spiele, Bubi glücklich! [Diese Nachricht wurde von Archäologie Bubi am 25. Nov. 2021 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |