Seite 1 von 2

Problem mit Exel

Verfasst: 28.09.2006 20:38
von sebsch80
Hallo!!!

Ich hab da ein Problem. Ich wollte eine Exel Tabelle in PureBasic verwenden.
Da ich aber ein absoluter Anfänger bin, hab ich keinen Plan wie ich das bewerkstelligen soll.

Also meine Frage:
Ist es überhaupt möglich Daten aus einer ExelTabelle einzulesen, sie dann zu berechnen und in einem Fenster auszugeben?

Wenn ja wie und mit welchen Befehlen?

Weiß jemand ob es zu diesem Thema ein Tutorial gibt?

Verfasst: 28.09.2006 20:41
von ts-soft
Siehe hier: http://www.purebasic.fr/german/viewtopi ... iptcontrol
Beispiel für Excel-Tabelle ist bei.

Verfasst: 28.09.2006 22:33
von mk-soft
Mit SQL -> OpenDatabase()

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  : 

; ***************************************************************************************

#ODBC_ADD_DSN = 1; // Add data source 
#ODBC_CONFIG_DSN = 2; // Configure (edit) Data source 
#ODBC_REMOVE_DSN = 3; // Remove data source
#ODBC_ADD_SYS_DSN = 4; // add a system DSN 
#ODBC_CONFIG_SYS_DSN = 5; // Configure a system DSN 
#ODBC_REMOVE_SYS_DSN = 6; // remove a system DSN 
#ODBC_REMOVE_DEFAULT_DSN = 7; // remove the default DSN

; ***************************************************************************************

Procedure.s AddDSN(driver.s, databasename.s, user.s, pass.s) 

  name.s = GetFilePart(databasename.s)
  name = Left(name.s, Len(name.s) - 4)
  name = "Pure" + name
  Select UCase(driver)
    Case "ACCESS"
      strDriver.s = "Microsoft Access Driver (*.mdb)"
    Case "EXCEL"
      strDriver.s = "Microsoft Excel Driver (*.xls)"
    Default
      strDriver.s = driver
  EndSelect
  strAttributes.s = "Server=APServer;Description=" + name
  strAttributes.s + ";DSN=" + name
  strAttributes.s + ";DBQ=" + databasename 
  strAttributes.s + ";UID=" + user 
  strAttributes.s + ";PWD=" + pass + ";"  
  
  MyMemory = AllocateMemory(Len(strAttributes))  ; Allocate the memory you need here 
  CopyMemory(@strAttributes, MyMemory, Len(strAttributes))      ; Copy the database information string into the memory space 
  
  For L = 1 To Len(strAttributes)                               ; Check the string in the memory space now 
    If PeekB(MyMemory + L - 1) = Asc(";")                       ; If you find a semicolon anywhere in the string 
      PokeB(MyMemory + L - 1, 0)                                ; Replace it with an empty character as the driver doesn't use it 
    EndIf                                                       ; End the current check 
  Next L                                                        ; Check the next byte 
  
  result = SQLConfigDataSource_(0, #ODBC_ADD_DSN, strDriver, MyMemory)   ; Call the function you need from the ODBC library with the right details 
    
  FreeMemory(MyMemory)                                     ; Free the memory now 
  
  If result
    ProcedureReturn name
  Else
    ProcedureReturn ""
  EndIf

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

Procedure.l RemoveDSN(driver.s, databasename.s, user.s, pass.s) 

  name.s = GetFilePart(databasename.s)
  name = Left(name.s, Len(name.s) - 4)
  name = "Pure" + name
  
  Select UCase(driver)
    Case "ACCESS"
      strDriver.s = "Microsoft Access Driver (*.mdb)"
    Case "EXCEL"
      strDriver.s = "Microsoft Excel Driver (*.xls)"
    Default
      strDriver.s = driver
  EndSelect
  strAttributes.s = "DSN=" + name + ";"
  
  MyMemory = AllocateMemory(Len(strAttributes))  ; Allocate the memory you need here 
  CopyMemory(@strAttributes, MyMemory, Len(strAttributes))      ; Copy the database information string into the memory space 
  
  For L = 1 To Len(strAttributes)                               ; Check the string in the memory space now 
    If PeekB(MyMemory + L - 1) = Asc(";")                       ; If you find a semicolon anywhere in the string 
      PokeB(MyMemory + L - 1, 0)                                ; Replace it with an empty character as the driver doesn't use it 
    EndIf                                                       ; End the current check 
  Next L                                                        ; Check the next byte 
  
  result = SQLConfigDataSource_(0, #ODBC_REMOVE_DSN, strDriver, MyMemory)   ; Call the function you need from the ODBC library with the right details 
    
  FreeMemory(MyMemory)                                     ; Free the memory now 

  ProcedureReturn result

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

;- Test

#Datenbank = 0

InitDatabase()

Path.s = "D:\Daten\PureBasic4\Database\Telefon.xls"
; DSN anlegen
Base.s = AddDSN("Excel", 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("Excel", path, "", "")

Erst wird eine Benutzer DSN angelegt und mit SQL-Statement die Tabelle gelesen. Am Ende die Benutzer DSN wieder löschen.

Excel Tabellen Namen mit "$" erweitern im SQL-Statement


FF :wink:

Verfasst: 29.09.2006 11:28
von NicTheQuick
Damit das ganze auch mit Dateinamen funktioniert, die Leerzeichen
beinhalten, hab ich in der AddDSN-Procedure folgende Zeile geändert:

Code: Alles auswählen

strAttributes + ";DBQ=" + Chr(34) + databasename + Chr(34)
Aber ein Problem gibt es da noch. Ich erhalte folgenden Fehler bei
OpenDatabase():
[Microsoft][ODBC Excel driver] Aktualisieren nicht möglich; Datenbank oder Objekt ist schreibgeschützt.
Was hat das zu bedeuten, wenn ich die Datei nicht geöffnet habe oder
sonstwas. Ich hab sie nicht einmal im Explorer markiert.

Verfasst: 29.09.2006 11:35
von Karl
Im ODBC-Dialog gibt es speziell für Exceldateien bei Optionen so´n Haken für schreibgeschützt. Der ist eigentlich standardmäßig aktiviert. Kann sein, dass das die Quelle des Übels ist.

OK, ist eigentlich nur bei Updates interessant.

Ich habe mal den Code ausprobiert (mk-soft). Geht auch wunderbar mit Dateinamen, die Leerzeichen enthalten. Wahrscheinlich interpretiert er die Anführungsstriche zum Dateinamen und findet keinen solchen?


Gruß Karl

Verfasst: 29.09.2006 12:09
von NicTheQuick
Das Problem ist, dass ohne die Anführungszeichen Base = "" ist.

Sorry, dass ich jetzt so blöd frage, aber ich hab mich mit dem ODBC-Zeugs
noch nie auseinandergesetzt:

Wo gibt es denn den ODBC-Dialog?
Muss ich das für jede Excel-Datei einzeln einstellen oder einfach nur global?

Wäre schön, wenn mich da jemand mal so von Grund auf aufklären könnte.
Also Danke schonmal, wenn's jemand schafft mir zu helfen. <)

sebsch80:
Hab mal die Ausrufezeichen in deinem Thread-Titel gelöscht. Sie waren zu
aufdringlich.

Verfasst: 29.09.2006 12:47
von bobobo
Für jeden ODBCEintrag
Exceltabellen werden einzeln im ODBCManager eingetragen.


Mir fällt zu Excel und ODBC noch ein, das man die Exceltabellen sich
vorher gut angucken und eventuell editieren sollte. Häufig fehlen
Eindeutigkeiten wie aufnumerierte Indexnummern, so daß die
Bearbeitung per SQL dann schwierig wird.

Außerdem muss (!) man einen oder mehrere Bereiche mit Namen
versehen (Spalten auswählen (sollte nicht zu groß sein sonst wirds arschlahm) und oben links in Namenfeld einen Namen eintragen).
Das geht auch blätterübergreifend.
Dies(r)e Name(n) tauch(t)(en) dann in der ODBC-Verknüpfung als
Tabelle(n) auf.

Verfasst: 29.09.2006 16:55
von mk-soft
@NicTheQuick

Mit Anführungszeichen geht es bei mir gar nicht. Mit Leerzeichen funktioniert es bei mir auch.

Als Datenbanktreiber habe ich für Excel und Access die englischen Treiber gewählt. In der Regel sind diese bei Windows immer mit installiert.

"Microsoft Access Driver (*.mdb)"
"Microsoft Excel Driver (*.xls)"

Vielleicht mal Prüfen welche Datenbank Treiber installiert sind.

START -> Ausführen -> odbcad32

Mögliche Treiber sind noch.
"Microsoft Access-Treiber (*.mdb)"
"Microsoft Excel-Treiber (*.xls)"

Für CSV und TXT Dateien
"Microsoft Text Driver (*.txt; *.csv)"
"Microsoft Text-Treiber (*.txt; *.csv)"

Code: Alles auswählen

Driver.s = "Microsoft Excel-Treiber (*.xls)"
Base.s = AddDSN(Driver, Path,"","")
oder CSV, TXT

Code: Alles auswählen

Driver.s = "Microsoft Text Driver (*.txt; *.csv)"
Base.s = AddDSN(Driver, Path,"","")
FF :wink:

Verfasst: 29.09.2006 17:23
von mk-soft
Ich habe das ganze noch mal etwas umgestaltet.

Denn zu verwendeten Treiber Optional auf den letzten Parameter.
Wenn dieser nicht mit angegeben wird, wählt das Programm automatisch aus der Extension den richtigen Treiber aus.

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  : 

; ***************************************************************************************

#ODBC_ADD_DSN = 1; // Add data source 
#ODBC_CONFIG_DSN = 2; // Configure (edit) Data source 
#ODBC_REMOVE_DSN = 3; // Remove data source
#ODBC_ADD_SYS_DSN = 4; // add a system DSN 
#ODBC_CONFIG_SYS_DSN = 5; // Configure a system DSN 
#ODBC_REMOVE_SYS_DSN = 6; // remove a system DSN 
#ODBC_REMOVE_DEFAULT_DSN = 7; // remove the default DSN

; ***************************************************************************************

Procedure.s AddDSN(databasename.s, user.s, pass.s, driver.s = "") ; Result DSN

  ; 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 + ";"  
  
  MyMemory = AllocateMemory(Len(strAttributes))  ; Allocate the memory you need here 
  CopyMemory(@strAttributes, MyMemory, Len(strAttributes))      ; Copy the database information string into the memory space 
  
  For L = 1 To Len(strAttributes)                               ; Check the string in the memory space now 
    If PeekB(MyMemory + L - 1) = Asc(";")                       ; If you find a semicolon anywhere in the string 
      PokeB(MyMemory + L - 1, 0)                                ; Replace it with an empty character as the driver doesn't use it 
    EndIf                                                       ; End the current check 
  Next L                                                        ; Check the next byte 
  
  result = SQLConfigDataSource_(0, #ODBC_ADD_DSN, strDriver, MyMemory)   ; Call the function you need from the ODBC library with the right details 
    
  FreeMemory(MyMemory)                                     ; Free the memory now 
  
  If result
    ProcedureReturn name
  Else
    ProcedureReturn ""
  EndIf

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

Procedure.l RemoveDSN(databasename.s, user.s, pass.s, driver.s = "") 

  ; Databasename erzeugen
  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 = "DSN=" + name + ";"
  
  MyMemory = AllocateMemory(Len(strAttributes))  ; Allocate the memory you need here 
  CopyMemory(@strAttributes, MyMemory, Len(strAttributes))      ; Copy the database information string into the memory space 
  
  For L = 1 To Len(strAttributes)                               ; Check the string in the memory space now 
    If PeekB(MyMemory + L - 1) = Asc(";")                       ; If you find a semicolon anywhere in the string 
      PokeB(MyMemory + L - 1, 0)                                ; Replace it with an empty character as the driver doesn't use it 
    EndIf                                                       ; End the current check 
  Next L                                                        ; Check the next byte 
  
  result = SQLConfigDataSource_(0, #ODBC_REMOVE_DSN, strDriver, MyMemory)   ; Call the function you need from the ODBC library with the right details 
    
  FreeMemory(MyMemory)                                     ; Free the memory now 

  ProcedureReturn result

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

;- Test

#Datenbank = 0

InitDatabase()

Path.s = "D:\Daten\PureBasic4\Database\Telefon Liste.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, "", "")

FF :wink:

P.S. Bei TXT und CSV läuft es etwas anders. Die DSN wird zwar angelegt, aber nur auf den Path zu den Tabellen. In der SQL Abfrage muss dann die Datei mit angegeben werden.

Verfasst: 29.09.2006 17:42
von ts-soft
@mk-soft
Danke, sehr brauchbar :allright:

PS: Mit Variablendeklaration wäre es schöner

Gruß
Thomas