OBDC Le nom des tables dans fichier "mdb"

Programmation d'applications complexes
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

OBDC Le nom des tables dans fichier "mdb"

Message par GeBonet »

Bonjour,

J'avais un problème, résolut ici. Mais le code est probablement a améliorer :?
Utiliser un fichier "Access" était pas trop compliqué, mais en extraire les noms des tables ou requête en était une autre...
La solution est ci dessous avec l'aide de SRod... pour les tables.

Il faut évidement pour bien faire disposer d'un fichier ACCESS :D

Code : Tout sélectionner

; ====================================================================
;  Comments extraire les NOMS des tables ou Requêtes d'un fichier de type ACCESS (*.mdb)...
;  Les titres de colonnes de chaque Tables ... Et, enfin les données de chaque tables...                
;                                                                                                                                                            
;  Je remercie SRod pour la manière d'extraire les TABLES ...                                  GeBonet          
; =====================================================================
;  A Utiliser a partir d'un fichier "Machin.mdb" contenant plusieurs tables... C'est mieux :-)               
;   On appelle donc DSN (Data Source Name) la déclaration de la source de données qui                
;   sera accessible par l'intermédiaire de ODBC.                                                                                
; =====================================================================
; A essayer sur une base à essayer 
; ----------------------------------------------------------------------------------------------------------------------------
;  
    #SQL_SUCCESS = 0
    #SQL_SUCCESS_WITH_INFO = 1
    #SQL_NO_DATA = 100
    #SQL_NULL_HANDLE = 0
    #SQL_HANDLE_ENV = 1
    #SQL_HANDLE_DBC = 2
    #SQL_HANDLE_STMT = 3
    #SQL_ATTR_ODBC_VERSION = 200
    #SQL_OV_ODBC3 = 3
    #SQL_NTS = -3
    #SQL_DRIVER_COMPLETE = 1
    #SQL_C_CHAR = 1
    #SQL_C_WCHAR = -8
    #SQL_MAX_TABLE_NAME_LEN = 35
    ; 
    ; The following compiler directive accounts for Ansi and Unicode modes.
    ; Les directives pour le compilateur selon que l'on utilise l'Ansi ou l'Unicode.
    ; 
    CompilerIf #PB_Compiler_Unicode
        #SQL_CHAR = #SQL_C_WCHAR
    CompilerElse
        #SQL_CHAR = #SQL_C_CHAR
    CompilerEndIf

Enumeration 0                                       ;- Types de donnees des lignes
    #ODBC_UNKNOW
    #ODBC_NUMERIC
    #ODBC_STRING
    #ODBC_FLOAT
EndEnumeration

Enumeration 1
    #ODBC_ADD_DSN                             ; Add a new user Data source. 
    #ODBC_CONFIG_DSN                       ; Configure (modify) an existing user Data source. 
    #ODBC_REMOVE_DSN                     ; Remove an existing user Data source.
    #ODBC_ADD_SYS_DSN                    ; Add a new system Data source.
    #ODBC_CONFIG_SYS_DSN              ; Modify an existing system Data source.
    #ODBC_REMOVE_SYS_DSN            ; Remove an existing system Data source.
    #ODBC_REMOVE_DEFAULT_DSN   ; Remove the default data source specification section from the system information.
EndEnumeration
;
    #ODBC_DRIVER_MSACCESS = "Microsoft Access Driver (*.mdb)"

Global Dim DatabaseType.s(4)            ;- Types de donnees de la BD
    DatabaseType(#ODBC_UNKNOW)  = "Unknown"
    DatabaseType(#ODBC_NUMERIC) = "Numeric"
    DatabaseType(#ODBC_STRING)  = "String"
    DatabaseType(#ODBC_FLOAT)   = "Float"
    
Global hasBD.b, DSN.s, Rep3$
    #Database        = 1
    #BD_NAME$    = "Biblio.mdb"                      ; <=====    NOM DE LA BASE DE DONNES ICI !!!! "divx.mdb"
     DSN = "TEST" ;"Pb_Test" ;                             
    dsn$=DSN 
    
Global myConnection, MyTable
Global Dim TableMDB$(MyTable)                   ; Pour mémoriser les noms des tables....

    Rep3$=GetPathPart(ProgramFilename())   ; Repertoire actuel du programme.
    SetCurrentDirectory(Rep$)                           ; Permet de stabiliser le répertoire... 
    Debug "3- "+Rep3$
    Sp$=" => "
;
; =====================================================
;  Procédure POUR seulement regarder (extraire) les tables / SRod 
; =====================================================
;  Set the 'blnListAllObjects' parameter to #True if you wish to list all objects.
;  You have to do this in the case of the MS Excel ODBC driver for example.
;  Returns zero if no error else returns an SQL error code.
;
;  Réglez le paramètre 'blnListAllObjects' à True# si vous le souhaitez lister tous les objets. 
;  Vous devez le faire dans le cas du pilote ODBC Microsoft Excel par exemple.
;  Retourne zéro si aucune erreur sinon retourne un code d'erreur de SQL.   
; 
Procedure.l ODBCListTables(dsn$, blnListAllObjects = #False)
    
    Protected result.w, env, dbc, stmt, table, len
    Protected tableNameMaxSize, tableName$
    ; Create an environment handle and set the environment attribute to use ODBC 3
    ; Créer et configurer l'environnement apte à utiliser ODBC 3.
    SQLAllocHandle_(#SQL_HANDLE_ENV, #SQL_NULL_HANDLE, @env)
    SQLSetEnvAttr_(env, #SQL_ATTR_ODBC_VERSION, #SQL_OV_ODBC3, 0)
    ; Allocate a connection handle. Allouer un descripteur d'instruction
    SQLAllocHandle_(#SQL_HANDLE_DBC, env, @dbc);
    ; Connect to the database. Connection sur la base de données... 
    result = SQLDriverConnect_(dbc, #Null, dsn$, #SQL_NTS, #Null, 0, #Null, #SQL_DRIVER_COMPLETE)&$ffff
    ; 
    If result = #SQL_SUCCESS Or result = #SQL_SUCCESS_WITH_INFO
        SQLGetInfo_(dbc, #SQL_MAX_TABLE_NAME_LEN, @tableNameMaxSize, 4, 0)
        tableName$ = Space(tableNameMaxSize+1)
        ; Allocate a statement handle - Allouer un descripteur d'instruction
        SQLAllocHandle_(#SQL_HANDLE_STMT, dbc, @stmt)
        ; Retrieve a list of tables - Récupérer une liste de tables
        If blnListAllObjects
            SQLTables_(stmt, #Null, 0, #Null, 0, #Null, 0, 0, 0)
        Else
            SQLTables_(stmt, #Null, 0, #Null, 0, #Null, 0, @"TABLE", #SQL_NTS)
        EndIf
        ; Boucle à travers les tableaux -- Loop through the tables .
        SQLBindCol_(stmt,3,#SQL_CHAR,@tableName$, (tableNameMaxSize+1)<<(SizeOf(CHARACTER)-1), 0)
        result = SQLFetch_(stmt)
        While result = #SQL_SUCCESS
            table+1:MyTable=table                                     ; Compte les Tables... 
            Debug "Table " + Str(table) + " is named : " + tableName$
            result = SQLFetch_(stmt)
            ReDim TableMDB$(MyTable)                          ; Redimension pour les nouvelles tables... 
            TableMDB$(MyTable)=tableName$                 ; Mémorisation des Tables... 
        Wend
        If result = #SQL_NO_DATA
            result = #SQL_SUCCESS
        EndIf
        SQLFreeHandle_(#SQL_HANDLE_STMT, stmt);
        SQLDisconnect_(dbc)
    EndIf
    ;Free the handles - .
    SQLFreeHandle_(#SQL_HANDLE_DBC, dbc);
    SQLFreeHandle_(#SQL_HANDLE_ENV, env)
    ProcedureReturn result
      
EndProcedure
; =====================================================
; Partie plus commune...
;
Procedure.l MSAccess_AddConnection(name.s, database.s, hwnd.l = #Null) ; Initialise l'espace pour l'ouverture a suivre
    Protected attrs.s
    attrs + "UID="         + ";"
    attrs + "PWD="         + ";"
    attrs + "DSN="         + name + ";"
    attrs + "DBQ="         + database + ";"
    attrs + "FIL="         + "MS Access;"
    attrs + "Driver="      + "ODBCJT32.DLL;"
    attrs + "DefaultDir="  + GetPathPart(database) + ";"
    attrs + "Description=" + FormatDate("Créé le %dd-%mm-%yyyy, %hh:%ii:%ss;", Date())
    ReplaceString(attrs, ";", #NULL$, 2)
    Debug "Initialisation = "+attrs
    Debug "===================================" 
    ;ODBCListTables(attrs, blnListAllObjects = #False) ; dsn$
    ProcedureReturn SQLConfigDataSource_(hwnd, #ODBC_ADD_DSN, #ODBC_DRIVER_MSACCESS, attrs)
    
EndProcedure
Procedure.l MSAccess_RemoveConnection(name.s, hwnd.l = #Null)             ; Libère l'espace de la connection 
  ProcedureReturn SQLConfigDataSource_(hwnd, #ODBC_REMOVE_DSN, #ODBC_DRIVER_MSACCESS, "DSN="+name)
EndProcedure

Procedure BD_Connect(user$, pass$) ;- Connexion a la BD
    If UseODBCDatabase()=#Null
        MessageRequester("Error", "Impossible d'initialiser les drivers BD", #MB_ICONERROR)
        hasBD = #False
        ProcedureReturn #False
    EndIf
    If MSAccess_AddConnection(DSN, #BD_NAME$) = 0
        MessageRequester("Error", "Impossible de créer la connexion à la BD", #MB_ICONERROR)
        hasBD = #False
        ProcedureReturn #False
    EndIf
    ;
    If OpenDatabase(#Database, DSN, user$, pass$)=0
        MessageRequester("Error", "Impossible d'ouvrir la BD", #MB_ICONERROR)
        hasBD = #False
        ProcedureReturn #False
    Else        
        myConnection = DatabaseID(#Database)
    EndIf
    hasBD = #True
    ProcedureReturn #True

EndProcedure
Procedure BD_Close()

    CloseDatabase(#Database)
    MSAccess_RemoveConnection(DSN.s)
    hasBD = #False
EndProcedure
; -------------------------------------------------------------------------------------------------------
Procedure FindIndiceField(champ$)     ;- Recupere l'indice d'un champs après requete
    Protected k.b
     
    For k=0 To DatabaseColumns(#Database)-1
        If DatabaseColumnName(#Database, k) = champ$
            ProcedureReturn k
        EndIf
    Next k
    
    For k=0 To DatabaseColumns(#Database)-1
        If UCase(DatabaseColumnName(#Database, k)) = UCase(champ$)
            ProcedureReturn k
        EndIf
    Next k
    
    Debug ">> Erreur FindIndiceField <<"
    Debug champ$
    
EndProcedure
Procedure.s GetStrField(champ$)       ; - Extrait un indice et les données "string" grace à champ$ 
    Protected ind.b, s$
        ind = FindIndiceField(champ$)
        s$ = GetDatabaseString(#Database, ind)
        ReplaceString(s$, Chr(34), "'", 2)
    ProcedureReturn s$
EndProcedure
Procedure.l GetNumField(champ$)      ; - Extrait un indice et les données numérique "Long" grace à champ$ 
    Protected ind.b
    ind = FindIndiceField(champ$)
    ProcedureReturn GetDatabaseLong(#Database, ind)
EndProcedure
Procedure.f GetFloatField(champ$)     ; - Extrait un indice et les données numérique "Float" grace à champ$ 
    Protected ind.b
    ind = FindIndiceField(champ$)
    ProcedureReturn GetDatabaseFloat(#Database, ind)
EndProcedure
Procedure.l GetNewLine(table$, champ$)                                  ;- Index nouvelle ligne (Auto-Increment)
    If DatabaseQuery(#Database, "SELECT MAX("+champ$+") as max FROM " + table$)
        If NextDatabaseRow(#Database)
            ProcedureReturn(GetNumField("max")+1)
        Else
            ProcedureReturn(1)
        EndIf
    Else
        Debug " -> Erreur dans la recherche du MAX"
        ProcedureReturn(0)
    EndIf
EndProcedure
Procedure.l GetMaxTable(table$, champ$)                                 ;- Max from table
    If DatabaseQuery(#Database, "SELECT MAX("+champ$+") as max FROM " + table$)
        If NextDatabaseRow(#Database)
            ProcedureReturn(GetNumField("max"))
        Else
            ProcedureReturn(0)
        EndIf
    Else
        Debug " -> Erreur dans la recherche du MAX"
        ProcedureReturn(0)
    EndIf
EndProcedure
Procedure.l GetIndexRow(table$, value$, stringField$, numField$) ;- Get Index of a Row

    query$ = "SELECT "+numField$+" FROM " + table$ + " WHERE "+stringField$+" = "+value$
    ; Debug query$
    If DatabaseQuery(#Database, query$)
        If NextDatabaseRow(#Database)
            ProcedureReturn(GetNumField(numField$))
        Else
            Debug "ERR: GetIndexRow -> Pas de ligne sélectionné"
            ProcedureReturn(0)
        EndIf
    Else
        Debug "ERR: GetIndexRow -> Erreur dans la requête"
        ProcedureReturn(0)
    EndIf
EndProcedure
; =================================================================
;  Appel de la Procédure pour extraire les NOMS des TABLES ou REQUETES voir les deux 
;  de la base de données types MDB. 
;  Extrait les LES Tableaux / Objets trouvés en fonction de la valeur du paramètre "blnListAllObjects". 
;   
    
    BD_Connect(user$, pass$)                ; Ouvrir l'accès à la BD...
    Resultat = IsDatabase(#Database)    ; C'est OK ? 
    ; Indique quelle Base de Donnée est concernée
    ;    ODBCListTables(#BD_NAME$, blnListAllObjects = #False) 
    ; Ainsi, en supposant que vous avez configuré un DSN avec le nom TEST puis vous appelez 
    ; la fonction comme ceci:
    ; 
    ;    ODBCListTables("DSN=TEST;", 1) ; Ici "blnListAllObjects =1 => donne tout, les requeste$ et les Tables...
    ;            OU : 
       ODBCListTables("DSN=TEST;", 0) ; Ici "blnListAllObjects = 0 => Seulement les Tables... 
    ;
    Debug "===================================" 
    Debug "Nombre de tables = "+Str(MyTable)
    ;  
; =================================================================    
    Dim Type(0) 
    Dim Titre$(0) 
    ; ----------------------------------------------------------------------------------------------------------------------
    If Resultat<>0
        Debug "Base de donnees = "+Str(Resultat) +" OK" ; <>0 = OK
        Debug "===================================" 
        ; ------------------------------------------------------------------------------------------------
        For k=1 To MyTable
            Requete$="Select * FROM "+TableMDB$(k) 
            If DatabaseQuery(#Database, Requete$)                                         
                numColumns = DatabaseColumns(#Database) ; myConnection)
                ReDim Titre$(numColumns)                                                         
                ReDim Type(numColumns)                                                          
                ; --------------------------------------------------------------------------
                Debug "=====< "+TableMDB$(k)+" >================"            
                For i=0 To numColumns-1 
                    Titre$(i) = DatabaseColumnName(#Database, i) 
                    Type(i) = DatabaseColumnType(#Database, i) 
                    Debug ">"+Str(i+1)+" : "+Titre$(i)+Sp$+" Type : "+Str(Type(i)) 
                Next i                
                Debug "===================================" 
                ;  Champs de la Table 
                While NextDatabaseRow(#Database)  
                    For i=0 To numColumns-1
                        ; If Type(i)=2:No$+GetStrField(Titre$(i))+" : ":EndIf              ; Utilisation procédures API extraction chaine           
                        ; If Type(i)=1:No$+Str(GetNumField(Titre$(i)))+" : ":EndIf    ; Utilisation procédures extraction numérique   
                        ;  
                        If Type(i)=2:No$+GetDatabaseString(#Database, i)+" : ":EndIf   ; Forme d'appel direct via commande PB. 
                        If Type(i)=1:No$+GetDatabaseString(#Database, i)+" : ":EndIf                                                                          
                    Next i                
                    Debug No$ 
                    No$="" 
                Wend      
                FinishDatabaseQuery(#Database) 
            Else               
                MessageRequester("Erreur", "Impossible d'executer la requete: "+DatabaseError())
            EndIf              
        Next k                                  
    Else                  
        MessageRequester("Erreur : ", "Impossible d'ouvrir la base de donnée : "+#BD_NAME$)
    EndIf               
;   Permanent ...   
    BD_Close()      
      
End
Si ce n'est pas connus et que ça peut aider, alors voilà.... :roll:
Et voilà...
Windows 7 et Windows 8.1 Pb 5.0 jusque 5.24 Lts 64 et 5.3 (64)/b]
“Ceux qui rêvent éveillés ont conscience de mille choses qui échappent à ceux qui ne rêvent qu’endormis.”
-Edgar Allan Poe-