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.