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 :

Ajout d'enregistrements dans une table dont un champ est le résultat d'une requête [AC-2003]


Sujet :

Requêtes et SQL.

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Février 2014
    Messages : 75
    Points : 49
    Points
    49
    Par défaut Ajout d'enregistrements dans une table dont un champ est le résultat d'une requête
    Bonjour,

    débutant en VBA Access, je rencontre ce problème:

    Je dispose d'une table initiale "VolumesReels" avec les champs "Client", "Volume" et "Semaine" où je sais quel client a demandé tel volume lors de telle semaine.

    Mon objectif est de réaliser une table listant pour chaque semaine le volume total, tous clients confondus (en bouclant donc sur le nombre de semaines). Ses deux champs sont : « semaine » et « sommeVolume »

    Voici le code que j’ai réalisé (s’exécute lorsque je clique sur le bouton d’un formulaire) :

    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
    Private Sub Commande0_Click()
    ' Quelques variables
        Dim rst As DAO.Recordset
        Dim i As Long
        Dim strSQL As String
        ' Ouvrir la table en lecture/écriture
        Set rst = CurrentDb.OpenRecordset("tableSommeVolume", dbOpenDynaset)
        ' Boucler sur le nombre de semaines
        For i = 1 To 52
            ' Créer un enregistrement dans la table
        With DoCmd
        .SetWarnings False   'Désactive les alertes
        .RunSQL ("delete * from [tableSommeVolume] where [Semaine] =" & i & ";")
        .SetWarnings True
      End With 
            rst.AddNew
            ' Alimenter les champs
            rst("semaine") = i
        strSQL = "SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine " &
        "FROM VolumesReels " & _
        "GROUP BY VolumesReels.Semaine " & _
        "HAVING VolumesReels.Semaine =" & i & ";" 
         rst("sommeVolume") = DoCmd.RunSQL(strSQL)
            ' Valider
            rst.Update
        Next
        rst.Close
        Set rst = Nothing
        MsgBox "Opération terminée !", vbInformation
    End Sub
    La partie qui met à jour le champ « semaine » fonctionne mais pas celle qui doit mettre à jour sommeVolume. J’obtiens l’erreur « fonction ou variable attendue » qui pointe sur DoCmd.RunSQL et se réfère à Private Sub Commande0_Click().

    Merci d’avance pour vos réponses et n'hésitez pas à me demander des précisions si besoin.

  2. #2
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    ostrich95,

    Cà ne marchera jamais !


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rst("sommeVolume") = DoCmd.RunSQL(strSQL)
    tu essaies d'affecter dans un champ l’exécution d'une requête. Tu dois faire un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Set rst = oDb.OpenRecordset("SELECT .....")
      '
    If rst.RecordCount <>0 Then
        rst("sommeVolume") = rst.Fields(0)  'renvoie le premier argument de la requête
    Else
       rst("sommeVolume") = 0	
    End If
    et ainsi récupérer le résultat renvoyé par la requête

    JimBoLion
    N'oubliez pas le Tag si la réponse donnée vous a été utile et pour une réponse pertinente.
    Retrouvez-moi sur le chat en salon base de données

  3. #3
    Membre du Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Février 2014
    Messages : 75
    Points : 49
    Points
    49
    Par défaut
    Merci de ta réponse JimBoLion!

    Je ne comprends pas quelque chose: le rst que tu utilises et celui que j'utilise sont-ils différents?

    car j'ai besoin de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set rst = CurrentDb.OpenRecordset("tableSommeVolume", dbOpenDynaset)
    pour pouvoir ajouter des enregistrements à la table alors que je ne vois pas comment faire avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set rst = oDb.OpenRecordset("SELECT .....")
    Si tu peux éclaircir ce point qui est sûrement évident...

  4. #4
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    Sur quelle requête souhaites tu établir ton calcul (la requête stockée)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set rst_2 = CurrentDb.OpenRecordset("tableSommeVolume", dbOpenDynaset)
    ou celle ci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    strSQL = "SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine " &
        "FROM VolumesReels " & _
        "GROUP BY VolumesReels.Semaine " & _
        "HAVING VolumesReels.Semaine =" & i & ";"
    pour bien faire j'aurais pu mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set rst_2 = oDb.OpenRecordset("SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine FROM VolumesReels  GROUP BY VolumesReels.Semaine HAVING VolumesReels.Semaine =" & i & ";")

    et récupérer ensuite le retour par rst("sommeVolume") = rst_2.Fields(0) (pour ne pas écraser le rst précédent)

    comme tu l'as bien fait d'ailleurs dans CurrentDb.OpenRecordset("tableSommeVolume", dbOpenDynaset)

    Copier-coller attention à vérifier la syntaxe

    Dans le principe tu es ok !
    N'oubliez pas le Tag si la réponse donnée vous a été utile et pour une réponse pertinente.
    Retrouvez-moi sur le chat en salon base de données

  5. #5
    Membre du Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Février 2014
    Messages : 75
    Points : 49
    Points
    49
    Par défaut
    Voici l'état actuel de mon code

    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 Commande0_Click()
    ' Quelques variables
        Dim rst_2 As DAO.Recordset
        Dim rst As DAO.Recordset
        Dim i As Long
        Dim strSQL As String
        ' Ouvrir la table en lecture/écriture
        Set rst = CurrentDb.OpenRecordset("tableSommeVolume", dbOpenDynaset)
        ' Boucler sur le nombre de semaines
     
        For i = 1 To 52
            ' Créer un enregistrement dans la table
        With DoCmd
        .SetWarnings False   'Désactive les alertes
        .RunSQL ("delete * from [tableSommeVolume] where [Semaine] =" & i & ";")
        .SetWarnings True
      End With
     
            rst.AddNew
            ' Alimenter les champs
            rst("semaine") = i
     
        Set rst_2 = CurrentDb.OpenRecordset("SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine FROM VolumesReels  GROUP BY VolumesReels.Semaine HAVING VolumesReels.Semaine =" & i & ";")
        rst("sommeVolume") = rst_2.Fields(0)
     
            ' Valider
            rst.Update
        Next
        rst.Close
        Set rst = Nothing
     
        MsgBox "Opération terminée !", vbInformation
    End Sub

    Dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set rst = oDb.OpenRecordset("SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine FROM VolumesReels  GROUP BY VolumesReels.Semaine HAVING VolumesReels.Semaine =" & i & ";")
    ce que tu nommes oDb est bien CurrentDb?

    Car voici l'erreur que j'obtiens:

    "erreur d'exécution 3021 : aucun enregistrement en cours"
    et ça me renvoie à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rst("sommeVolume") = rst_2.Fields(0)

  6. #6
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    ostrich95,

    C'est pour cela que j'avais mis le test ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If rst.RecordCount <>0 Then
        rst("sommeVolume") = rst.Fields(0)  'renvoie le premier argument de la requête
    Else
       rst("sommeVolume") = 0	
    End If
    rst à transformer rst_2 bien évidemment

    mon odb correspond bien à currentdb en effet

    maintenant si la requête ne te retourne rien, c'est que soit il n'existe pas d'enregistrements à retourner soit il y a une erreur dans ta requête

    En utilisant debug.print tu vas pouvoir afficher le contenu de ta requête dans la fenêtre d’exécution, et la copier dans l'assistant requête pour voir ce qui ne vas pas !

    après ta requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    debug.print "SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine FROM VolumesReels  GROUP BY VolumesReels.Semaine HAVING VolumesReels.Semaine =" & i & ";"
    ou

    si tu as gardé cette méthode

    JimBoLion
    N'oubliez pas le Tag si la réponse donnée vous a été utile et pour une réponse pertinente.
    Retrouvez-moi sur le chat en salon base de données

  7. #7
    Membre du Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Février 2014
    Messages : 75
    Points : 49
    Points
    49
    Par défaut
    Bon revoilà mon code:
    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
    Private Sub Commande0_Click()
    ' Quelques variables
        Dim rst_2 As DAO.Recordset
        Dim rst As DAO.Recordset
        Dim i As Long
        Dim strSQL As String
        ' Ouvrir la table en lecture/écriture
        Set rst = CurrentDb.OpenRecordset("tableSommeVolume", dbOpenDynaset)
        ' Boucler sur le nombre de semaines
     
        For i = 1 To 52
            ' Créer un enregistrement dans la table
        With DoCmd
        .SetWarnings False   'Désactive les alertes
        .RunSQL ("delete * from [tableSommeVolume] where [Semaine] =" & i & ";")
        .SetWarnings True
      End With
     
            rst.AddNew
            ' Alimenter les champs
            rst("semaine") = i
     
        Set rst_2 = CurrentDb.OpenRecordset("SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine FROM VolumesReels  GROUP BY VolumesReels.Semaine HAVING VolumesReels.Semaine =" & i & ";")
        strSQL = "SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine FROM VolumesReels  GROUP BY VolumesReels.Semaine HAVING VolumesReels.Semaine =" & i & ";"
     
     
        Debug.Print strSQL
     
        rst("sommeVolume") = rst_2.Fields(0)
     
        If rst_2.RecordCount <> 0 Then
            rst("sommeVolume") = rst_2.Fields(0)  'renvoie le premier argument de la requête
        Else
            rst("sommeVolume") = 0
        End If
     
        ' Valider
        rst.Update
        Next
        rst.Close
        Set rst = Nothing
     
        MsgBox "Opération terminée !", vbInformation
    End Sub
    Dis moi si j'ai mis le Debug.Print au bon endroit et surtout je ne sais pas comment l'utiliser!

    Encore merci de me consacrer un peu de ton temps!

  8. #8
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    ostrich95,

    Avant de te fournir une réponse quelques explications sur ton code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    For i = 1 To 52
            ' Créer un enregistrement dans la table
        With DoCmd
        .SetWarnings False   'Désactive les alertes
        .RunSQL ("delete * from [tableSommeVolume] where [Semaine] =" & i & ";")
        .SetWarnings True
      End With....
    1. Le next se retrouve en fin de procédure, ce qui veut clairement dire qu'à chaque fois tu lances la suppression sur chaque itération de ta boucle. Pourquoi ne pas lancer une seule fois ta suppression en supprimant la condition semaine (gain de performances) et agir ensuite sur la boucle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    With DoCmd
        .SetWarnings False   'Désactive les alertes
        .RunSQL ("delete * from [tableSommeVolume];")
        .SetWarnings True
        For i = 1 To 52 ....
    sur cette partie tu ne dois pas affecter rst_2.Fields(0) dans rst("sommeVolume") avant le test if..else...end if

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    rst("sommeVolume") = rst_2.Fields(0)
     
        If rst_2.RecordCount <> 0 Then
            rst("sommeVolume") = rst_2.Fields(0)  'renvoie le premier argument de la requête
        Else
            rst("sommeVolume") = 0
        End If

    Ensuite sur le reste, mis à part quelques erreurs mineures le traitement devrait fonctionner, donc nous en arrivons aux quelques correctifs incluant ton debug.print (à enlever lorsque tu auras trouvé ta solution)

    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
    Private Sub Commande0_Click()
    ' Quelques variables
        Dim rst_2 As DAO.Recordset
        Dim rst As DAO.Recordset
        Dim i As Long
        Dim strSQL As String
        ' Ouvrir la table en lecture/écriture
        Set rst = CurrentDb.OpenRecordset("tableSommeVolume", dbOpenDynaset)
        ' Boucler sur le nombre de semaines
        '
        With DoCmd
            .SetWarnings False   'Désactive les alertes
            .RunSQL ("delete * from [tableSommeVolume];")       ' effacement global de toutes les semaines
            .SetWarnings True
        End With
        '
        For i = 1 To 52
            ' Créer un enregistrement dans la table
     
     
            rst.AddNew
            ' Alimenter les champs
            rst("semaine") = i
        '
        strSQL = "SELECT Sum(VolumesReels.Volume) AS SommeDeVolume, VolumesReels.Semaine FROM VolumesReels  GROUP BY VolumesReels.Semaine HAVING VolumesReels.Semaine =" & i & ";"
        '
        Set rst_2 = CurrentDb.OpenRecordset(strSQL)
        Debug.Print strSQL
        '
        If rst_2.RecordCount <> 0 Then
            rst("sommeVolume") = rst_2.Fields(0)    'renvoie le premier argument de la requête
        Else
            rst("sommeVolume") = 0                  ' si aucun enregistrement alors 0 dans sommeValue
        End If
     
        ' Valider
        rst.Update
        rst_2.Close
        Next
        rst.Close
        Set rst = Nothing
        Set rst_2 = Nothing
     
        MsgBox "Opération terminée !", vbInformation
    End Sub
    Explications sur le debug.print

    Tu executes ta fonction en appuyant sur le bouton clic de ton formulaire.
    Dans la fenêtre d’exécution tu verras donc apparaître les n dernières semaines contenant le passage sur chaque requête, tu copies une ligne et tu crées une nouvelle requête (tu passes en mode SQL). Tu colles le résultat de cette ligne et tu regardes en mode création ce que cela donne (si elle répond bien à tes attentes).

    Tu peux également travailler avec des points d'arrêts, ce qui te permets de suivre pas à pas l’exécution de ton code (vérifier les passages sur les lignes, fonctions appelées, variables d’exécution...). Ces fonctions debug sont très pratiques quant à la recherche des éventuelles erreurs. Access à contrario de certains langages nous offre ces possibilités, autant s'en servir.

    Regarde ce tuto de Cafeine : http://cafeine.developpez.com/access...el/debugprint/

    JimBoLion
    N'oubliez pas le Tag si la réponse donnée vous a été utile et pour une réponse pertinente.
    Retrouvez-moi sur le chat en salon base de données

  9. #9
    Membre du Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Février 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Février 2014
    Messages : 75
    Points : 49
    Points
    49
    Par défaut
    ça fonctionne! Merci infiniment! Comme quoi je n'étais pas si loin dans l'idée mais la rigueur et les petits détails font toute la différence! Et merci pour le tuto sur le débogage, je m'y mets!

    Je passe le sujet en résolu et te souhaite (peut-être) à bientôt pour un nouveau sujet!

  10. #10
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut
    ostrich95,

    Oui effectivement ta solution était toute proche.

    N'oublie pas d'enleverle debug.print !

    Toute cette problématique aurait pu être gérée directement par requête, dans ce cas 3 lignes de code aurait suffit mais ton approche permet de mettre la main dans le code.

    Bonne continuation et au plaisir de se retrouver


    JimBoLion
    N'oubliez pas le Tag si la réponse donnée vous a été utile et pour une réponse pertinente.
    Retrouvez-moi sur le chat en salon base de données

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/07/2014, 14h44
  2. [AC-2003] Requete qui écrit dans une table dont un champ est un format personnalisé
    Par ostrich95 dans le forum Requêtes et SQL.
    Réponses: 30
    Dernier message: 19/03/2014, 14h21
  3. Accéder à une table dont le nom est dans une table
    Par claralavraie dans le forum Oracle
    Réponses: 7
    Dernier message: 26/12/2006, 15h51

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