Hot News:

Mit Unterstützung durch:

  Foren auf CAD.de (alle Foren)
  Lisp
  Schneller Excel lesen und daraus Liste erstellen

Antwort erstellen  Neues Thema erstellen
CAD.de Login | Logout | Profil | Profil bearbeiten | Registrieren | Voreinstellungen | Hilfe | Suchen

Anzeige:

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen nächster neuer Beitrag | nächster älterer Beitrag
  
Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte
Autor Thema:  Schneller Excel lesen und daraus Liste erstellen (813 mal gelesen)
Archäologie Bubi
Mitglied
Archäologische Funddokumentation


Sehen Sie sich das Profil von Archäologie Bubi an!   Senden Sie eine Private Message an Archäologie Bubi  Schreiben Sie einen Gästebucheintrag für Archäologie Bubi

Beiträge: 38
Registriert: 09.03.2021

AutoCAD Map 3D 2013
AutoCAD Map 3D 2023
Faro AS-Built / TachyCAD
BricsCAD V18
Elcovision ElTheo
Agisoft Metashape Professional

erstellt am: 24. Nov. 2021 15:50    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

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


Sehen Sie sich das Profil von joern bosse an!   Senden Sie eine Private Message an joern bosse  Schreiben Sie einen Gästebucheintrag für joern bosse

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: 24. Nov. 2021 17:04    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Archäologie Bubi 10 Unities + Antwort hilfreich

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


Sehen Sie sich das Profil von Archäologie Bubi an!   Senden Sie eine Private Message an Archäologie Bubi  Schreiben Sie einen Gästebucheintrag für Archäologie Bubi

Beiträge: 38
Registriert: 09.03.2021

erstellt am: 25. Nov. 2021 08:52    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

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


Sehen Sie sich das Profil von joern bosse an!   Senden Sie eine Private Message an joern bosse  Schreiben Sie einen Gästebucheintrag für joern bosse

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: 25. Nov. 2021 09:17    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Archäologie Bubi 10 Unities + Antwort hilfreich

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

Archäologie Bubi
Mitglied
Archäologische Funddokumentation


Sehen Sie sich das Profil von Archäologie Bubi an!   Senden Sie eine Private Message an Archäologie Bubi  Schreiben Sie einen Gästebucheintrag für Archäologie Bubi

Beiträge: 38
Registriert: 09.03.2021

erstellt am: 25. Nov. 2021 10:51    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

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

Anzeige.:

Anzeige: (Infos zum Werbeplatz >>)

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen

nächster neuerer Beitrag | nächster älterer Beitrag
Antwort erstellen


Diesen Beitrag mit Lesezeichen versehen ... | Nach anderen Beiträgen suchen | CAD.de-Newsletter

Administrative Optionen: Beitrag schliessen | Archivieren/Bewegen | Beitrag melden!

Fragen und Anregungen: Kritik-Forum | Neues aus der Community: Community-Forum

(c)2023 CAD.de | Impressum | Datenschutz