Echange entre Excel et access
Bonjour,
J'essaie de m'auto-former sur la liaisons excel Access.
J'essaie de comprendre le language SQL qui n'a pas l'air si compliqué...
Cependant toute mes tentatives de code se solde par un echec...
Je suis passé par le Query mais le fait de retravailler les données sous forme de tableauexcel ne me plait pas forcément.
J'aimerai savoir comment on peut faire pour récupéré des infos d'Access dans un Userform type listview ou listbox sans forcément ouvrir la Database Access.
Merci pour vos éclaircissement.
ci joint des Tests que j'ai pu trouver sur le net. En BdD un simple fichier excel avec une table première colonne bleu blanc rouge deuxième colonne 1, 2, 3 juste pour faire des tests (le forum ne prendre pas la database access)
Bonjour,
Voici une démo. C'est un fichier Excel qui se synchronise avec la base Access qu'on choisit au début de l'utilisation.
Il y a donc une lecture/écriture dans les 2 sens.
Pierre
Bonjour pierre,
je comprends le concept, je crois bien que si le fichier est dans le meme dossier que la database on peut le séléctionner automatiquement avec un truc du style activeworkbook.path &database.accdb ??
serais t'il possible de le récupérer dans un Userform?
Bien cordialement,
Nicolas
j'en suis arrivé ici je pense que sa fonctionne mais je n'arrive pas à mettre mon rst dans une list d'un UF
Sub getDatawithADO()
'Ajouter la bibliothèque suivante :
'Microsoft activex data objects 2.8 librairy
Dim cnx As New ADODB.Connection
Dim rst As New ADODB.Recordset
'Définition du pilote de connexion
cnx.Provider = "Microsoft.ACE.OLEDB.12.0"
'Définition de la chaîne de connexion
cnx.ConnectionString = "C:\Users\naubin\Desktop\Database71.accdb"
'Ouverture de la base de données
cnx.Open
'Requête déterminant la valeur du recordset
'table1 : c'est la table dans Access
rst.Open "Select couleur, habilitation From table1", cnx
'ici je dois mettre mon rst dans ma listbox ou ma listview
Set rst = Nothing
End Sub
Dans la démo proposée :
- le nom de la base est stockée dans la variable BDD
Cette variable peut être remplie par une ligne du type :
BDD = thisworkbook.Path & "\MaBaseAccess.accdb"
(thisworkbook.Path est à préférer à activeworkbook.Path au cas où plusieurs fichiers Xl sont ouverts en même temps)
- l'import des données se fait dans la procédure "Sub Import_Access". Dans cette procédure :
* on peut préciser la requête comme on veut (cf commandes Sql => https://sql.sh/)
* une fois la requête établie, le résultat est stockée dans la variable tableau T.
Ce contenu peut être collé par exemple dans une listbox, en écrivant une ligne du genre :
UserForm1.ListBox1.List = T
Au final on pourrait avoir du code qui ressemblerait à ceci :
BDD = thisworkbook.Path & "\MaBaseAccess.accdb"
Req = "SELECT `Nom`, `Prénom`,`Adresse perso` FROM [Table_Clients]"
T = Tquery(BDD, Req)
UserForm1.ListBox1.List = T
UserForm1.show
A noter : si en effet il est assez facile d'écrire une requête Sql simple, on peut avoir un niveau de complexité assez élevé.
Juste pour donner un exemple de requête plus complète/complexe, voiçi le code d'une requête d'une de mes appli :
requete = "SELECT O1.PAYS, O1.FOURNISSEURS, O1.PRODUITS, O1.MOIS, O1.T14, O2.T15, O1.V14, O2.V15 " & _
" FROM(SELECT PAYS, FOURNISSEURS, PRODUITS, MOIS, ANNEES, SUM(CA) AS T14, SUM(VOL) AS V14 " & _
" FROM [" & Data1 & "] " & _
" WHERE ANNEES=" & annee_1 & _
" GROUP BY PAYS, FOURNISSEURS, PRODUITS, MOIS, ANNEES) AS O1" & _
" LEFT JOIN (SELECT PAYS, FOURNISSEURS, PRODUITS, MOIS, ANNEES, SUM(CA)AS T15, SUM(VOL)AS V15 " & _
" FROM [" & Data1 & "] " & _
" WHERE ANNEES=" & annee_2 & _
" GROUP BY PAYS, FOURNISSEURS, PRODUITS, MOIS, ANNEES) AS O2" & _
" ON O1.PAYS=O2.PAYS AND O1.FOURNISSEURS=O2.FOURNISSEURS AND O1.PRODUITS=O2.PRODUITS" & _
" ORDER BY O1.MOIS "
Pierre
Voici du code fonctionnel.
* le code d'un module à copier/coller tel quel dans un module quelconque
* ensuite pour interroger la base access :
Dim Bdd as string, Req as string, T as variant
Bdd="C:\Users\naubin\Desktop\Database71.accdb"
Req = "Select `couleur`, `habilitation` From [table1]"
Connect_Access Bdd
T=Select_Db(Req)
Close_Cnx
UserForm1.ListBox1.List = T
UserForm1.show
(la listbox est bien sûr multi-colonnes)
nb : attention aux crochets entourant le nom de la table, et les `` (optionnel mais conseillé) entourant le nom
des champs
`` s'obtient avec Alt-Gr + 7 2 fois
Niquel je te remercie !!
rst.Open "Select `Nom_Prénom`, `Niveau_Habilitation` From Poste" & poste & " where Nom_Prénom=" & nom, cnx
il me met un message d'erreur
erreur d'éxecution '-2147217900(80040e12)':
<< Nom_Prénom=NOM PRENOM>>:
alors que NOM PRENOM sont bien dans ma bdd ...
Si la valeur nom
est du texte (non numérique à priori) dans une table nommée Poste
il faut écrire :
"Select `Nom_Prénom`, `Niveau_Habilitation` From [Poste] where `Nom_Prénom`='" & nom & "'"
En gardant les bonnes habitudes : crochets entourant le nom de la table, Alt-gr 7 pour les champs
Attention ici la variable nom
est entourée de guillemets simples (du 4)
merci pour tes retour ma table varie aussi cest Poste & poste
poste=une variavble entre 1 et 36 défini préalablement
OULA!!! 36 tables de structure identique dans une base de données!!
C'est pas sérieux!! Ou alors il faut vite changer de prestataire!!
bonjour
salut au passage Pierre
tu as raison, s'il y a vraiment 36 tables identiques, il y a un souci de conception
concernant la lecture de données Access par Excel
https://www.youtube.com/watch?v=gwW2CDdvUUs
il est inclus dans les versions plus récentes d'Excel
il lit en une fraction de seconde une grosse masse de données (Access et plus de 100 autres formats)
très puissant et très fiable
amitiés à tous
Bonjour,
C'est pas moi qui ai fait la base de donnée moi je cherche juste les solutions ^^'. je pourrai à a limite fusionner toute ces tables en une seul, et ou les transformer en requête ...
Donc le mieux c'est de fusionner toute ces tables et de faire mes requête sql dans une mono table?
Bonjour
Bien sûr!
Si l'intention est de pouvoir distinguer 36 secteurs différents, il est mieux d'avoir une table unique avec un champs "secteur". Du genre :
Nom_Prénom / Habilitation / Secteur
Nicolas/ Forte / Service bidule
Pierre / Faible / Service truc
Ensuite on peut requêter en fonction(ou non) de ce nouveau champs, par exemple :
"SELECT ... WHERE Secteur='Service truc' AND Nom_Prénom='Pierre'"
C'est plus simple que de faire des "UNION" sur 36 tables si on veut avoir une liste complète de tout le monde par exemple.
Pierre
Heum,
Je te suggère d'exposer ta problématique pour qu'on puisse te proposer une structure adéquate.
A première vue, il me semble qu'il faudrait 2 tables (au moins) avec une relation 1 à n
Pierre
deux étapes:
-une table avec les Nom_Prénom et tous les postes aux niveau des champs car je met un niveau d'habilitations =1 ou 2 ou 3 ou 10 ou 20 ou 30 cf tableau deux ci dessus
( Dans le même table je voulais mette les Date de poste c'est à dire à chaque fois que je modifie une habilitation d'un gars dans sur un poste du tableau deux je viens modifier la date qui fait ref à ce poste, cf Tableau trois ci dessus)
-Enfin le pointage un système de pointage un peu comme le tableau deu xmais au lieux de mettre des habilitations mettre des heures de pointages cf tableau 4
ça c'est le sujet ^^"
C'est pas clair tout ça.
C'est quoi pour toi un niveau d'habilitation? Pourquoi ça évolue dans le temps?
C'est quoi un poste? Pourquoi 36?
C'est quoi ton système de pointage?
Est-ce qu'un même jour le gars peut faire plusieurs postes et plusieurs horaires?
tes habilité:
- 1 2 ou 3 pour représenter 1 en formation 2 habilité 3 "habiliteur"
- 10 20 ou 30 pour représenter 10 à reformer 20 à réhabiliter 30 "habiliteur" à réhabiliter
un poste c'est l'équivalent d'une ligne de production
le poste 1 = poste 1 de la ligne Dupond
le poste 2 = poste 2 de la ligne Dupond
poste 3 = le poste 1 de la ligne Durand
poste 36 = poste 1 de la ligne Banane
un système classique avec le nombre d'heure réalisé par poste et par nom prénom =7h35 par défaut.
et oui la ou ca se complique c'est que un gars peut faire plusieurs poste dans une journée... même si c'est rare mais ca arrive quand même.
Alors pour ce que je pense comprendre, il me semble qu'il faudrait 3 tables.
* une table "Opérateurs" avec nom, prénom, etc... avec clé primaire "Id"
* une table "Habilitations" avec relation Opérateurs.Id <=> Habilitations.Id_O (1 à n)
contenant une date de début et un code habilitation
* une table "Postes" avec relation Opérateurs.Id <=> Postes.Id_O (1 à n)
contenant une date, des horaires (ou une durée) et le code " poste" (1à36)
voir schéma (astérisque+gras+souligné=clé primaire, gras+souligné=clé étrangère)