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
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

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

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
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
PS: Mit Variablendeklaration wäre es schöner
Gruß
Thomas