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

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

Et voilà...