[Access 2003] - SQL/VBA relation 1 à 1

[Résolu/Fermé]
Signaler
Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
-
Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
-
Bonjour,

d'habitude je répond aux question des autres mais là je galère vraiment.

Sur access, il y a la possibilité de créer une relation de 1 à plusieurs en reliant manuellement une clé primaire à une clé étrançère. En VBA & SQL, ça donne :

 DoCmd.RunSQL ("ALTER TABLE [Table1] ADD CONSTRAINT [nom_relation]  FOREIGN KEY [ChampsCléEtrangère] REFERENCES [Table2] [ChampsCléPrimaire]")

Mais moi j'aimerais créer une relation 1 à 1. C'est possible de la faire manuellement cependant j'aimerais le faire en SQL (si c'est possible), du style:

 DoCmd.RunSQL ("ALTER TABLE [Table1] ADD CONSTRAINT [nom_relation] PRIMARY KEY [ChampsCléPrimaire1] REFERENCES [Table2] [ChampsCléPrimaire2]") 
Qui ne fonctionne évidemment pas.

Si vous me demander: "Pourquoi ne mets tu pas tout dans une table", bah c'est une table importée d'un excel donc c'est compliqué.

Merci de pouvoir m'éclairer ;)

14 réponses

Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
537
Salut à toi,

j'ose à peine intervenir ici parce que tu as l'air effectivement de te débrouiller pas mal d'habitude, mais on ne sait jamais.

Tu dis "Table importée d'Excel", mais ça ne serait pas plutôt "attachée"? Parce que dans ce cas effectivement tu ne peux pas définir de propriétés comme par exemple mettre une clé primaire.

Voilà ce que je ferais si vraiment tu as besoin d'une relation 1 à 1 et que la table est attachée:
Créer une table Access, dans laquelle tu mettrais une clé sur le champ qui t'intéresse, et la remplir à chaque fois que nécéssaire avec un INSERT INTO, et la re-vider après.

Si par contre la table est bien importée, mais que tu ré-importes régulièrement, le principe serait à peu près le même, sauf que tu pourrais lancer l'importation de données et dans la foulée la vidange puis le remplissage de la table possédant la clé, puis toujours utiliser cette table. Je le fais régulièrement sans problème.

Sans indiscrétion, pourquoi as-tu besoin d'une relation 1 à 1?

Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
51
Bonjour, merci LatelyGeek pour ta réponse.

A chaque fois que j'ai un problème, il faut croire qu'il n'y ait que toi qui ose me répondre ^^

En fait, je m'explique. J'ai un bouton qui execute plusieurs requête SQL.
- Il supprime tout d'abord l'ancienne table.
- Il importe l'excel dans une nouvelle table (de même nom).
- Il créer un champs "numAuto" avec sa clé primaire.
- Il relie cette clé à une clé étrangèe d'une autre table existante.
- Puis je voudrais qu'il créer une relation 1 à 1 avec une autre table qui permet de stocker des informations complémentaires à celle importée. Tu vois ce que je veux dire? En fait il me manque juste la requête de création de relation 1 à 1 mais je doute qu'elle existe ;)

Peut être que toute ma démarche est mauvaise, mais c'est pour le moment la plus simple.
Si tu as d'autres questions, n'hésite pas. Merci encore.
Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
537
Je procèderais différemment:

En fait, je m'explique. J'ai un bouton qui execute plusieurs requête SQL.
- Il supprime tout d'abord l'ancienne table.
- Il importe l'excel dans une nouvelle table (de même nom).
- Il créer un champs "numAuto" avec sa clé primaire.
- Il relie cette clé à une clé étrangère d'une autre table existante.
- Puis je voudrais qu'il créer une relation 1 à 1 avec une autre table qui permet de stocker des informations complémentaires à celle importée. Tu vois ce que je veux dire? En fait il me manque juste la requête de création de relation 1 à 1 mais je doute qu'elle existe ;)

Si tu créais cette table (Que j'appelle TableAccess) "en dur", avec la clé et les liaisons qu'il te faut (y compris la 1 à 1) et que ton importation Excel (dans une table que j'appelle TableExcel) était suivie d'une suppression des enregistrements de TableAccess et remplissage de TableAccess à partir des données de TableExcel, tu résoudrais tous tes problèmes d'un coup...

Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
51
Merci de ta réponse.

J'ai pensé à cette solution. Je me doutais bien qu'il fallait que je passe par là.
Je n'avais juste pas le courage de me taper une requête INSERT INTO avec 150 champs, d'où ma solution de facilité plus haut.
Par contre si tu as la syntaxe VBA pour faire un import d'un fichier Excel vers Access sans création de nouvelle table (car j'ai l'autre qui créer la table seulement), ça m'aiderais bien.

Merci encore !
Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
537
Je ne l'ai jamais fait, mais ça doit être à base de docmd.TransferText acImportDelim ou acImportFixed...

J'exporte avec docmd.TransferText acEportDelim pour créer un fichier Excel, donc ça doit bien être quelque chose dans ce goût là... Si ça fonctionne, tu pourras me donner la syntaxe???
Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
51
Pas de problème. Par contre je pense que je verrais ça demain.

Merci !
Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
537
Une solution de facilité pour le INSERT INTO, c'est une requête que tu lancerais avec un OpenQuery... Mais tu as l'air de vouloir tout faire en VB et SQL...? Ah oui, sauf que 150 champs ça passe sans doute pas.
Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
51
J'ai exactement 104 champs. Mais je vais voir du coté de docmd.TransferText acImportDelim .
Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
51
En utilisant ce très bon code pour récupérer le chemin du fichier Excel : https://access.developpez.com/faq/?page=CheminsRep#AffBoitDialog

Et en ajoutant quelques lignes de code, j'arrive presque au résultat souhaité:

Private Sub bouton_Click()
     DoCmd.RunSQL ("DELETE * FROM [commande];")
     chemin = OuvrirUnFichier(Me.Hwnd, "Parcourir", 1, "Fichier Excel", "xls")
     DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "commande", chemin, True
End Sub


J'y rajoute une clé primaire avec un numéro auto, ainsi que les liaisons. Quand je clique sur le bouton ça marche nickel mise à part le numéroauto qui continue de s'incrémenter sans se reinitialiser.

DU coup j'ai rajouté:
DoCmd.RunSQL ("ALTER TABLE commande ALTER COLUMN n_site COUNTER(0,1);")

Ca réinitialise sauf qu'avec les relations la requête bug :( Je me retrouve avec le même problème initial.
Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
537
Une fois la table vidée, si tu compactes la base, ça réinitialise le NuméroAuto. Je ne sais pas s'il y a une commande qui permette de compacter pendant l'exécution...?
Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
51
Personnellement, en regardant des aides ou en demandnt à des personnes, ils m'ont toujours dit:
"NumAuto? Rien de plus facile à réinitialiser, t'as juste à compacter ta base de données".
Sur toutes les bases que j'ai créé, ça n'a jamais mais alors jamais fonctionné.

Je pense que je vais laissé tomber l'limportation. Tant pis faudra saisir tout à la main ^^
Merci tout de même !
Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
537
Le compactage n'a d'effet que sur les tables VIDES, c'est peut-être pour ça que tu n'as jamais vu la différence _ chez moi ça fonctionne.

Et il y a toujours moyen de lancer une numérotation "automatique" sur un champ numérique après importation, avec un compteur incrémenté, un peu bidouille mais moins que la saisie manuelle...
Messages postés
609
Date d'inscription
lundi 7 janvier 2008
Statut
Membre
Dernière intervention
21 avril 2010
51
Ouais, comme par exemple, faire un NumAuto perso en VBA. Tout en laissant la clé en Numérique et pas le NumAuto d'access. Comme ça tu peux réinitialiser comme tu veux.

Mais j'ai trouvé une solution. J'ai viré les liaisons et à mon grand étonnement le formulaire et sous-formulaire concordent quand même. Donc nickel, enfin presque car du coup mon analyse est toute pourrie.
De plus, c'est mon dernier jour de taf dans cette boite donc je vais pas creser plus ;)

Bon allez, disons problème Résolu.
Merci à toi !
Messages postés
1712
Date d'inscription
vendredi 4 janvier 2008
Statut
Membre
Dernière intervention
16 janvier 2020
537
En fait, même si tu as viré les liaisons entre les tables, comme elles étaient présentes lors de la création du formulaire, ton lien ChampPère/ChampFils doit encore être là...