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

Macros et VBA Excel Discussion :

Copier données feuille Excel vers table Access sans doublons [Toutes versions]


Sujet :

Macros et VBA Excel

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Points : 15
    Points
    15
    Par défaut Copier données feuille Excel vers table Access sans doublons
    Bonjour à tous,

    J'ai une application Excel relié à une base Access pour stocker les données. J'ai crée une fonction qui permet de coller les données d'une feuille de l'application vers la base. Le problème survient lorsque je met à jour les valeurs de la feuille et que je rapelle ma fonction, il y a un message qui apparaît m'indiquant la présence d'un doublon. Je voudrais savoir comment faire pour que la fonction mette à jour l'enregistrement si celui ci existe déjà (Clé primaire de la table : ID_Action). Ci dessous, le code de la fonction qui me permet de copier les données:
    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
    62
    63
    64
    65
    66
    67
    68
    69
    Sub ExportExcel()
    Dim Plage As Range
    Dim Array1 As Variant
    Dim x As Variant
    Dim Db1 As Database
    Dim Rs1 As Object
     
     
    ' Opening database
    Set Db1 = DBEngine.OpenDatabase(DBEXPORT)
    'Open SaveMatrix table
    Set Rs1 = Db1.OpenRecordset("Save_Matrix", dbOpenDynaset)
     
    Set Plage = Worksheets("SaveMatrix").Range("A1").CurrentRegion.Offset(1, 0)
         Set Plage = Plage.Resize(Plage.Rows.Count - 1, Plage.Columns.Count)
     
    Array1 = Plage.Value
     
         For x = 1 To UBound(Array1, 1)
              With Rs1
                   .AddNew
                .Fields("ID_Action") = Array1(x, 1)
                .Fields("Compilance_Conse") = Array1(x, 2)
                .Fields("Compilance_Freq") = Array1(x, 3)
                .Fields("Safety_Conse") = Array1(x, 4)
                .Fields("Safety_Freq") = Array1(x, 5)
                .Fields("Environment_Conse") = Array1(x, 6)
                .Fields("Environment_Freq") = Array1(x, 7)
                .Fields("Integrity_Conse") = Array1(x, 8)
                .Fields("Integrity_Freq") = Array1(x, 9)
                .Fields("SCE_Conse") = Array1(x, 10)
                .Fields("SCE_Freq") = Array1(x, 11)
                .Fields("Financial_Conse") = Array1(x, 12)
                .Fields("Financial_Freq") = Array1(x, 13)
                .Fields("Media_Conse") = Array1(x, 14)
                .Fields("Media_Freq") = Array1(x, 15)
                .Fields("LevelCompil_Conse") = Array1(x, 16)
                .Fields("LevelFreq_Conse") = Array1(x, 17)
                .Fields("LevelSafety_Conse") = Array1(x, 18)
                .Fields("LevelSafety_Freq") = Array1(x, 19)
                .Fields("LevelEnvi_Conse") = Array1(x, 20)
                .Fields("LevelEnvi_Freq") = Array1(x, 21)
                .Fields("LevelIntegrity_Conse") = Array1(x, 22)
                .Fields("LevelIntegrity_Freq") = Array1(x, 23)
                .Fields("LevelSCE_Conse") = Array1(x, 24)
                .Fields("LevelSCE_Freq") = Array1(x, 25)
                .Fields("LevelFinancial_Conse") = Array1(x, 26)
                .Fields("LevelFinancial_Freq") = Array1(x, 27)
                .Fields("LevelMedia_Conse") = Array1(x, 28)
                .Fields("LevelMedia_Freq") = Array1(x, 29)
                .Fields("Result_Compil") = Array1(x, 30)
                .Fields("Result_Safe") = Array1(x, 31)
                .Fields("Result_Envi") = Array1(x, 32)
                .Fields("Result_integrity") = Array1(x, 33)
                .Fields("Result_SCE") = Array1(x, 34)
                .Fields("Result_Financial") = Array1(x, 35)
                .Fields("Result_Media") = Array1(x, 36)
                .Fields("Final_Result") = Array1(x, 37)
                .Fields("Manual_Result") = Array1(x, 38)
                .Update
              End With
         Next
     
         ' Close database
         Db1.Close
     
        'Delete records feom the sheet
         Plage.ClearContents
    End Sub
    Merci de votre aide

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    Si ta feuille Excel contient toutes les données (celles qui sont déjà dans la base, plus les nouvelles), une méthode bourrin mais simple consisterait à vider ta table et à tout ré-exporter dedans (si le temps d'exécution est acceptable, bien entendu).

    Sinon tu peux toujours tester si ton record existe déjà. Mais dans ce cas-là je te conseillerai d'utiliser un 'table-type" recordset car je pense que ce sera plus rapide qu'un 'dynaset-type'.
    En plus la recherche est plus simple car avec un 'table-type" on définit explicitement une clé primaire et on peut donc faire une recherche dessus avec comme conséquence implicite qu'il y aura au plus un résultat. En revanche avec un 'dynaset-type', il peut y avoir plusieurs occurrences et il y a donc plusieurs méthodes (FindNext, FindPrevious, FindFirst et FindLast).

    Du coup tu déclares ton recordset comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    'Open SaveMatrix table
    Set Rs1 = Db1.OpenRecordset("Save_Matrix", dbOpenTable)
    Rs1.Index = "PrimaryKey"
    Et pour savoir si ton recordset existe déjà:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Rs1.Seek("=", Array(x, 1))
    If Rs1.NoMatch Then    'Si un enregistrement correspond, il devient l'enregistrement courant
     
         [...]    'Ajoute ton nouveau record
     
    Else
     
        Rs1.Edit
        [...]    'Modifie les fields nécessaires
        Rs1.Update
     
    End if
    A adapter à tes conditions particulières, bien sûr.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Points : 15
    Points
    15
    Par défaut
    Bonjour,

    Juste quelques petites questions :

    "Primary Key" : je laisse comme sa ou je mets l'intitulé de ma clé

    Rs1.Seek("=", Array(x, 1)) : le "=" je le laisse ossi ou il faut mettre quelque chose en particulier (il me met erreur de compilation)

    A part les changements données, mon code je pe le garder come tel ou il y a des choses à supprimé ?

    Merci

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    Citation Envoyé par dragoes64 Voir le message
    "Primary Key" : je laisse comme sa ou je mets l'intitulé de ma clé
    Normalement si tu as un seul champ définit comme clé primaire, il ne devrait pas y avoir d'ambigüité donc tu peux laisser comme ça. Jette un œil à la collection Indexes de ta table si ça ne fonctionne pas.

    Citation Envoyé par dragoes64 Voir le message
    Rs1.Seek("=", Array(x, 1)) : le "=" je le laisse ossi ou il faut mettre quelque chose en particulier (il me met erreur de compilation
    Il faut laisser le "=" tel quel et pour le deuxième argument (key1), je pense que l'aide VBA est assez explicite:

    Citation Envoyé par VBA Help
    Le type de données de champ de l'argument key1 doit être identique à celui du champ correspondant dans l'index en cours. Par exemple, si l'index en cours fait référence à un champ numérique (par exemple, N° employé), key1 doit contenir des données numériques. De même, si l'index en cours fait référence à un champ texte (par exemple, Nom), key1 doit être une chaîne.
    Tiens-moi au courant si ça ne fonctionne pas, auquel cas je testerai de mon côté. Normalement tu dois pouvoir garder le reste de ton code car la seule chose ayant vraiment changé, c'est le type de recordset (dynaset en table, et les 2 sont assez proches).

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Points : 15
    Points
    15
    Par défaut
    J'ai un problème avec cette ligne :

    Rs1.Seek("=" , Array1(x, 1)
    Le message dit "Erreur de compilation Attendu séparateur de liste ou ) "

    J'ai beau cherché je vois pas ou rajouter cet élément ( j'ai pensé à un = après Seek mais il me dit encore qu'il manque une parenthèse)

    Merci

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 207
    Points : 251
    Points
    251
    Par défaut
    Citation Envoyé par dragoes64 Voir le message
    Le message dit "Erreur de compilation Attendu séparateur de liste ou ) "
    Peut-être que tu as oublié une parenthèse:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Rs1.Seek("=" , Array1(x, 1))
    Sinon c'est parce qu'en VBA, pour les appels de procédures, il ne faut normalement pas lister les arguments entre parenthèses (c'est réservé aux fonctions). Personnellement je n'aime pas donc j'utilise toujours les parenthèses .

    2 solutions:

    Ou tu enlèves les parenthèses:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Rs1.Seek "=" , Array1(x, 1)
    ou tu utilises 'Call' devant (il parait que ce n'est pas recommandé mais je ne sais pas pourquoi et je n'ai jamais eu de problème avec):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Call Rs1.Seek("=" , Array1(x, 1))

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 29
    Points : 15
    Points
    15
    Par défaut
    En enlevant les parenthèses sa marche parfaitement.

    Merci à toi Sclarckone tu m'as été d'une grande aide. Ce sujet est à présent résolu !!!

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

Discussions similaires

  1. Copier cellule Excel vers table Access
    Par HERBAG dans le forum Général VBA
    Réponses: 1
    Dernier message: 09/12/2013, 11h21
  2. Donnée feuille Excel vers table base Access
    Par LE MAHJONG dans le forum Bases de données
    Réponses: 13
    Dernier message: 06/10/2008, 21h15
  3. copier une feuille excel vers un autre fichier excel en access VBA
    Par acbdev dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 19/03/2008, 09h32
  4. données tableau excel vers table access ?
    Par alexkickstand dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 24/09/2007, 21h11
  5. Importer des données d'une feuille Excel vers TABLE
    Par souminet dans le forum Bases de données
    Réponses: 1
    Dernier message: 07/11/2006, 09h10

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