IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Access Discussion :

[VBA]Duplication de données


Sujet :

VBA Access

  1. #1
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut [VBA]Duplication de données
    Bonjour,

    Voilà ma question : comment serait-il possible de dupliquer un certain enregistrement (qui est sur plusieurs tables) assez facilement ? Je m'explique :

    J'ai 4 table :

    tbl_entite : Num entite / nom_entite / .... / num_adresse
    tbl_unité_travail : IdxUT / num_ut / num_entite
    tbl_activite : IdxAct / IdxUT / num_activite
    tbl_danger : IdxDanger / num_danger / IdxAct

    Une entite peut avoir plusieurs unités de travail, qui elles même pourront avoir plusieurs activiés, et elles même pourront avoir plusieurs dangers.
    Si on prend un exemple :
    Pour l'entité X, j'ai 4 unités de travail, chacunes ayant 3 activités, chacunes des activités a 3 dangers, on se retrouve donc pour cette entité X avec 36 dangers.

    Imaginons maintenant que nous avons 150 entités, et que ces 150 entités ont une unité de travail commune. J'aurais aimé ne pas à avoir à la saisir 150 fois, mais à faire une sorte de duplication après qu'on l'ai saisit une fois, ce qui implique donc de dupliquer les données d'un enregistrement (qui se trouve sur 4 tables) vers telle ou telle entité (qu'on aura sélectionné par une liste déroulante par exemple).

    Et là est mon problème, je saisie pas trop comment procéder, si quelqu'un avait une idée !

    Merci d'avance !

    PS : sachant que le code trouvé dans la partie Sources du forum ne permet pas de dupliquer un enregistrement qui contiendrai plusieurs lignes dans une autre table il me semble.

  2. #2
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Il faut te poser la question s'il est judicieux de dupliquer l'ensemble des données rattachées à une unité de travail pour chaque entité.

    Si par exemple une nouvelle activité est rajoutée à une unité de travail, est-elle visible pour toutes les entités référençant cette unité de travail ou seulement pour celle qui a servi au rajout ?

    Si tu considères ton unité de travail comme un élément commun à plusieurs entités alors tu n'as besoin que de gérer le lien (entité)-(unité de travail).

    Si tu considères ton unité de travail comme un élément unique pour chaque entité alors tu as besoin de dupliquer l'unité de travail modèle. Tu peux utiliser un simple INSERT INTO SELECT.

    Ouala

  3. #3
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut
    En fait il s'agirait d'une duplication qui servirai de base (et qui servirai à gagner beaucoup de temps), je dis de base puisque derrière on pourait adapter le contenu d"une unité de travail.

    Si par exemple une nouvelle activité est rajoutée à une unité de travail, est-elle visible pour toutes les entités référençant cette unité de travail ou seulement pour celle qui a servi au rajout ?
    Elle ne sera visible que pour l'unité de travail en question.

    Si tu considères ton unité de travail comme un élément commun à plusieurs entités alors tu n'as besoin que de gérer le lien (entité)-(unité de travail).
    Une unité de travail est unique. Même si d'une entité à une autre certaines unités de travail sont totalement identiques, chaque unité de travail est considérée comme propre à une entité. D'où l'interet de la duplication : même si je duplique une unité de travail, on pourra ajouter dérrière d'autres activités par rapport aux activités initiales dupliquées.

    Si tu considères ton unité de travail comme un élément unique pour chaque entité alors tu as besoin de dupliquer l'unité de travail modèle. Tu peux utiliser un simple INSERT INTO SELECT.
    Il faut encore aller plus loin que de simplement dupliquer l'unité de travail modèle, il faut même dupliquer TOUTES les unités de travail se rapportant à une entité, et les copier vers la nouvelle entité sélectionnée. On pourrait donc parler d'entité modèle à copier, plutôt que d'unité de travail modèle . D'où mon problème, comment copier, pour une entité, TOUTES les lignes de la table tbl_unité_travail se rapportant à elle et TOUTES les lignes de la table tbl_activite se rapportant à elle et TOUS les dangers se rapportant à elle ?

  4. #4
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Donc là, vu les possibilités d'access y'a pas 36 solutions, étape par étape.
    Pour des questions de performances, je chargerai d'abord intégralement le modèle en mémoire et ensuite je le parcourerai autant de fois que nécessaire en faisant les ajouts dans les tables au fur et à mesure.

  5. #5
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut
    yep, et ça, je sais pas faire xD

  6. #6
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut
    Bon, j'ai tripoté quelques lignes de code, ça me donne ça :

    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
    Set rstProtocole = Db.OpenRecordset("SELECT nom_entite, date FROM tbl_entite WHERE Num_adresse = " & Me.Modifiable0 & "  ")
    'Verifie que le protocole 1 existe
    If rstProtocole.EOF Then Exit Sub
    'ouvre le recordset où sera ajouté le protocole
    Set rstProtocole2 = Db.OpenRecordset("tbl_entite")
    'Duplique le protocole
    With rstProtocole2
     
            .AddNew
            'duplique les champs
             For Each fld In rstProtocole.Fields
              .Fields(fld.Name) = fld.Value
            Next
            .Fields("num_adresse") = Me.Modifiable1
           ' id = .Fields("num_adresse")
     
      'se positionne sur l'enregistrement ajouté
     
      .Update
    End With
    Donc dans ma table tbl_entité, j'arrive bien à copié l'enregistrement provenant de la liste déroulante Me.Modifiable0 ... Seul problème, si j'ai 3 lignes pour cet enregistrement, il ne me copiera que la première.

    La solution serait à l'intérieur de mon with de lui dire de passer à la ligne suivant, pour refaire le même traitement (et donc recopier la ligne suivante). Mais je ne sais pas comment faire xD
    Je pense qu'avec un For ça devrait être bon, mais FOR de quoi ? et quel traitement appliquer pour lui dire : passe à la ligne suivante et recopie aussi ?
    Ca ressemblerait à du :

    FOR EACH ligne que tu m'a trouvé dans rstProtocole ==> en code VBA ça donne quoi ça ?

  7. #7
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut
    Pour tester un peu, j'ai rajouté un simple for pour voir si il me copiait bien le nombre de ligne :

    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
    sql1 = ("SELECT Count(*) FROM tbl_entite WHERE Num_adresse = " & Me.Modifiable0 & "  ;")
    Set requete = CurrentDb.OpenRecordset(sql1)
     
    'Ouvre le recordset où sera prélevé le protocole
    Set rstProtocole = Db.OpenRecordset("SELECT nom_entite, date FROM tbl_entite WHERE Num_adresse = " & Me.Modifiable0 & "  ")
    'Verifie que le protocole 1 existe
    If rstProtocole.EOF Then Exit Sub
    'ouvre le recordset où sera ajouté le protocole
    Set rstProtocole2 = Db.OpenRecordset("tbl_entite")
    'Duplique le protocole
    With rstProtocole2
        For i = 1 To requete.Fields(0)
            .AddNew
            'duplique les champs
             For Each fld In rstProtocole.Fields
              .Fields(fld.Name) = fld.Value
            Next
            .Fields("num_adresse") = Me.Modifiable1
           ' id = .Fields("num_adresse")
     
      'se positionne sur l'enregistrement ajouté
      .Update
      Next i
    End With
    Sur mon test, j'ai 3 enregistrements, et il me copie bien 3 fois .. mais le même enregistrement, à savoir le premier qu'il trouve ! Je reviens donc à ma question du dessus, comment lui dire, passe à la ligne d'après ?

  8. #8
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut
    Résolu !!!!!!!!! xD

    Il s'agissait tout simplement d'un : .MoveNext !

  9. #9
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Ouaip c'est bien, mais je pense que tu peux améliorer légèrement ton code et n'oublie pas que la méthode avec .AddNew Update est assez

    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
     
    Private Sub duplicationEntite()
       Dim vSql As String, vSource As DAO.RecordSet, vDest As DAO.RecordSet, vFld As Field
     
       vSql = "SELECT nom_entite, date FROM tbl_entite WHERE Num_adresse = " & Me.Modifiable0
     
       Set vSource = CurrentDb.OpenRecordset(vSql)
     
       With vSource
          If Not .EOF Then
             .MoveFirst
             Set vDest = CurrentDb.OpenRecordset("tbl_entite") 
             Do
                vDest.AddNew
                For Each vFld In vSource.Fields
                   vDest.Fields(vFld.Name) = vFld.Value
                Next
                vDest.Fields("num_adresse") = Me.Modifiable1
                vDest.Update
                'ici tu renvoie vers la routine qui te duplique tes unités de travail
                'car tu as acquis définitivement le nouveau Id (AutoNum)
                duplicationUniteDeTravail vDest!Id, vSource!Id   'exemple nouveau id et ancien pour la sélection
                .MoveNext
             Loop Until .EOF
          End If
          .Close
          vDest.Close
       End With
     
       Set vSource = Nothing
       Set vDest = Nothing
     
    End Sub

  10. #10
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     duplicationUniteDeTravail vDest!Id, vSource!Id
    euh, ça doit renvoyer vers rien ça non ?

  11. #11
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Comme tu l'indiques, l'organisation de tes tables est celle-ci :
    tblEntite -(1,*)- tblUniteTravail -(1,*)- tblActivite -(1,*)- tblDanger

    Donc une fois que tu a dupliqué tblEntite tu passe à la duplication de tblUniteTravail (tu précises toi-même que cela doit être fait en cascade) d'où la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    duplicationUniteDeTravail vDest!Id, vSource!Id
    Ici le code saute vers la routine qui se charge de ce travail. On lui passe vDest!Id qui correspond au nouveau IdEntite (le dupliqué) et vSource!Id qui correspond à l'IdEntite du modèle.

    De cette manière tu peux sélctionner à partir de tblUniteTravail et de vSource!Id les unités dites modèles et les dupliquer en leur affectant IdEntite = vDest!Id

    Ouala

  12. #12
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    691
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 691
    Par défaut
    Encore faut-il écrire la routine duplicationUniteDeTravail xD
    J'essaierais quand j'aurais du temps de libre, en tout cas, je m'en suis sorti avec ça :

    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
    Option Compare Database
     
    Private Sub Commande10_Click()
    Dim rstProtocole As DAO.Recordset, rstProtocole2 As DAO.Recordset
    Dim Db As DAO.Database, fld As DAO.Field
    Dim sql As String
    Dim id As Long
    Set Db = CurrentDb
    'Ouvre le recordset où sera prélevé l'entite
    Set rstProtocole = Db.OpenRecordset("SELECT nom_entite, date FROM tbl_entite WHERE num_entite = " & Me.Modifiable3 & "")
    'Verifie que l'entité éxiste
    If rstProtocole.EOF Then Exit Sub
    'ouvre le recordset où sera ajouté l'entite
    Set rstProtocole2 = Db.OpenRecordset("tbl_entite")
    'Duplique l'entité
    With rstProtocole2
      .AddNew
      'duplique les champs
      For Each fld In rstProtocole.Fields
        .Fields(fld.Name) = fld.Value
      Next
      .Fields("num_adresse") = Me.Modifiable1
      id = .Fields("num_entite")
      .Update
      'se positionne sur l'enregistrement ajouté
    End With
     
    'Duplique les lignes
    sql = "insert into tbl_unite_travail (num_entite,num_ut) SELECT " & _
      id & ", num_ut FROM tbl_unite_travail WHERE num_entite = " & Me.Modifiable3 & ""
    Db.Execute sql
    MsgBox "Duplication terminée avec succés"
    End Sub
    Avec une liste déroulante (liste déroulante 1), on selectionne quelle entité on veut dupliquer vers quelle adresse (liste déroulante 2) , puisque je me suis aperçu qu'il fallait que je prenne les adresse en compte :

    tbl_adresse : Num / ...
    tbl_entite : Num entite / nom_entite / .... / num_adresse
    tbl_unité_travail : IdxUT / num_ut / num_entite
    tbl_activite : IdxAct / IdxUT / num_activite
    tbl_danger : IdxDanger / num_danger / IdxAct

    Une adresse peut avoir plusieurs entités, donc je sélectionne quelle entité de quelle adresse je veut dupliquer, et vers où ! Et le tour est joué ! Maintenant il faut que je vois pour dupliquer les activités et les dangers des unités de travail spécifique à une entité ! Une belle partie de plaisir en vue !!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VBA-E]Export données dans table Access
    Par lolo_bob2 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 11/04/2006, 09h56
  2. [VBA-E]replacement données excel par données VBA
    Par plante.douce dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 02/04/2006, 20h23
  3. Réponses: 1
    Dernier message: 22/03/2006, 12h03
  4. [VBA] Transmettre des données d'une feuille à l'autre
    Par Overflow64 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 20/12/2005, 09h58
  5. [VBA] Comparer des données en excel
    Par Micavk dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 17/10/2005, 12h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo