Seite 1 von 1
DBF in XLS mit xBase++
Verfasst: Sa, 08. Apr 2023 10:06
von Bernd Reinhardt
Hallo
Ich habe mir das Beispiel von Alaska genommen um dbf in excel zu übertragen. Alles ohne zusätzliche Bibliothek.
Auch Umlaute passen. Die Datei lässt sich mit Excel öffnen.
Funktioniert auch sehr gut so lange ich weniger als ca. 200 Zeilen habe. Bei mehr friert das Programm ein.
Windows 11, genügend freier Speicher, xBase++ Version 2.0, Office 2019
An den Daten selbst kann es aber nicht liegen, da das Programm nicht immer an der selben Stelle abbricht.
Muss man hier was spezielles beachten damit xBase++ richtig arbeitet?
Code: Alles auswählen
oExcel := CreateObject("Excel.Application")
oExcel:DisplayAlerts := .F.
oExcel:visible := .T.
oBook := oExcel:workbooks:Add()
oSheet := oBook:ActiveSheet
oSheet:PageSetup:Orientation := xlLandscape
select 1
USE "dstati06.DBF" EXCLUSIVE ALIAS dstati
DbGoTop()
nRow := 1
// Überschriften
oSheet:Cells(nRow,1):Value := "DA_2023"
oSheet:Cells(nRow,2):Value := "Gesamtumsatz"
oSheet:Cells(nRow,3):Value := "Lieferadresse"
oSheet:Cells(nRow,4):Value := "Anlage"
oSheet:Cells(nRow,5):Value := "Lieferfirma"
oSheet:Cells(nRow,6):Value := "Ort"
oSheet:Cells(nRow,7):Value := "Firmenname"
oSheet:Columns( 1 ):NumberFormat := "0.00"
oSheet:Columns( 2 ):NumberFormat := "0.00"
nRow := 2
DO WHILE !EOF()
oSheet:Cells(nRow,1):Value := dstati->DA_2023
oSheet:Cells(nRow,2):Value := dstati->DA_GESAMT
oSheet:Cells(nRow,3):Value := dstati->DA_LIEFADR
oSheet:Cells(nRow,4):Value := dstati->DA_ANLAGE
oSheet:Cells(nRow,5):Value := dstati->DA_LFIRMA
oSheet:Cells(nRow,6):Value := dstati->DA_ORT
oSheet:Cells(nRow,7):Value := dstati->DA_NAME
nRow++
nCounter++
DbSkip(1)
if nCounter > 200
exit
endif
ENDDO
use
oSheet:Columns( 1 ):AutoFit()
oBook:SaveAs("d:\temp\MyExcel.xls",xlWorkbookNormal)
oExcel:Quit()
oExcel:Destroy()
Gruß
Bernd
Re: DBF in XLS mit xBase++
Verfasst: So, 09. Apr 2023 7:44
von brandelh
zunächst würde ich nicht XLS nutzen ! XLSX (kein Dateimakrovirus möglich) ist der Standard seit 2010 oder für große Dateien XLSB.
Ich speichere nach dem Programm von Alaska Dateien mit 850.000 Datensätzen, das dauert aber es geht, sowohl mit Excel 2010 (32 Bit) als auch mit Version 2021 (64 bit).
die excel.ch für die neueren Versionen hab ich - meine ich auch mal hochgeladen.
Wichtig dabei ist, dass man ganze Dateien auf einmal überträgt, sonst wird das doch sehr langsam.
Ich schaue mal ob das nicht in der Wissensbasis steht...
Re: DBF in XLS mit xBase++
Verfasst: So, 09. Apr 2023 8:02
von brandelh
Hier ist der Quellcode ... Namen und Erläuterung verallgemeinert:
Mehrere Datensätze einzeln, ist viel zu langsam, dafür nimmt man besser HBLibXL mit der LibXL
Re: DBF in XLS mit xBase++
Verfasst: So, 09. Apr 2023 14:29
von ramses
brandelh hat geschrieben: ↑So, 09. Apr 2023 7:44
Ich speichere nach dem Programm von Alaska Dateien mit 850.000 Datensätzen
Hallo Hubert
hast du das mal mit LibXl versucht? Ich stehe gerade mächtig an einem Problem an.
Die Exporte nach XLS werden immer grösser aktuell sind es ca. 186000 Datensätze (10 Werte pro Satz) die in eine Exceltabelle in mehrere Tabs übertragen werden sollen/müssen. Leider stürzt die ganze Anwendung nun immer ohne Fehlermeldung ab. Im Taskmamanger sieht man wie der genutze Speicher von 20MB ansteigt und irgendwo bei 400MB ist die App ohne Kommentar und ohne Meldungs einfach weg. (Abgestürzt, einfach nicht mehr in Action und im Speicher)
Mit einigen 10000 Sätzen weniger geht es, die Speichernutzung steigt aber auch bis über 300MBytes die fertige Exceltabelle ist dann ca. 7MB gross.
Re: DBF in XLS mit xBase++
Verfasst: Mo, 10. Apr 2023 13:35
von Bernd Reinhardt
Hallo Hubert.
Vielen Dank für das Beispiel. Ich denke ich muss den Schritt gehen.
Oder wie bisher in eine csv-Datei. Das hat bisher immer gut funktioniert.
Aber das stört mich an xBase++. Wenn man was mit Bordmitteln machen will dann benötigt man einen kostenpflichtigen Zusatz.
Ich hab mal in meinem Beispiel eine Zeitverzögerung eingebaut. Alle 20 Datensätze warte ich 6 sec. Dauert zwar lange aber es sind dann tatsächlich alle 1900 Zeilen in 17 Spalten übertragen worden.
Gruß
Bernd
Re: DBF in XLS mit xBase++
Verfasst: Di, 11. Apr 2023 8:25
von Koverhage
Hallo Bernd,
kann aber mit den 200 Zeilen nicht zusammenhängen.
Ich erzeuge hier z.B. eine Tabelle mit 4842 Zeilen und 63 Spalten (Spalte 63 = Memofeld)
1-62 = Adressdaten und andere.
Die Daten bereite ich allerdings als aArray vor
Das geht rucki zucki
BEGIN SEQUENCE
oSheet:Range(cFullRange+cMaxLength):value := aArray
oSheet:Application:ActiveWindow:SplitRow := 1
oSheet:Application:ActiveWindow:FreezePanes := YES
END SEQUENCE
ErrorBlock(oErrBlock)
Re: DBF in XLS mit xBase++
Verfasst: Mi, 12. Apr 2023 11:06
von brandelh
Ja das mit dem Array spart dem Programm viele ActiveX Aufrufe.
Mit LibXL kann man alles ohne Excel schnell machen, das ist der große Vorteil,
aber mal eben eine DBF öffnen und wieder als XLSX speichern ist nicht so einfach
(ich denke man muss alles einzeln machen, hat dadurch aber den Vorteil der vollen Kontrolle).
Ich könnte mir vorstellen, dass in der Schleife ein SLEEP(0) die Stabilität erhöht,
da es der Schnittstelle etwas mehr Zeit verschafft.
LibXL ist aus meiner Sicht für solche Aufgaben aber besser geeignet.
Du kannst dafür auch die Testversion nutzen, die belegt nur die erste Zeile ... wenn es dann geht einfach LizenzKey eingeben und gut ist.
Wichtig XLS ist veraltet, nimm XLSX !!!!
Ich lösche z.B. alle XLS Dateien ohne diese zu öffnen, ist mir viel zu gefährlich.
Re: DBF in XLS mit xBase++
Verfasst: So, 16. Apr 2023 12:19
von Bernd Reinhardt
Hallo Klaus
Wie müssen die beiden Variablen cFullRange und cMaxLength formatiert werden?
Ich hab darüber nichts gefunden.
Gruß
Bernd
Re: DBF in XLS mit xBase++
Verfasst: So, 16. Apr 2023 16:42
von Bernd Reinhardt
Hallo Klaus.
Manchmal sieht man den Wald vor lauter Bäumen nicht. Habs gelöst.
Mithilfe des Arrays geht die Umsetzung unglaublich schnell.
Jetzt wollte ich noch ein Feld als Währung formatieren.
oSheet:Columns( 3 ):NumberFormat := "#.##0,00 €"
Aber das Eurozeichen kommt nicht richtig an.
NumberFormatLocal hat auch nicht weiter geholfen.
Aber das ist ja nicht so wichtig. Erst mal vielen Dank für den Tip.
Hätte etwas Zeit gespart wenn Alaska das Beispiel gleich so gemacht hätte das es auch vernünftig läuft.
Gruß
Bernd
Re: DBF in XLS mit xBase++
Verfasst: Mo, 17. Apr 2023 10:01
von AUGE_OHR
hi,
Bernd Reinhardt hat geschrieben: ↑So, 16. Apr 2023 16:42
Hätte etwas Zeit gespart wenn Alaska das Beispiel gleich so gemacht hätte das es auch vernünftig läuft.
die Frage ist ob Alaska diesen "Trick" kennt der hier aus dem Forum stammt
Re: DBF in XLS mit xBase++
Verfasst: Mo, 17. Apr 2023 12:01
von Koverhage
Hallo Bernd,
bei mir ist das z.B.
oSheet:Range("H2:H"+cMaxLength):NumberFormat := "#.##0,00 _€"
Re: DBF in XLS mit xBase++
Verfasst: Mo, 17. Apr 2023 13:50
von brandelh
Für das € Zeichen muss man aber Xbase auf ANSI stellen und das Zeichen in der EXE freigeben, irgendwas mit Localisation, einfach in Hilfe suchen.
Re: DBF in XLS mit xBase++
Verfasst: Mo, 17. Apr 2023 14:01
von Jan
Hubert,
es geht beides, ANSI und ASCII. Muß man nur passend einstellen:
ANSI:
Code: Alles auswählen
SetLocale(NLS_SCURRENCY, Chr(128))
SetLocale(NLS_ICURRENCYEURO, "1")
ASCII:
Code: Alles auswählen
SetLocale(NLS_SCURRENCY, Chr(213))
SetLocale(NLS_ICURRENCYEURO, "1")
Jan
Re: DBF in XLS mit xBase++
Verfasst: Mo, 17. Apr 2023 21:27
von Bernd Reinhardt
Hallo
Danke habs jetzt am laufen. Ich war der Meinung das ich die locale richtig gesetzt habe.
An anderer Stelle im Programm habe ich das Eurozeichen auch schon verwendet.
Habe dann zur Sicherheit die Einstellungen direkt vor dem setzten des Format eingetragen.
So passt es jetzt. Und unsagbar schnell die Exceldatei.
Code: Alles auswählen
ErrorBlock(bError)
SET CHARSET TO ansi
SetLocale(NLS_SCURRENCY, chr(128)) // Chr(213))
SetLocale(NLS_ICURRENCYEURO, "1")
for nI = 1 to 13
oSheet:Columns( nI ):NumberFormat := "0,00 €"
next
Vielen Dank.
Gruß
Bernd
Re: DBF in XLS mit xBase++
Verfasst: Di, 18. Apr 2023 0:16
von AUGE_OHR
hi,
Bernd Reinhardt hat geschrieben: ↑Mo, 17. Apr 2023 21:27
An anderer Stelle im Programm habe ich das Eurozeichen auch schon verwendet.
wie Hubert und Jan schon sagten
Deine Xbase++ App ist wohl OEM was die Default Einstellung ist auf die sich die Hilfe bezieht
Windows Apps sind aber gewöhnlich ANSI / Unicode und deshalb musst du das ANSI Zeichen verwenden
---
Frage : hast du Dezimal Stellen ?
Re: DBF in XLS mit xBase++
Verfasst: Do, 20. Apr 2023 10:34
von Bernd Reinhardt
Hallo Klaus.
Wie wäre der umgekehrte Weg am einfachsten?
Auslesen eines festen definierten Bereiches aus einer Exceldatei.
Dateiname, Arbeitsplatzname und Tabellengröße sind immer fest.
Die Inhalte werden in Excel geändert und ich müsste die Änderungen übernehmen.
Gruß
Bernd
Re: DBF in XLS mit xBase++
Verfasst: Do, 20. Apr 2023 10:57
von Koverhage
Hallo Bernd,
Code: Alles auswählen
FUNCTION ar_xls_import(cXLSFile)
Local oExcel, ;
oBook, ;
oSheet, ;
mess2 := LGTrans('0051002','Microsoft Excel ist nicht installiert'), ;
nRow := 0, ;
nCell := 0, ;
i := 0, ;
n := 0, ;
y := 0, ;
nMax := 0, ;
aValues := {}, ;
aTempValues := {}
#if XPPDEVVER > 01890000
// Create the "Excel.Application" object
oExcel := CreateObject("Excel.Application")
IF Empty( oExcel )
MsgBox( mess2 )
RETURN .f.
ENDIF
// Avoid message boxes such as "File already exists". Also,
// ensure the Excel application is Visible.
oExcel:DisplayAlerts := .F.
oExcel:Visible := .F.
oExcel:Interactive := .F.
// Open the Workbook
oBook := oExcel:Workbooks:Open( cXLSFile )
// Count the number of WorkSheets
i := oBook:Worksheets():count()
for n := 1 to i
oBook:Worksheets(n):activate() // Activate sheet
oSheet := oBook:Worksheets(n) // Shortcut
oExcel:Application:ActiveCell:SpecialCells(xlLastCell):Select
nRow := oExcel:Application:ActiveCell:Row
nCell := oExcel:Application:ActiveCell:Column
IF n = 1
aValues := oExcel:Application:Range(oSheet:Cells(2,1),oSheet:Cells(nRow,nCell)):value
ELSE
aTempValues := oExcel:Application:Range(oSheet:Cells(2,1),oSheet:Cells(nRow,nCell)):value
nMax := Len(aTempValues)
FOR y := 1 TO nMax
aAdd(aValues,aTempValues[y])
NEXT
ENDIF
next
oExcel:Interactive := .T.
oExcel:Quit()
sleep(10)
oExcel:Destroy()
oExcel := NIL
#endif
RETURN aValues
Re: DBF in XLS mit xBase++
Verfasst: Do, 20. Apr 2023 10:58
von Tom
Das kann man z.B. mit der ODBCDBE machen. Oder Du fichtelst direkt in der XML-Struktur der XLSX-Datei herum. Such mal nach "Excel" im Forum, da findest Du das Thema dutzendfach.