DBF in XLS mit xBase++

Eigentlich ist mir die Frage peinlich, aber es kann sonst niemand helfen ... :)

Moderator: Moderatoren

Antworten
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

DBF in XLS mit xBase++

Beitrag 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
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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...
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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
Dateianhänge
Export_DBF_to_XLSX.prg
(5.21 KiB) 113-mal heruntergeladen
excel-2010.ch
(183.02 KiB) 105-mal heruntergeladen
Gruß
Hubert
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: DBF in XLS mit xBase++

Beitrag 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.
Valar Morghulis

Gruss Carlo
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: DBF in XLS mit xBase++

Beitrag 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
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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)
Gruß
Klaus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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.
Gruß
Hubert
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: DBF in XLS mit xBase++

Beitrag von Bernd Reinhardt »

Hallo Klaus

Wie müssen die beiden Variablen cFullRange und cMaxLength formatiert werden?
Ich hab darüber nichts gefunden.


Gruß
Bernd
Bernd Reinhardt
fa.reinhardt@gmx.de
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: DBF in XLS mit xBase++

Beitrag 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
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: DBF in XLS mit xBase++

Beitrag 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
gruss by OHR
Jimmy
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag von Koverhage »

Hallo Bernd,
bei mir ist das z.B.
oSheet:Range("H2:H"+cMaxLength):NumberFormat := "#.##0,00 _€"
Gruß
Klaus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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.
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: DBF in XLS mit xBase++

Beitrag 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
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: DBF in XLS mit xBase++

Beitrag 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 ?
gruss by OHR
Jimmy
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: DBF in XLS mit xBase++

Beitrag 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
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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

Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: DBF in XLS mit xBase++

Beitrag 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.
Herzlich,
Tom
Antworten