Problem mit Exel

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
mk-soft
Beiträge: 3845
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

CSV und TXT klappt noch nicht.
Vielleicht weiss einer noch rat.

FF :|
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Hab mal die Variablen deklariert und das Memorygedönse geändert

Code: Alles auswählen

;-TOP
; Kommentar : Excel Tabelle lesen über SQL
; Version   : v1.01
; Author    : Michael Kastner
; Datei     : FcDatabase.pb
; Erstellt  : 28.09.2006
; Geändert  :
; ***************************************************************************************
Enumeration 1
  #ODBC_ADD_DSN             ; // Add data source
  #ODBC_CONFIG_DSN          ; // Configure (edit) Data source
  #ODBC_REMOVE_DSN          ; // Remove data source
  #ODBC_ADD_SYS_DSN         ; // add a system DSN
  #ODBC_CONFIG_SYS_DSN      ; // Configure a system DSN
  #ODBC_REMOVE_SYS_DSN      ; // remove a system DSN
  #ODBC_REMOVE_DEFAULT_DSN  ; // remove the default DSN
EndEnumeration
; ***************************************************************************************

Procedure.s AddDSN(databasename.s, user.s = "", pass.s = "", driver.s = "") ; Result DSN
  Protected name.s, strDriver.s, strAttributes.s
  Protected L.l, result.l
  Protected *buffer.Character
  
  ; Databasename erzeugen (DSN)
  name.s = GetFilePart(databasename)
  name = Left(name.s, Len(name.s) - 4)
  name = "Pure" + name
  ; Bei fehlenden driver automatisch wählen
  If driver = ""
    driver = GetExtensionPart(databasename)
  EndIf
  ; Datenbanktreiber auswählen
  Select UCase(driver)
    Case "ACCESS", "MDB"
      strDriver.s = "Microsoft Access Driver (*.mdb)"
    Case "EXCEL", "XLS"
      strDriver.s = "Microsoft Excel Driver (*.xls)"
    Case "DBASE", "DBF"
      strDriver.s = "Microsoft dBase Driver (*.dbf)"
    Case "TEXT", "TXT", "CSV"
      strDriver.s = "Microsoft Text Driver (*.txt; *.csv)"
    Default
      strDriver.s = driver
  EndSelect
  ; Attributes zustellen
  strAttributes.s = "Server=APServer;Description=" + name
  strAttributes.s + ";DSN=" + name
  strAttributes.s + ";DBQ=" + databasename
  strAttributes.s + ";UID=" + user
  strAttributes.s + ";PWD=" + pass + ";" 
 
  *buffer = @strAttributes
  For L = 0 To Len(strAttributes) - 1
    If *buffer\c = ';'
      *buffer\c = 0
    EndIf
    *buffer + 1
  Next L                                                         ; Check the next byte

  result = SQLConfigDataSource_(0, #ODBC_ADD_DSN, strDriver, @strAttributes)   ; Call the function you need from the ODBC library with the right details
   
  If result
    ProcedureReturn name
  Else
    ProcedureReturn ""
  EndIf

EndProcedure
 
; ***************************************************************************************

Procedure.l RemoveDSN(databasename.s, user.s = "", pass.s = "", driver.s = "")
  Protected name.s, strDriver.s, strAttributes.s
  Protected L.l, result.l
  Protected *buffer.Character
  
  ; Databasename erzeugen
  name = GetFilePart(databasename)
  name = Left(name, Len(name) - 4)
  name = "Pure" + name
  ; Bei fehlenden driver automatisch wählen
  If driver = ""
    driver = GetExtensionPart(databasename)
  EndIf
  ; Datenbanktreiber auswählen
  Select UCase(driver)
    Case "ACCESS", "MDB"
      strDriver = "Microsoft Access Driver (*.mdb)"
    Case "EXCEL", "XLS"
      strDriver = "Microsoft Excel Driver (*.xls)"
    Case "DBASE", "DBF"
      strDriver = "Microsoft dBase Driver (*.dbf)"
    Case "TEXT", "TXT", "CSV"
      strDriver = "Microsoft Text Driver (*.txt; *.csv)"
    Default
      strDriver = driver
  EndSelect
  ; Attributes zustellen
  strAttributes = "DSN=" + name + ";"
 
  *buffer = @strAttributes
  For L = 0 To Len(strAttributes) - 1
    If *buffer\c = ';'
      *buffer\c = 0
    EndIf
    *buffer + 1
  Next L                                                        ; Check the next byte
 
  result = SQLConfigDataSource_(0, #ODBC_REMOVE_DSN, strDriver, @strAttributes)   ; Call the function you need from the ODBC library with the right details

  ProcedureReturn result

EndProcedure
 
; ***************************************************************************************

;- Test
#Datenbank = 0

InitDatabase()

Path.s = "E:\Eigene Dateien\PureBasic4\Libs\ScriptControl\Examples\Telefon.xls"
; DSN anlegen
Base.s = AddDSN(Path)

If Base
  Debug "DSN=" + Base
  If OpenDatabase(#Datenbank, Base, "", "")
    sql.s = "Select * From [Tabelle1$]"
    If DatabaseQuery(#Datenbank, sql) ; Ermittelt alle Einträge in der 'employee' Tabelle
      Spalten = DatabaseColumns(#Datenbank) - 1
      temp.s = ""
      For Spalte = 0 To Spalten
        temp + DatabaseColumnName(#Datenbank, Spalte) + ";"
      Next
      Debug temp
      While NextDatabaseRow(#Datenbank)  ; alle Einträge durchlaufen
        temp.s = ""
        For Spalte = 0 To Spalten
          temp + GetDatabaseString(#Datenbank, Spalte) + ";"
        Next
        Debug temp
      Wend

    EndIf
  EndIf
EndIf
; DSN am Ende entfernen
RemoveDSN(path, "", "")
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3845
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

@ts-soft,

Danke :allright:

Habe mal ein bischen gesucht und das hier gebastelt.

Code: Alles auswählen

Procedure.s GetTables(Datenbank)

  Protected hwnd.l, r1.l, len.l
  Protected *buffer
  Protected result.s
  
  hwnd = PeekL(IsDatabase(Datenbank) + 4)
  result.s = ""
  If hwnd
    r1 = SQLTables_(hwnd,0,0,0,0,0,0,0,0) & $FFFF
    If r1 = 0 Or r1 = 1
      *buffer = AllocateMemory(256)
      SQLBindCol_(hwnd,3,1,*buffer,256,@len)
      While SQLFetch_(hwnd) & $FFFF = 0
        result + PeekS(*buffer, len) + ";"
      Wend
      FreeMemory(*buffer)
    EndIf
  EndIf
  ProcedureReturn result
  
EndProcedure

Debug GetTables(#Datenbank)
Und schon hat man die Tabellennamen.

FF :wink:

Edit: Nach DatabaseQuery(...) geht die Funktion nicht mehr. Bin noch am testen.
Zuletzt geändert von mk-soft am 29.09.2006 20:02, insgesamt 2-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

@mk-soft
Du hast schon wieder die Variablen nicht deklariert!
So würdest Du zum Beispiel eine sehr wahrscheinliche globale Variable hWnd
zerstören.

Bitte alle Variablen in den Proceduren deklarieren, möglichst Protected. Bei
den Beispielsource spielts dann keine so grosse Rolle. Möchte das ja als
Include gefahrlos überall einsetzen können :wink:

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3845
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

@ts-soft

Sorry, bin sonst nicht so nachlässig :oops: :allright:

Edit: Update GetTables()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Hab noch einen Optionalen Separator eingebastelt, muß ja nicht immer
Semikolon sein :wink:

Code: Alles auswählen

Procedure.s GetTables(Datenbank, Seperator.s = ";")

  Protected hwnd.l, r1.l, len.l
  Protected *buffer
  Protected result.s
 
  hwnd = PeekL(IsDatabase(Datenbank) + 4)
  result.s = ""
  If hwnd
    r1 = SQLTables_(hwnd,0,0,0,0,0,0,0,0) & $FFFF
    If r1 = 0 Or r1 = 1
      *buffer = AllocateMemory(256)
      SQLBindCol_(hwnd,3,1,*buffer,256,@len)
      While SQLFetch_(hwnd) & $FFFF = 0
        result + PeekS(*buffer, len) + Seperator
      Wend
      FreeMemory(*buffer)
    EndIf
  EndIf
  ProcedureReturn result
 
EndProcedure
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

Was passiert, wenn meine CSV-Datei durch Excel folgendes hat:


"3;4";Hallo;"Post";2,3;6;7;"5;2"

Und alle Dinge in "" Anführungszeichen sollen auch in einer Zelle sein ...

3;4 statt 3 und 4

Probleme gibt es bei Excel und bei OpenOffice, wenn da Formeln mit drin sind und die gern das Semikolon verbrauchen. Oder ein Nutzer vorher ein Semikolon benutzt hat in einer Zelle

Habt ihr Rat? Ohne aufwendige StringOperationen ... :roll:
Kinder an die Macht http://scratch.mit.edu/
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Versuchs mal mit OpenCalc, der öffnet automatisch einen Dialog, wo Du sehr
viel einstellen kannst. Bei Excel hat MS nur einen Standard, obwohl es einen
solchen garnicht gibt :mrgreen: . Nichtmal Komma oder Semikolon
läßt sich definieren beim öffnen.

Excel ist IMHO rausgeschmissenes Geld :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

Ich merk schon, ich drücke mich mal wieder falsch aus.

Ich hab selbst auch kein Excel mehr. Benutze nur noch das OpenOffice.

Aber genau da ist das Problem.

Und so toll sind die Einstellungsmöglichkeiten bei OpenCalc auch nicht.

Wenn ich zum Beispiel einen Seperator hätte, der aus zwei Zeichen besteht, ist es schon nicht möglich. Genauso kann ich beim Exportieren nicht abstellen, dass es mir Strings in Anführungszeichen setzt.

Es ging ja auch eher drum, wie ich eine CSV-Datei, die mit Excel oder Calc erstellt worden ist, ohne langsames Stringhändlich richtig entschlüsseln kann.

StringFild() ist eine sehr schöne Option. Damit kann man einen sauberen Datensatz sehr gut einlesen. Aber wie schon angesprochen kann es dabei zu Konflikten kommen, wenn der Seperator durch Anführungszeichen variiert ...

Oder sehe ich Probleme, wo keine sind? :freak:
Kinder an die Macht http://scratch.mit.edu/
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> Oder sehe ich Probleme, wo keine sind? :freak:
Dann parste den String eben selber, richtig gemacht ist es sogar schneller als
mit StringField! Siehe als Beispiel erstes Posting hier:
http://www.purebasic.fr/german/viewtopi ... 5&start=40
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten