Seite 2 von 2

Verfasst: 29.09.2006 17:46
von mk-soft
CSV und TXT klappt noch nicht.
Vielleicht weiss einer noch rat.

FF :|

Verfasst: 29.09.2006 18:41
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, "", "")

Verfasst: 29.09.2006 19:04
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.

Verfasst: 29.09.2006 19:38
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

Verfasst: 29.09.2006 19:58
von mk-soft
@ts-soft

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

Edit: Update GetTables()

Verfasst: 29.09.2006 22:11
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

Verfasst: 30.03.2007 16:27
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:

Verfasst: 30.03.2007 17:59
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:

Verfasst: 30.03.2007 18:04
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:

Verfasst: 30.03.2007 18:17
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