| |
| 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: Geschwindigkeit mit ActiveX (1634 mal gelesen)
|
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 21. Apr. 2006 13:17 <-- editieren / zitieren --> Unities abgeben:
Hallo! Ich habe gestern ein Programm mit der Funktion mx:get-excel-contents von CADchup (leicht angepasst) geschrieben (siehe hier). Es klappt echt super. Allerdings musste ich feststellen, dass die Geschwindigkeit nicht sonderlich berauschend ist. Ich lese 70 Spalten ein. Wenn ich 10 Zeilen (700 Werte) einlese dauert das ganze ca. 7 Sekunden (Armbanduhr) . Wenn ich 100 Zeilen (7000 Werte) einlese dauert es schon 103 Sekunden . Ich traue mich gar nicht alle 1126 Zeilen einlesen zu lassen. Und es werden vielleicht auch noch mehr. Ich hatte zwei Ideen, mit denen ich das Problem bekämpfen könnte: 1. Ich könnte Excel veranlassen, die Daten in eine temporäre Ascii-Datei zu schreiben und diese dann einlesen und 2. ich könnte die Daten Häppchenweise einlesen (ca. 5 bis 10 zeilen auf einmal) Bevor ich mich aber in wilde Abenteuer stürze und rumprobiere, wollte ich fragen, ob jemand schon Erfahrung mit diesen Wegen gemacht hat. Kann ich mein Ziel (viel) Zeit zu sparen dadurch erreichen? Oder soll ich dem User es zumuten zwischendurch Kaffee zu trinken oder zu (ich mag keinen Kaffee und rauchen tue ich auch nicht). Schöne Grüße, Stefan [Diese Nachricht wurde von s.wickel am 21. Apr. 2006 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13529 Registriert: 30.11.2003 .
|
erstellt am: 21. Apr. 2006 13:23 <-- editieren / zitieren --> Unities abgeben: Nur für s.wickel
Cadchups Funktion is allincusive für alle Zellen .. wenn du mehrere auf einmal einlesen willst, reicht es, den ganzen Initialisierungskram nur einmal aufzurufen, das spart zeit. also, dass: (setq excel (vlax-get-object "Excel.Application")) (vl-catch-all-error-p (setq zellen (vl-catch-all-apply 'vlax-get-property (list (vlax-get-property (vlax-get-property excel "ActiveWorkbook" ) "ActiveSheet" ) "Cells" ) ) ) ) bloß eimal am Anfang! ------------------ - Thomas - "Bei 99% aller Probleme ist die umfassende Beschreibung des Problems bereits mehr als die Hälfte der Lösung desselben." Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4189 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 21. Apr. 2006 13:44 <-- editieren / zitieren --> Unities abgeben: Nur für s.wickel
Hallo Stefan, das hast du richtig festgestellt. Der Zugriff auf Excel via ActiveX ist seeeehr langasam. Weshalb ich nach wie vor empfehle die Daten, sofern diese nicht minütliche Änderungen erfahren als TAB-getrennte ASCII-Datei zu speichern. Diese ist innerhalb kürzester Zeit mit Lisp eingelesen und sortiert. Grüße Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 21. Apr. 2006 13:54 <-- editieren / zitieren --> Unities abgeben:
|
Ex-Mitglied | |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 24. Apr. 2006 07:50 <-- editieren / zitieren --> Unities abgeben:
Hallo Rabbit007! Ich habe mir nicht die mühe gemacht, eine Stopuhr zu basteln, eine Armbanduhr hat mir vollkommen gereicht. Die hat nur einen Sekundenzeiger . Ich habe keinen eigenen Code geschrieben, weil ich mir die Zeit nicht nehmen wollte. Deshalb habe ich den Code von CADchup verwendet. Doch es scheint ja einen schnelleren Weg zu geben. Deshalb werde ich mich auch dran machen, einen eigenen Code zu produzieren. Diesmal vielleicht mit Stopuhr. Und dann werde ich das ganze vielleicht noch auf ACCESS übertragen. Dann bin ich glücklich. Schönen Montag, Stefan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 24. Apr. 2006 11:04 <-- editieren / zitieren --> Unities abgeben:
Hallo Rabbit! Ich habe es mal statt mit MAPCAR mit zwei Foreach-Schleifen probiert. Das zeitliche Ergebnis (diesmal mit Stoppuhr) kommt ungefähr auf's gleiche raus. Zwanzig Zeilen mit je 70 Werten = 14 Sekunden. Eindeutig zuviel. Hier mein Testcode: Code: (defun xldaten ( zeilen spalten ) (setq excel (vlax-get-object "Excel.Application")) (setq activeworkbook (vlax-get-property Excel "Activeworkbook")) (setq activesheet (vlax-get-property activeworkbook "Activesheet")) (setq cells (vlax-get-property activesheet "Cells")) (foreach zeile Zeilen (foreach spalte spalten (setq ergeb (cons (vlax-variant-value (vlax-get-property (vlax-variant-value (vlax-get-property cells 'Item zeile spalte) ) 'Text ) ) ergeb );cons );setq ergeb );foreach spalte (setq ergebnisse (cons ergeb ergebnisse)) );foreach spalte ) ;Aufruf mit: (xldaten '(2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) '(1 2 3 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151))
Dauer: 14 Sekunden. Eindeutig zu lang. Vielleicht findest du ja eine Stelle die mich bremst. Gruß, Stefan
[Diese Nachricht wurde von s.wickel am 24. Apr. 2006 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied | |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 25. Apr. 2006 07:57 <-- editieren / zitieren --> Unities abgeben:
Kaum zu glauben, aber wahr: heute morgen betrug meine Zeit 4,25 Sekunden wenn alle Zellen gefüllt sind und 3,11 Sekunden wenn nur drei Spalten gefüllt sind. Wahnsinn. Vielleicht liegt es daran, wieviele Programme geöffnet sind. Außerdem hatte ich sonst immer noch mehrere Exceltabelle geöffnet. Ich werde noch mehr Versuche in verschiedenen Lebenslagen anstellen und vielleicht darüber berichten. Danke für die Mithilfe Stefan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 25. Apr. 2006 08:54 <-- editieren / zitieren --> Unities abgeben:
Ich habe jetzt noch etwas rumprobiert. Es dauert zwar nicht mehr so lange wie anfangs, ist aber immer noch nicht das wahre. Aber die ASCII-Lösung ist auch nicht wirklich gut. Ich habe jetzt einfach einen Fortschrittsbalken mit eingebaut, der das Warten erträglicher macht (weil man sieht, dass etwas passiert). (Funktion dos_progbar aus DOSLIB) Danke für eure Mithilfe, das Programm wird jetzt nur noch verfeinert (was nichts direkt mehr mit LISP zu tun hat) und geht dann an die Kollegen. Stefan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied | |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 25. Apr. 2006 09:06 <-- editieren / zitieren --> Unities abgeben:
Steh ich mir jetzt auf dem Schlauch? Meinst du die Codezeilen zum ermitteln der letzten Spalte und Zeile? Das brauche ich nicht, da ich genau weiß, welche Spalten gefüllt sind und der Benutzer die Zeilen vorgibt (Die Daten stammen aus einer Datenbank). Ansonsten wüsste ich nicht, was du meinst (den anderen Beitrag habe ich intensiv verfolgt und er hat mir erst Mut gemacht, dieses Programm zu schreiben). Stefan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied | |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 25. Apr. 2006 11:07 <-- editieren / zitieren --> Unities abgeben:
Schnell, sehr schnell! So stelle ich mir das vor. Aber wie machst du das jetzt? Also: Objekt initialisieren: (setq excel (vlax-get-object "Excel.Application")) (setq activeworkbook (vlax-get-property Excel "Activeworkbook")) (setq activesheet (vlax-get-property activeworkbook "Activesheet")) (setq cells (vlax-get-property activesheet "Cells")) ob Activesheet oder Tabelle1 ist egal (ich hab's ausprobiert). Dann habe ich eine foreach-Schleife über alle Zeilen (die als Liste übergeben wurden) und eine foreach-schleife über die Spalten. Ich sammle die Ergebnisse jeder Zeile in einer Liste (mit cons zusammengefügt) und drehe die fertige Liste um. Diese Listen sammle ich wiederum in einer Liste, die ich am Ende wieder mit reverse umdrehe. Die gebe ich dann zurück. Bei mir liegt das Problem beim lesen der Daten aus der Exceltabelle. Code immer noch wie oben. Wo bist du schneller? Ein Test ergab: In der Zeit, in der deine Routine 1762 Zeilen und 174 Spalten einließt, ließ meine nur 20 Zeilen mit 70 Spalten. Stefan PS: Verwendest du mapcar für die Schleife oder vielleicht eine while-schleife mit zähler? [Diese Nachricht wurde von s.wickel am 25. Apr. 2006 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied | |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 25. Apr. 2006 12:01 <-- editieren / zitieren --> Unities abgeben:
|
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 25. Apr. 2006 12:22 <-- editieren / zitieren --> Unities abgeben:
Und noch für alle die jetzt immer noch nicht schlauer sind, die Funktion die ich zum einlesen einer KOMPLETTEN Exceltabelle erstellt habe. Code: (defun get-xldaten (/ excel activeworkbook activesheet datenfeld maxze maxspt ergeb ergebnisse zaehler zeile spalte) ;Initialisierung (setq excel (vlax-get-object "Excel.Application")) (setq activeworkbook (vlax-get-property Excel "Activeworkbook")) (setq activesheet (vlax-get-property activeworkbook "Activesheet")) (setq Datenfeld (vlax-variant-value (vlax-get-property (vlax-get-property activesheet "UsedRange") "VALUE") ) ) ;Datenfeld mit den Daten ACHTUNG! Index 1 1 gibt die erste BENUTZTE Zeile und Spalte zurück (setq maxze (vlax-safearray-get-u-bound Datenfeld 1)) ; Anzahl der Zeilen (setq maxspt (vlax-safearray-get-u-bound Datenfeld 2)) ; Anzahl der Spalten (setq ergebnisse ()) ;Liste für Gesamtergebnis ;nur für Fortschrittsbalken (setq zaehler 0) (dos_progbar (strcat (itoa zaehler) " von " (itoa maxze) " Zeilen") maxze) ;Einschalten des Fortschrittbalkens (dos_progbar zaehler)
(setq Zeile 1) ;Zähler für Zeilen
(while (< Zeile maxze) ;Schleife über Zeilen (setq ergeb ()) ;Liste für Zeilendaten (setq Spalte 1) ;Zähler für Spalten (while (< Spalte maxspt) ;Schleife über Spalten (setq ergeb (cons (vlax-variant-value (vlax-safearray-get-element datenfeld Zeile Spalte)) ergeb ) ;cons ) ;setq ergeb (setq Spalte (1+ Spalte)) ) ;While spalte (setq ergebnisse (cons (reverse ergeb) ergebnisse)) ;Zeile in Gesamtergebnis übernehmen ;nur für Fortschrittsbalken (setq zaehler (1+ zaehler)) (dos_progbar (strcat (itoa zaehler) " von " (itoa maxze) " Zeilen") maxze) (dos_progbar zaehler) (setq Zeile (1+ Zeile)) ) ;While zeile
;nur für Fortschrittsbalken (dos_progbar) ;Ausschalten des Fortschrittbalkens (vlax-release-object excel)
;RÜCKGABEWERT !!!!!!!!!!!!!!!!!!! (setq Ergebnisse (reverse ergebnisse)) )
Für Hinweise auf Fehler bin ich dankbar, weil ich den Code noch nicht durchgetestet habe. Habe ich heute auch keine Zeit mehr für. Stefan Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |