Salut,
Je cherche à créer une table access à partir d'un recordset, je suppose que c'est possible mais je ne sais pas comment faire...
Help ! Please...
Salut,
Je cherche à créer une table access à partir d'un recordset, je suppose que c'est possible mais je ne sais pas comment faire...
Help ! Please...
Va voir les tuto, ils sont assez bien faits...
http://warin.developpez.com/access/dao/
N'oubliez pas de mettre le
Si je poste un message, c'est bien parce que je n'ai pas trouvé solution à mon problème.
Genre, t'es dans une piscine, tu sais pas très bien nager, tu vas te noyer, et le maître nageur te dit : nage !
Sa fait un moment que je patoge et que je bois la tasse ... Mais j'ai cherché et j'ai pas trouvé.
Je demandes juste de l'aide pas de la redirection !
Cela dit je te remercie de ton aide !
Hummm... Un nerveux... Ok, alors je vais poser mes questions tout doucement pour ne pas te rendre plus agressif...
1°)Dans ton RecordSet, tu as quoi? Le contenu de la table que tu veux créer? Et tu l'as remplis comment?
2°) Ta table, elle sera dans quoi? Access, Oracle, MySql?
3°) Les noms des colonnes de ta future table, il faudra les deviner, ou on peut choisir des noms de Dieux Grecs? (ça, c'est pour voir si tu t'emballes encore ou pas)
Je ne suis pas un nerveux , le problème c'est que c'est le genre de réponse de réponse qu'on n'aime pas avoir quand on galère... Bref on ne va pas épiloguer là dessus ! Je te remercie déjà de ton attention .
Alors le recordset je l'obtiens en effectuant une requête sur un serveur SQL. En faisant un recordcount, je sais que mon recordset n'est pas vide.
Donc pour l'instant j'ai un recordset plein, et j'aimerais stocker ses données dans une table ou un élément query dans la base de données locales.Donc la table sera dans access localement.
Pour le nom des colonnes, supposons que ce sont des noms de dieux Egyptiens... Y'en a pleins ! Est-ce que la table ne peut pas être créée suivant le modèle du recordset ?...
Merci de ton aide !
Faut il absolument que ce soit du code VBA? Sinon je peux te proposer une autre solution... Tu crée une requete 'ajout - Creation de table' dans access qui se connecte a SQL Server et copie ta table SQL Server... Ca marche tres bien...
Eventuellement tu code une petite macro qui sera bien plus simple a faire avec access qui lance cette requete...
Désolé je pensais que tu n'avais pas lu les tuto.
N'oubliez pas de mettre le
Concernant la copie complète de la table, j'y avais pensé et j'avais déjà essayé... Le seul problème 'est que la table compte 18900 enregistrements donc je ne peux pas tous les prendre d'un coup.
Donc je voulais récupérer uniquement les données qui m'interressent, les mettre dans une table et faire le traitement à partir de la table créée...
J'ai essayé les solutions simples... Mais sa prend trop de temps !
C'est juste cette transformation qui me pose pb !
Et bien c'est tout a fait possible dans accessDonc je voulais récupérer uniquement les données qui m'interressent, les mettre dans une table et faire le traitement à partir de la table créée...
Tu crée une table liée dans access (lien vers SQL Server)
Tu crée une requete dont la source de donnée est cette table liée et tu met les criteres que tu veux dans la requete en mode création, donc uniquement les enregistrements que tu veux importer et ensuite tu change le type de requete en une requete mise a jour, création de table
, il va te demander ou les importer dans quelle nouvelle table ou existante et la le tour est joué...
N'oubliez pas de mettre le
J'ai déjà essyé avec une table liée, ce que je ne comprends pas c'est que sur les 18900 enregistrements je n'en ai que 4823 de disponibles quand j'ouvre cette table liée...
Etant donnée que c'est une manipulation qui se fait toute les semaines et que ce n'est que le début d'un ensemble d'opérations je voulais automatiser tout sa !
Si j'arrive à avoir le nombre d'enregistrements je penses que je suis proche de la solution. Je vais me casser la tête encore un peu.
Merci de ton aide !
J'ai été oublié, je crois que j'ai trouvé une piste...
Mon problème c'est que je dois initialiser un recordset pour la table locale.
Pour la copie sa devrait être bon !
Help , the last breathe ...
En tant que "grand maitre de la moulinette VB" dans ma société, je pense pouvoir faire ça sans problème.
Cependant, pour éviter de pédaler dans le vide et pour donner directement du code efficace, j'ai besoin des infos suivantes:
- Le nom de la table cible dans la base Access (et quelle version d'Access)
- le texte complet de la requête SQL
- la méthode utilisée en VB pour l'accès à la base source (SQL direct, DAO, ADO, RDO, ADODB...)
- La méthode utilisée pour récupérer le recordset
Le mieux serait de mettre le bout de code qui lance la requête et récupère le recordset.
Au fait, tu ne dis pas la méthode utilisée pour savoir le nombre d'enregistrements du recordset. Si c'est avec RecordCount, il faut avoir fait un MoveLast pour que l'info soit correcte. C'est peut être le cas, mais on ne sait jamais...
Avec DAO (c'est la méthode que j'utilise toujours car c'est de loin la plus efficace, bien que déclarée obsolète par Microsoft), on obtient le nom des champs avec un code du genre (Rs est un recordset de la classe DAO.Recordset) :
Ben tiens, pendant que j'y étais, j'ai créé un petit projet et j'ai développé le code ci-dessous. Je précise que ce code a été testé et fonctionne. La base source et la base destination sont toutes les deux des tables Access (la source, Access2000, la destination, Access2003).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Dim Fd as DAO.Field For Each Fd in Rs.Fields debug.? rs.name Next
Dans une form, on trouve le code d'appel de la procédure:
Bon courage...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 Private Sub cmdCreerTable_Click() Dim Rs As DAO.Recordset, Db As DAO.Database Set Db = OpenDatabase("D:\_Portable\Access\Test2000.mdb") Set Rs = Db.OpenRecordset("AscomParents", dbOpenTable) CreerTable Rs End Sub Ailleurs (peu importe où, dans ce cas c'est un module), on trouve la routine suivante: Public Sub CreerTable(ByVal rsSrce As DAO.Recordset) Dim Db As DAO.Database 'Base de données cible Dim Td As DAO.TableDef 'Table à créer Dim rsDest As DAO.Recordset 'Contenu de la table cible Dim fdSrce As DAO.Field 'Champ générique du recordset source Dim fdDest As DAO.Field 'Champ générique de la table à créer 'Création de la structure de la table Set Db = OpenDatabase("D:\_Portable\Access\Test2003.mdb") 'Table cible Set Td = New DAO.TableDef Td.Name = "TheTable" For Each fdSrce In rsSrce.Fields Set fdDest = New DAO.Field fdDest.Name = fdSrce.Name fdDest.Type = fdSrce.Type Select Case fdDest.Type Case dbBinary, dbLongBinary, dbText 'Champs de taille réglable fdDest.Size = fdSrce.Size Case Else 'On ne fait rien car la taille est implicite End Select Td.Fields.Append fdDest 'Ajout du champ à la table Next Db.TableDefs.Append Td 'Ajout de la table à la base 'Vérification que le recordset source n'est pas vide If rsSrce.EOF Then Exit Sub 'Ouverture de la table cible pour le remplissage Set rsDest = Db.OpenRecordset(Td.Name, dbOpenTable) 'Remplissage des données de la table rsSrce.MoveFirst Do Until rsSrce.EOF rsDest.AddNew For Each fdSrce In rsSrce.Fields rsDest.Fields(fdSrce.Name) = fdSrce Next rsDest.Update rsSrce.MoveNext Loop 'Fermeture propre du total (facultatif) sauf le recordset source '(il peut être encore utilisé par la procédure appelante) rsDest.Close Set rsDest = Nothing Set Td = Nothing Db.Close Set Db = Nothing End Sub
Ben je te remerci grandement de ton aide MGD !
Je penses que le bout de code que tu m'as passé me servira grandement...
- Table source :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Let str = "Provider=MSDASQL;DSN=REVIEW;UID=TEMP;PWD=;" Set db = ws.OpenDatabase("REVIEW", True, False, str)
- Table cible - Access 2002:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Set Db_curr = CurrentDb()
- Requête SQL - j'en ai mis une simple :
sqlquery = "SELECT * FROM call_req"
- Méthode utilisée pour récupérer le Recordset :
Monrs.Open sqlquery, str, adOpenStatic, adLockReadOnly
En fait j'ai créé un recordset ADODB
- Méthode utilisé pour accès à la base source
Je t'ai tout mis !
Voici le code complet si sa ne suffit pas :
PS : Désole du retard de la réponse je n'ai plus le net chez moi ! Merci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 Dim Monrs As ADODB.Recordset Dim Localrs As Recordset Dim qdf As QueryDef Dim Db_curr As Database Dim sqlquery As String Dim ws As Workspace Dim db As Database Dim str As String sqlquery = "SELECT * FROM call_req" Set Monrs = New ADODB.Recordset DoCmd.Hourglass True Set ws = DBEngine.Workspaces(0) Let str = "Provider=MSDASQL;DSN=REVIEW;UID=TEMP;PWD=;" Set db = ws.OpenDatabase("REVIEW", True, False, str) Monrs.Open sqlquery, str, adOpenStatic, adLockReadOnly Set Db_curr = CurrentDb() Set Localrs = db While Not Monrs.EOF Localrs.AddNew For i = 0 To Monrs.Fields(i).Value Next Localrs.Update Monrs.MoveNext Wend If Monrs.EOF Then Monrs.MoveFirst MsgBox Monrs.RecordCount Monrs.Close db.Close DoCmd.Hourglass False
Désolé pour l'allure du code, j'avais oublié de mettre l'attribut qui va bien et le HTML a dévoré toutes mes belles indentations. C'est réparé.
Comme je l'ai dit, je maitrise mal ADODB et j'utilise ADO. Si tu veux pouvoir utiliser in extenso (ou presque) le code de ma dernière contribution, il suffit de passer en ADO. Pour cela, il faut aller dans un module de code, utiliser le menu "Outils / Références" et cocher la case Microsoft DAO 3.6 Object Library.
Le problème dans ton code est que tu crées bien un recordset, mais que ce dernier est volatile : il n'existe qu'en mémoire et ne constitue en aucune façon une table. Pour créer une table et la remplir, il faut:
- Créer une table vide
- Pour chaque champ, créer un objet champ vide
- Affecter les différents paramètres du champ nouvellement créé
- Ajouter ce champ à la table (une fois ajouté, on ne peut plus modifier la plupart de ses paramètres)
- Quand tous les champs sont ajoutés, ajouter la table à la base (une fois ajoutée, il est compliqué de créer de nouveaux champs, et certaines propriétés de la table ne sont plus modifiables)
- Qand la table est ajoutée à la base, alors seulement on peut ouvrir un recordset dessus et ajouter des enregistrements.
Il est également possible de faire tout cela avec des instructions SQL standard, du type:
La première ligne crée la table (vide)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 CREATE TABLE 'MaTable' ALTER TABLE 'MaTable' ADD 'Champ1' type(taille), Champ2 type(taille)... INSERT INTO 'MaTable' ('Champ1', 'Champ2', ...) VALUES (ValeurChamp1, ValeurChamp2,...) UPDATE 'MaTable' SET 'Champ1'=Valeur1, 'Champ2'=Valeur2,... WHERE 'ID'=ValeurCle
La seconde ligne crée les champs de la table
La troisième ligne ajoute un enregistrement à la table.
La quatrième ligne modifie un enregistrement spécifié par la valeur ValeurClé de la clé primaire ID (il peut y avoir d'autres critères de sélection)
Cela nécessite cependant une bonne connaissance du langage SQL. C'est obligatoire quand on travaille avec certaines bases de données comme MySQL (et qu'on a pas accès à l'interface PHP qui va avec). Je pense que la méthode VB est plus facile. Le INSERT INTO reste cependant nécessaire en VB lorsqu'on s'attaque à des serveurs distants du type SQL Serveur ou ORACLE en mode direct, car les recordsets qu'on ouvre sur les tables sont en lecture seule.
Fait curieux: j'ai collé ton code dans un module Access 2003, car les fonctions CurrentDb et DoCmd sont spécifiques d'Access et j'en ai conclu que ce code n'est pas du VB mais du VBA. Or il plante dès le départ car il ne reconnait pas ADODB. Je croyais qu'ADODB était natif dans acces 200x. Il faut croire que ce n'est pas le cas. En ajoutant la référence à Microsoft ActiveX Data Objects, il reconnait ADODB mais pas la constante adLockReadOn. Je n'ai pas insisté.
Si tu décides d'utiliser DAO, ton code devient :
Dans la procédure CreerTable, si la base et la même que la base source, il suffit de la passer en paramètre et de supprimer l'ouverture de la base. Sinon, mets son nom dans la ligne OpenDatabase au lieu de D:\..., et change le nom de la table deux lignes plus bas. Si la base cible est la base courante, il suffit de remplacer la ligne comportant OpenDatabase par
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 Dim Monrs As DAO.Recordset Dim Localrs As DAO.Recordset Dim qdf As QueryDef Dim Db_curr As Database Dim sqlquery As String Dim ws As Workspace Dim db As DAO.Database Dim str As String sqlquery = "SELECT * FROM call_req" DoCmd.Hourglass True Set ws = DBEngine.Workspaces(0) Let str = "Provider=MSDASQL;DSN=REVIEW;UID=TEMP;PWD=;" Set db = ws.OpenDatabase("REVIEW", True, False, str) Set Monrs = db.OpenRecordset(sqlquery, dbOpenSnapshot) CreerTable Monrs DoCmd.Hourglass False
Set Db = CurrentDb
Notes que l'utilisation de ws est facultative car Access utilise toujours WorkSpaces(0) par défaut. Il n'est donc paq nécessaire de la préciser.
Il est clair qu'il doit exister rigoureusement la même chose en ADODB, mais la syntaxe est différente et je n'ai ni l'envie ni le courage de me replonger dans une méthode qui risque encore d'être obsolète dans peu de temps : il en sort pratiquement une par an : ADO, RDO, DAO, ADODB,.... (merci Bill !). J'attendrai la prochaine pour me réactualiser.
Bon courage.
Je te remercie vraiment pour toutes ces explications.
J'essaie sa et je te tiens au courant !
Bon alors conclusion sa commence à fonctionner !
J'ai une erreur runtime 3315, parce que j'ai un champ est vide.
J'ai chercher des réponses concernant cette erreur et on me dit de réactiver la propriété , possibilité de mettre des champs vides: AllowZeroLength.
Mais je ne la trouve pas !
Je sais qu'en SQL il y une commande qui permet de remplacer un champs particulier par un autre donc un champs vide par " ", mais je ne me rappelle plus.
A part cette petite erreur, tout semble fonctionner correctement !
Je connaissais les commandes en SQL permettant de créer la table mais tu ne peux l'utiliser que lorsque tu connais tous les champs de ta table....
Un dernier petit coup de pouce... ne serait pas de refus !
Le coup des champs vides, c'est une grande classique!
La solution c'est de faire, dans la boucle qui met à jour les champs :
Comme ça, le champ destination reste Null aussi si le source est vide.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 For Each fdSrce In rsSrce.Fields If Not IsNull(fdSrce) then rsDest.Fields(fdSrce.Name) = fdSrce End If Next
Désolé de ne pas y avoir pensé du premier coup !
Je connaissais les commandes en SQL permettant de créer la table mais tu ne peux l'utiliser que lorsque tu connais tous les champs de ta table....
Je t'ai déjà donné la solution : avec un "For Each Fd in Rs.Fields" on récupère la liste des champs, et leur nom avec la propriété Fd.Name.
Mais si ça marche avec DAO, c'est plus simple...
Courage, tu vas y arriver !
Toujours la même erreur... il commence à enregistrer mais après il coupe ... à cause d'un champ.... j'essai de voir où se trouve le problème, mais c'est pas évident !
J'essai 2 méthodes en même temps, j'ai créé une vue sur le serveur, pour avoir toutes les données d'un coup .
Mon pb c'est que je n'arrive pas à importer la vue....
Quel est le libellé de l'erreur 3315 ? (je ne peux pas la reproduire, car il faut être dans le contexte, sinon error$(3315) renvoie "Erreur définie par l'application ou par l'objet, ce qui ne fait pas avancer le schmilblick).
Erreur 3315 : Field 'TheTable.category' cannot be a zero-lenght string.
C'est quand on fait le rsDest.update.
En fait, j'ai bien compris que c'est par rapport à ce champ qui est certainnement vide....
Très grand merci pour ta patiente....
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager