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

Requêtes et SQL. Discussion :

Besoin d'astuces pour implémenter un choix entre un UPDATE et un INSERT TO [AC-2003]


Sujet :

Requêtes et SQL.

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut Besoin d'astuces pour implémenter un choix entre un UPDATE et un INSERT TO
    Bonsoir, je vous explique mon soucis et j'ai besoin d'un astuce pour implementer mon idée car je rame depuis plusieurs semaines.

    J'ai un fichier Excel (fichierexcel.xls) duquel je dois extraire des données chaque jour pour les intégrer à ma base de données (mabase.mbd).
    Mon soucis est le suivant:
    - Au jour J, j'ai par exemple 25000 lignes de données dans le fichier excel
    - A J+1, j'ai 35000 lignes dont certaines ( supposons 5000 lignes) existaient déjà à J. Ainsi donc, les 5000 lignes déjà présentes à J dans mon fichier Excel se retrouve le lendemain à J+1 dans le fichier Excel.

    Comment donc faire pour extraire les données du fichier Excel chaque jour en étant sûr d'avoir des données distinctes dans ma base? Les données qui n'existent pas doivent être importées et celle qui existent diovent être mise à jour

    Je joins 3 fichiers d'exemples. Les fichiers FichierExcel_J et FichierExcel_J+1 contiennent des données et le dernier FichierExcel_Resultat vous présente les donnéEs que je souhaiterais voir enregistrer dans ma base de données.


    J'aimerai si possible que le résultat soit sous la forme implémenter dans Access pour me faciliter la tâche. Néanmoins, je ne refuserai pas bien évidemment des solutions (bien expliquées).

    Merci
    Fichiers attachés Fichiers attachés
    flet le kid

  2. #2
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Bonsoir,

    Il faut dans ce cas importer le classeur dans une table temporaire et lancer deux requêtes :

    • Une qui insère les données qui n'existe pas
    • Une qui mets à jour les données restantes


    Enfin, on vide (ou on supprime) la table temporaire.

  3. #3
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    Merci pour cette idée. J'ai déjà commencé à l'implémenter. Seulement comme le fichier Excel contient plus de 50 000 lignes, le processus est très long. Je cherche s'il n'y a pas plus court.

    A cet effet, j'envisage de parcourir toutes les lignes et de tester l'existance ou non de l'enregistrement dans la table de destination (DAO.Recordset). Si l'élément existe, je fais une mise à jour, sinon une insertion.

    Qu'en pensez vous?

    De plus, est il intéressant de se passer d'une table temporaire et de travailler directement du fichier Excel vers la table de destination. Ou bien il faut que j'importe les données d'abord dans une table temporaire? Laquelle des deux manières de travailler sera la plus rapide?

    Si j'ai une requête qui sélectionne des résultats (ex: RQT_SELECTION), comment faire pour parcourir les éléments un à un?

    Merci
    flet le kid

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    une solution VBA à tester :
    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
     
    'Fonction dérivée d'un code de la FAQ (Cafeine)
    Public Function ImportFromExcel(ByVal sFullPathExcelFile As String, _
                                    ByVal sNomFeuille As String, _
                                    ByVal sDestTable As String) As Boolean
     
       On Error GoTo errtag
       Dim oDb As DAO.Database
       Dim oRs As DAO.Recordset
       Dim vRows As Variant
       Dim l As Long, lRows As Long
       Dim i As Integer, iMaxCol As Integer
     
       Set oDb = OpenDatabase(sFullPathExcelFile, True, False, "Excel 8.0;")
       Set oRs = oDb.OpenRecordset(sNomFeuille & "$", DAO.dbOpenSnapshot)
     
       With oRs
          .MoveLast
          .MoveFirst
          lRows = .RecordCount
          vRows = .GetRows(lRows)
          .Close
       End With
       oDb.Close
     
       If lRows > 0 Then
          iMaxCol = UBound(vRows, 1)
          Set oDb = CurrentDb
          Set oRs = oDb.OpenRecordset(sDestTable, dbOpenTable)
          oRs.Index = "primarykey"
     
          With oRs
             For l = 0 To lRows - 1
                .Seek "=", vRows(0, l)
                If .NoMatch Then
                   .AddNew
                   .Fields(0) = vRows(0, l)
                Else
                   .Edit
                End If
                For i = 1 To iMaxCol
                   .Fields(i) = vRows(i, l)
                Next i
                .Update
             Next l
             .Close
          End With
          oDb.Close
       End If
       ImportFromExcel = True
    fin:
       Set oDb = Nothing
       Set oRs = Nothing
       Exit Function
    errtag:
       MsgBox "Erreur n°" & Err.Number & vbCrLf & "Description :" & Err.Description, vbExclamation, "Erreur..."
       Resume fin
    End Function
    Appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Public Function testimp()
       Debug.Print ImportFromExcel(CurrentProject.Path & "\" & "FichierExcel_J.xls", "Feuil1", "ImportExcel")
    End Function
    Avec "importexcel" le nom de la table destination ayant une clef primaire sur la premiere colonne (CODECLIENT)

    Philippe

  5. #5
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    Bonjour,
    J'ai testé l'opération et j'obtiens l'erreur suivante


    Erreur: n° 3219
    Description: Opération non valide
    J'ai poussé un peu plus loin pour voir ou se situe l'erreur et c'est au niveau de la ligne Set oRs = oDb.OpenRecordset(sDestTable, dbOpenTable)

    Sinon, ton code m'intéresse beaucoup mais je n'arrive pas à le corriger.

    Merci
    flet le kid

  6. #6
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Bonjour à tous,

    En testant ce code intéressant, j'ai eu aussi une erreur que j'ai résolue en dédoublant les déclarations de Database et Recordset (mais je ne m'explique pas pourquoi !)
    Ainsi la fonction de Philben devient :
    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
    70
    'Auteur : Philben
    '         Fonction dérivée d'un code de la FAQ (Cafeine)
    Public Function ImportFromExcel(ByVal sFullPathExcelFile As String, _
                                    ByVal sNomFeuille As String, _
                                    ByVal sDestTable As String) As Boolean
     
        On Error GoTo errtag
     
        Dim oDbXls As DAO.Database
        Dim oRsXls As DAO.Recordset
     
        Dim oDb As DAO.Database
        Dim oRs As DAO.Recordset
     
        Dim vRows As Variant
        Dim l As Long, lRows As Long
        Dim i As Integer, iMaxCol As Integer
     
        'Set oDbXls = OpenDatabase(sFullPathExcelFile, True, False, "Excel 8.0;")
        Set oDbXls = OpenDatabase(sFullPathExcelFile, False, True, "Excel 8.0;")
        Set oRsXls = oDbXls.OpenRecordset(sNomFeuille & "$", DAO.dbOpenSnapshot)
     
        With oRsXls
            .MoveLast
            .MoveFirst
            lRows = .RecordCount
            vRows = .GetRows(lRows)
            .Close
        End With
        oDbXls.Close
     
        If lRows > 0 Then
            iMaxCol = UBound(vRows, 1)
            Set oDb = CurrentDb
            Set oRs = oDb.OpenRecordset(sDestTable, dbOpenTable)
            oRs.Index = "primarykey"
     
            With oRs
                For l = 0 To lRows - 1
                    .Seek "=", vRows(0, l)
                    If .NoMatch Then
                        .AddNew
                        .Fields(0) = vRows(0, l)
                    Else
                        .Edit
                    End If
                    For i = 1 To iMaxCol
                        .Fields(i) = vRows(i, l)
                    Next i
                    .Update
                Next l
                .Close
            End With
            oDb.Close
        End If
        ImportFromExcel = True
     
     
    fin:
        Set oDbXls = Nothing
        Set oRsXls = Nothing
        Set oDb = Nothing
        Set oRs = Nothing
        Exit Function
     
    errtag:
        MsgBox "Erreur n°" & Err.Number & vbCrLf & "Description :" & Err.Description, vbExclamation, "Erreur..."
        Resume fin
     
    End Function
    De plus Flet, as tu créé préalablement , comme indiqué par Philben, la table "importexcel" avec :
    une clef primaire sur la premiere colonne (CODECLIENT)
    un champ texte NomClient
    un champ numérique Montant
    un champ Date : Date1
    En tout cas, ça marche bien
    "Always look at the bright side of life." Monty Python.

  7. #7
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    J'ai peut être omis un élément qui me crée de soucis alors.
    Dans ma table de destination, j'ai une clé primaire qui s'incrémente automatique et qui ne se trouve donc pas dans le fichier Excel.

    Si je pouvais avoir des commentaires pour chaque ligne du code proposé, je pourrais aisément l'adapté à mon cas.

    Parce que ça ne fonctionne toujours pas chez moi.

    Merci
    flet le kid

  8. #8
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Voici ma BD de test: en Access 2003 ,
    J'avais mis tes fichiers dans le même répertoire.

    Bon test,
    "Always look at the bright side of life." Monty Python.

  9. #9
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    Merci micniv , et en bonus,le code légèrement modifié (pour s'adapter plus facilement à votre cas) et totalement documenté à placer dans un module standard :

    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
     
    'Fonction à lancer pour test
    'Mettre le curseur dans cette fontion puis appuyer sur 'F5' pour démarrer l'importation
    'Modifier si besoin ici le nom, le chemin du fichier excel, le nom de la feuille excel et le nom
    'de la table Access qui va récupérer les données
    Public Function TestImport()
       'On veut importer le fichier excel 'FichierExcel_J.xls' qui se trouve dans le même
       'répertoire que la base Access.
       'La feuille Excel à importer se nomme 'Feuil1'
       'La table Access qui va récupérer les données Excel se nomme 'tImportExcel'
       'Changer ici le nom de la table pour s'adapter à votre cas
       If ImportFromExcel(CurrentProject.Path & "\" & "FichierExcel_J.xls", "Feuil1", "tImportExcel") Then
          'Si import ok, on affiche un message
          MsgBox "import terminé avec succès !", vbInformation
       End If
    End Function
     
     
    'Fonction dérivée d'un code de la FAQ (Cafeine)
    'Arguments :
    '  - Chemin complet + nom du fichier Excel source
    '  - Nom de la feuille Excel contenant les données à importer
    '  - Nom de la table Access qui va recevoir les données importées
    'Modifier si besoin dans cette fonction le nom des champs de la table Access
    Public Function ImportFromExcel(ByVal sFullPathExcelFile As String, _
                                    ByVal sNomFeuille As String, _
                                    ByVal sDestTable As String) As Boolean
     
       'Si une erreur ce produit aller à l'étiquette errtag en fin de fonction
       On Error GoTo errtag
     
       'Déclaration des bases de données et des recordsets
       Dim oDbXls As DAO.Database, oDb As DAO.Database
       Dim oRsXls As DAO.Recordset, oRs As DAO.Recordset
       'avRows va recevoir les données issues d'Excel sous forme d'un tableau
       Dim avRows As Variant
       Dim l As Long, lRows As Long
     
       'Ouverture du fichier Excel comme source de données
       Set oDbXls = DBEngine(0).OpenDatabase(sFullPathExcelFile, False, False, "Excel 8.0;")
       'Ouverture du recordset 'instantané' des données contenues dans la feuille Excel passée en argument
       'Le nom de la feuille Excel doit se terminer par le signe $
       Set oRsXls = oDbXls.OpenRecordset(sNomFeuille & "$", dbOpenSnapshot)
     
       'Avec le recordset défini (de la feuille X du fichier Excel Y)
       With oRsXls
          If Not .EOF Then        'S'il existe des enregistrements
             .MoveLast            'Pour initialiser la prorpiété RecordCount utilisée plus loin
             .MoveFirst           'Retour au premier enregistrement
             lRows = .RecordCount 'Retourne le nombre d'enregistrements ou lignes du fichier
             'On récupère toutes les lignes dans un tableau de variants
             'Méthode très performante en terme de rapidité
             'Tableau à 2 dimensions :
             '  - La première définie la colonne (de 0 à Nb colonnes - 1)
             '  - La deuxième définie la ligne   (de 0 à Nb lignes - 1)
             'Exemple : On veut obtenir la colonne 'NOMCLIENT' de la ligne 5
             '  - 'NOMCLIENT' est la colonne 2 mais la base du tableau est zéro
             '  - La ligne 5 correspond à la ligne 4 en base 0 du tableau
             '  => avRows(1,4) contient le résultat de 'NOMCLIENT' de la ligne 5
             avRows = .GetRows(lRows)
          End If
          .Close                  'On ferme le recordset Excel car on détient les données dans avRows
       End With
       oDbXls.Close               'On ferme la base de données Excel
     
       'Si on a importé des lignes
       If lRows > 0 Then
          'On ouvre la base de données Access courante
          Set oDb = CurrentDb
          'On ouvre un recordset type 'table' sur le nom de la table passée en argument
          Set oRs = oDb.OpenRecordset(sDestTable, dbOpenTable)
          'On ouvre l'index de la colonne 'CODECLIENT' (index sans doublon)
          oRs.Index = "CODECLIENT"
          'Si code client était la clef primaire, on ouvrirait l'index 'PrimaryKey'
     
          'Avec le recordset
          With oRs
             'On parcours chaque ligne du tableau (base zéro !) donc lrows - 1
             For l = 0 To lRows - 1
                'Grâve à l'index on recherche dans la table Access le code client courant
                'Dans la feuille Excel, le code client est la première colonne => 0 dans avRows
                'L'enregistrement courant correspond à la valeur de l
                .Seek "=", avRows(0, l)
                'Si le code client n'est pas trouvé on créé un nouvel enregistrement dans la table
                If .NoMatch Then
                   .AddNew
                   'On affecte à la colonne 'CODECLIENT' de la table la valeur issue du fichier Excel
                   .Fields("CODECLIENT") = avRows(0, l)
                'Si le code client existe, on passe en édition (update) de l'enregistrement trouvé
                Else
                   .Edit
                End If
                'On édite ou on renseigne les autres colonnes de la table Access
                'Adapter le nom des colonnes à ceux de votre table access
                .Fields("NOMCLIENT") = avRows(1, l) '= colonne 2 Excel : 'NOMCLIENT'
                .Fields("MONTANT") = avRows(2, l) '= colonne 3 Excel : 'MONTANT'
                .Fields("TRANSDATE") = avRows(3, l) '= colonne 4 Excel : 'DATE'
                'On enreigstre la création ou la modification de l'enregistrement
                .Update
             Next l
             .Close   'On ferme le recordset de la table Access
          End With
          oDb.Close   'On ferme la base de données Access
       End If
       ImportFromExcel = True  'Si on arrive ici, c'est que tout est ok, pas d'erreur
     
    'Etiquette de fin
    fin:
       'On libère les classes en commençant par le recordset puis la bases de données
       Set oRsXls = Nothing
       Set oDbXls = Nothing
       Set oRs = Nothing
       Set oDb = Nothing
       Exit Function        'Force la fin de la fonction pour ne pas évaluer les lignes suivantes
     
    'Etiquette du gestionnaire d'erreur, on arrive ici que si une erreur se produit
    errtag:
       'Affiche le message de l'erreur levée
       MsgBox "Erreur n°" & Err.Number & vbCrLf & "Description :" & Err.Description, vbExclamation, "Erreur..."
       'Nettoie l'erreur et saut sur l'étiquette fin pour libérer les classes : important !
       Resume fin
     
    End Function
    Bonne continuation,

    Philippe

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    Bonjour,

    j'ai testé avec 30 000 lignes à importer (10 lignes répliquées donc essentiellement des updates), on réalise l'import en moins de 1,5 seconde.

    Philippe

  11. #11
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    Merci pour tes explications vraiment claires et que je teste à présents.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                .Fields("NOMCLIENT") = avRows(1, l) '= colonne 2 Excel : 'NOMCLIENT'
                .Fields("MONTANT") = avRows(2, l) '= colonne 3 Excel : 'MONTANT'
                .Fields("TRANSDATE") = avRows(3, l) '= colonne 4 Excel : 'DATE'
    Je n'ai pas ajouté ce genre de ligne dans mon fichier.

    J'adapte rapidement cela à mon code et je vous en informe.

    Merci
    flet le kid

  12. #12
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    Bonjour,

    Je viens de lire le code qui est plus claire maintenant avec tes explication PHILBEN . Tu m'as ouvert les yeux. Merci pour le temps consacré aux commentaires dans ce code, pour le langage claire et précis et les petits exemples.

    Néamoins, j'ai une petite question: J'ai une clé primaire composé (cle1 et cle2). Dans le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                'Grâve à l'index on recherche dans la table Access le code client courant
                'Dans la feuille Excel, le code client est la première colonne => 0 dans avRows
                'L'enregistrement courant correspond à la valeur de l
                .Seek "=", avRows(0, l)
    Est ce que je peux remplacer l'instruction .Seek "=", avRows(0,l) par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (.Seek "=", avRows(0, l) And .Seek "=", avRows(1, l))
    . En supposant que cle1 et cle2 sont dans les colonnes 1 et 2 du fichier Excel donc (0 et 1) du tableau?

    Est possible? Si Non, comment faire pour remplacer cette instruction avec mes clés composées?

    Merci



    Edit:

    Ben, je viens de regarder dans l'aide, la solution n'est pas plutôt:
    .Seek "=", avRows(0, l), avRows(1,l)

    et il faudrait mofifier plus haut oRs.Index = "CODECLIENT" par

    oRs.Index = "cle1"
    oRs.Index = "cle2"

    Si ce ne sont pas des clés primaires ou

    oRs.Index = "primarykey" si je considère la clé primaire existante pour mes tests (j'espère que je m'exprime correctement)


    Ai je raison sur les points en rouge?
    flet le kid

  13. #13
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    J'ai toujours l'erreur 3219 du début. Je rappelle que ma table est une table liée sur une base de donné PostgreSQL, est ce que le problème peut venir de là?
    flet le kid

  14. #14
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    En fouillant dans l'aide, j'ai trouvé ceci:
    Pour créer un objet Recordset de type Table, utilisez la méthode OpenRecordset sur un objet Database ouvert.

    [COLOR="Red"]Vous pouvez créer un objet Recordset de type Table à partir d'une table d'une base de données Microsoft Jet, mais pas d'une table ODBC ni d'une table liée.[/COLOR] Vous pouvez utiliser l'objet Recordset de type Table avec des bases de données ISAM (telles que FoxPro, dBASE ou Paradox) lorsque vous les ouvrez directement.

    À la différence des objets Recordset de type Feuille de réponses dynamique (Dynaset) ou Instantané, l'objet Recordset de type Table ne peut faire référence à plus d'une table de base, et ne peut être créé avec une instruction SQL qui filtre ou trie les données. En règle générale, lorsque vous accédez à un objet Recordset de type Table, vous indiquez l'un des index prédéfinis pour la table pour trier les données renvoyées à votre application. Si la table ne dispose pas d'index, les données n'auront pas d'ordre particulier. Le cas échéant, votre application peut créer un index qui renvoie les enregistrements dans un ordre spécifique. Pour choisir l'ordre de votre objet Recordset de type Table, donnez à la propriété Index la valeur d'un index valide.

    Autre différence avec les objets Recordset de type Feuille de réponses dynamique (Dynaset) ou Instantané, il n'est pas nécessaire de remplir explicitement les objets Recordset de type Table pour obtenir une valeur exacte dans la propriété RecordCount.

    Pour gérer l'intégrité des données, les objets Recordset de type Table sont verrouillés pendant les opérations Edit et Update, de manière qu'un enregistrement donné ne puisse être mis à jour que par un seul utilisateur à la fois. Lorsque le moteur de base de données Microsoft Jet verrouille un enregistrement, il verrouille l'ensemble de la page de 2 Ko contenant cet enregistrement.

    Deux types de verrouillage sont utilisés avec les tables non ODBC - le verrouillage pessimiste et le verrouillage optimiste. Les tables accessibles par ODBC utilisent toujours un verrouillage optimiste. La propriété LockEdits détermine les conditions de verrouillage effectif pendant la modification.

    Ma table de destination à moi est une table liée. Comment contourner ce problème?
    flet le kid

  15. #15
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    Pour simplifier, modifier légèrement le code avec ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ...
    'On ouvre un recordset type 'Dynaset' sur le nom de la table passée en argument
          Set oRs = oDb.OpenRecordset(sDestTable, dbOpenDynaset)
    
          'Avec le recordset
          With oRs
             'On parcours chaque ligne du tableau (base zéro !) donc lrows - 1
             For l = 0 To lRows - 1
                .FindFirst "CODECLIENT = " & avRows(0, l)
                'Si le code client n'est pas trouvé on créé un nouvel enregistrement dans la table
                If .NoMatch Then
    ...
    Avec <codeclient> le nom du champ de la table liée qui correspond à votre code client.

    Philippe

  16. #16
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    Bonjour,

    GRAND MERCI PHILBEN . Le programme fonctionne correctement .

    Seulement, lorsqu'il y a de nombreuses lignes (près de 50000 dans mon cas), ACCESS prend énormément de temps pour retrouver les données.

    N'y a til pas un moyen d'y remédier?

    Je marque le problème résolu le temps d'attendre une réponse à cette dernière question.

    flet le kid

  17. #17
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    Tes premiers messages ne laissaient pas supposer que tu travaillait avec des tables PostgreSQL et j'ai donc cherché à optimiser la récupération des données d'excel. Finalement, l'optimisation à réaliser ne se situe pas là où je pensais...

    ACCESS prend énormément de temps pour retrouver les données.
    Ben je veux bien te croire que subjectivement le temps est trop long pour toi... Je te dirai bien qu'il faut laisser le temps au temps mais je ne crois pas que ça te contente...

    Si on ne veut pas rentrer dans la "programmation du dimanche" je ne sais pas trop comment améliorer la vitesse qui est dépendante non seulement d'Access mais aussi de facteurs externes (réseau, etc...).

    Si la vitesse est vraiment primordiale et selon le contexte d'utilisation, j'essaierai peut-être une réplication locale de la table pour soulager le réseau puis renvoi du contenu de la table locale après modifications mais ça commence a être de la bidouille...

    Philippe

  18. #18
    Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 170
    Points : 66
    Points
    66
    Par défaut
    Bonsoir,

    merci pour la réponse.

    C'est beau de lire tout ce que tu as dit mais en imaginant le code, je préfère bien m'épargner de misères en m'aventurant à l'heure actuel dans ce combat.

    Je vais donc m'ârrêter là, le sujet pouvant être ouvert à nouveau quand j'aurai fini totalement ce travail.

    Merci encore
    flet le kid

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

Discussions similaires

  1. [AC-2010] besoin d'aide pour valider mes relations entre les tables de ma bdd svp
    Par paulux67 dans le forum Modélisation
    Réponses: 13
    Dernier message: 28/05/2012, 23h59
  2. Réponses: 8
    Dernier message: 14/04/2011, 13h19
  3. [MySQL] Besoin d'astuce pour optimiser le temps de réponse de mes requêtes
    Par karlito40 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 28/01/2011, 17h08
  4. [AC-2007] quelle type de champ utiliser pour obtenir un choix entre plusieurs chaînes
    Par David42000 dans le forum Modélisation
    Réponses: 2
    Dernier message: 09/07/2009, 15h21
  5. Besoin d'aide pour faire un choix de MCD
    Par vallica dans le forum Schéma
    Réponses: 4
    Dernier message: 27/10/2007, 11h38

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