TMLExcel - herausfinden wieviele reihen es gibt
-
hi...
ich hab mir mit hife der TMLExcel komponente eine .xls datei geoeffnet und will mit jeder zeile in dieser datei etwas machen ... ich muss aber vorher schon wissen wieviele zeilen es gibt .. wie kann ich das herausfinden?danke
-
Hi,
im einer Tabelle eines Workbooks sind immer sowie Spalten drin, wie Excel es zulässt.
Die Anzahl wird nicht durch beschreibene Zellen begrenzt. Leider.Deshalb ist es immer Sinnvoll MaxRows und MaxCols von TMLWorksheet zu setzen. Setzte diese Begrenzung bevor du die Cellen ausließt mit Werten, die du für Sinnvoll hälst. Meistens weiss man ja, wieviel Spalten oder Zeilen in solchen Dateien drin sind. Wenn man es nicht genau weiss muss man halt den Rahmen etwas großzügig dimensionieren.
dan kannst du mit sowas:for( int i=1; i<Sheet->MaxRows;i++) { TStringList* Row=Sheet->Row[i]; // mach was mit Row }
deine Zeilen auslesen.
-
Excel speichert die letzte verwendete Zelle in [WorkSheet].Cells.SpecialCells(11). Allerdings ist das nicht unbedingt die letzte Zelle mit Inhalt, denn wenn Zellen gelöscht werden, wird der Wert für "SpecialCells" nur dann aktualisiert, wenn man Zelle "A1" markiert und dann abspeichert.
In VBasic habe ich mal die untenstehenden Routinen benutzt, um letzte Zeile/Spalte zu ermitteln, vielleicht hilft Dir das ja weiter: müßte sich relativ leicht in C++ umsetzen lassen.Dim XL as Excel.Application Function lastRow() Dim endzeile As Long endzeile = XL.ActiveSheet.Cells.SpecialCells(11).Row + 1 Do endzeile = endzeile - 1 Loop Until (Not range_empty(XL.ActiveSheet.Rows(endzeile))) Or (endzeile <= 1) lastRow = endzeile End Function Function lastColumn() Dim Endspalte As Long Endspalte = XL.ActiveSheet.Cells.SpecialCells(11).Column + 1 Do Endspalte = Endspalte - 1 Loop Until (Not range_empty(XL.ActiveSheet.Columns(Endspalte))) Or (Endspalte <= 1) lastColumn = Endspalte End Function Function range_empty(r) range_empty = False If (r.Find(What:="*", LookIn:=-4163, LookAt _ :=2, SearchOrder:=1, SearchDirection:=1, MatchCase:= _ False) Is Nothing) Then range_empty = True End Function
-
hm,
werds morgen mal testen und in die Klasse einbauen, wenn ich noch Zeit habe.
danke für den Hinweis
-
ich hab grad gemerkt das ich ein noch viel schlimmers problem als die maximalen reihen hab
wenn man sich den wert eines feldes ueber die funktion
String __fastcall TMLWorksheet::GetCellString(int Col, int Row)
ausgeben laesst so dauert das "relativ" lange ... wenn man nur ein feld auslesen will ist das kein problem ... es wird aber zum problem wenn man sich 4000x6 felder ausgeben lassen will .. das dauert dann so ca. ne stunde bis alles fetig ist ...
kann man das nicht auch noch ein wenig beschleunigen? .. dann koennte man ja auch den maximalen reihen mit durchtesten herausfinden
-
Die beste Lösung wäre ein Export der Excle- Datei in eine *csv. Die Datei kann man besser händeln als über OLE zu gehen. Ist auch wesentlich schneller.
Wenn du die Excel- Datei nicht manipulieren musst, würd ich das so machen.
Zeichne ein Macro in Excel auf, in dem du ein Export machst. Dieses Macro versuchst du über OLE nachzubauen. Die Funktionen der TMLWorkscheet - Klasse können dir dabei Anreiz bieten, wie man was realisieren kann.
Ich wollte eigentlich CodeWalker's Idee in der Klasse umsetzten und noch ein paar tests durchführen. Leider stecke ich zur Zeit bis über beide Ohren in Arbeit und kann deshalb keine zeitintensiven Sachen machen. As dem Grunde muss übrigens auch das OpenGL- Beispiel warten.
Wenn du Lust hast, kannst du ja die Klasse dahingehend ausbauen und verbessern.
Die Änderungen würd ich testen und in die FAQ mit aufnehmen.[ Dieser Beitrag wurde am 10.07.2003 um 11:36 Uhr von AndreasW editiert. ]
-
hab jetzt ma son makro gemacht ... viel nuetzen tut mir der auch nich wiklich .. ich hab keine ahnung wie ich den filetyp beim speichern aendern kann oder halt diesen makro mit deiner klasse ausfuehren kann
Sub Makro1() ' ' Makro1 Makro ' Makro am 10.07.03 von Gast aufgezeichnet ' ' Tastenkombination: Strg+s ' ActiveWorkbook.SaveAs FileName:= _ "C:\WINNT\Profiles\gast\Eigene Dateien\Mappe1.csv", FileFormat:=xlCSV, _ CreateBackup:=False Application.Run "Mappe1.csv!Makro1" End Sub
-
Hi,
mach sowas in der Header:
// weit oben irgendwo: enum TMLFileType { xlNormal = -4143, xlCSV = 6}; bool TMLExcel::SaveWorkbookAs(AnsiString BookName, String FileName, TMLFileType exp=xlNormal, bool backup=false)
bau die SaveAs- Methode so um:
bool TMLExcel::SaveWorkbookAs(AnsiString BookName, String FileName, TMLFileType exp, bool backup) { try { int temp=IndexOfWorkbooks(BookName); if(Connect && ++temp) var_Excel.OlePropertyGet("Workbooks",temp).OleProcedure("SaveAs",(Variant) FileName,(Variant)exp,(Variant)backup); else return false; UpdateBookList(); return true; } catch (...) { return false; } }
dann rufst du die Methode mit xlCSV auf.
PS:Der Quellcode ist natürlich ungetestet und kann eventuell noch FEhelr enthalten. Hab keine Zeit zum Testen.
-
vielen dank fuer deine antwort ... es funtzt jetzt
aber
wenn ich die datei als eine csv-file speicher kommen diverse abfragen (wo man dann manuell ok druecken muss) die beim normalen speichern nicht kommen .. wie kann ich diese unterbinden
-
Hi,
versuchs so:
bool TMLExcel::SaveWorkbookAs(AnsiString BookName, String FileName, TMLFileType exp, bool backup) { try { int temp=IndexOfWorkbooks(BookName); var_Excel.OlePropertySet("DisplayAlerts",false); if(Connect && ++temp) var_Excel.OlePropertyGet("Workbooks",temp).OleProcedure("SaveAs",(Variant) FileName,(Variant)exp,(Variant)backup); else return false; UpdateBookList(); return true; } catch (...) { return false; } }
-
Man kann doch in Excel das CSV-Trennzeichen aussuchen, oder? Dann würde ich vorschlagen, dafür das Komma statt des Standard-Semikolons zu benutzen, dann lässt sich die Datei später wunderbar bz. leichter mit TStringList::CommaText bearbeiten.
-
öhm, wenn du Zahlen in Excel hast, mach Excel aus dem Dezimaltrennzeichen ein Komma. Fatal, wenn man dann auch Komma als Cellen - Seperator hat.
-
In solchen Fällen wird der Zelleninhalt eben in Anführungszeichen "gekapselt". Excel hat kein Problem, eine CSV-Datei ala
111,"222,23","4356,34","der ""Lack"" ist ab",35324
korrekt zu öffnen. Und auch TStringList versteht diese Kapselung.
Allerdings habe ich mich wohl getäuscht, was das Festlegen des Trennzeichens betrifft. Ich kann keine diesbezügliche Option für das Speichern finden, lediglich beim Dateiimport gibt es die entsprechenede Möglichkeit.
-
Den Seperator kann man in der Ländereinstellung einstellen. Wenn man sich der Regristry bedient, kann man wahrscheinlich diesen ändern.