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 :

Mettre à jour une information de date


Sujet :

VBA Access

  1. #1
    Candidat au Club Avatar de L'intendant zonard
    Homme Profil pro
    Intendant de lycée développant des outils à partager avec les collègues
    Inscrit en
    Septembre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Intendant de lycée développant des outils à partager avec les collègues
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2016
    Messages : 9
    Points : 3
    Points
    3
    Par défaut Mettre à jour une information de date
    Bonjour,

    Je suis autodidacte et je contribue à la démarche OpenAcadémie, qui crée des logiciels pour faciliter la vie aux personnels administratifs -et autres- des collèges et des lycées. J'en arrive à poser des questions ici après avoir échoué plusieurs jours à exploiter ce que je trouve dans les discussions existantes. C'est probablement parce que je manque trop encore de vocabulaire et de pratique, mais promis je m'efforce de comprendre vite !

    Soit un logiciel qui sert à imprimer les cartes de lycéen. Tout fonctionne bien, et je voudrais une petite fonction pour afficher la date, si elle existe, à laquelle une carte a déjà été imprimée. Ainsi on évite d'imprimer un doublon, ou on le fait en toute connaissance de cause.

    J'ai créé une table "journalisation" comprenant, outre une clé primaire pour être tranquille, on a la clé de l'élève de la table des élèves, et la date. Plus simple y a pas. Dans le formulaire où l'on choisit l'élève dont on veut imprimer la carte, j'ai fait un petit sous-formulaire rattaché à cette table, avec l'affichage de ces deux informations. Et le bouton qui déclenche l'impression d'une carte a été agrémenté du code VBA suivant, trouvé sur le web :

    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
     'Ajouter une ligne dans la table-journal des éditions de cartes
     
        ' Variables
        Dim rst As DAO.Recordset
     
        ' Ouvrir la table en lecture/écriture
        Set rst = CurrentDb.OpenRecordset("table_journalisation", dbOpenDynaset)
     
                ' Créer un enregistrement dans la table
                rst.AddNew
                ' Alimenter les champs
                rst("Id_Elève") = Id_Elève
                rst("Date_dernière_édition_carte") = Now()
     
            ' Valider
            rst.Update
            Set rst = Nothing
    ... et ça marche ! MAIS... si j'imprime plusieurs fois de suite la même carte, la date affichée reste la même. En fait, le code ci-dessus va créer dans la table de journalisation une nouvelle ligne avec le même numéro d'élève, et une autre date. Et mon sous-formulaire affiche toujours la même !

    J'ai exploré plusieurs pistes, et je n'arrive à en faire marcher aucune, toutes mes tentatives aboutissent au bogue :

    • faire afficher la plus récente des dates concernant cet élève dans le sous-formulaire : je n'ai pas de piste pour obtenir ce comportement
    • effacer l'enregistrement existant sur ce numéro d'élève avant d'en écrire un nouveau (seule la dernière date m'intéresse, je n'ai pas spécialement envie de garder une trace à l'infini de toutes les impressions) : je ne sais pas comment dire au code d'effacer la ligne avec le numéro de cet élève-là
    • mettre à jour l'enregistrement existant au lieu d'en créer un nouveau : même problème pour accéder à cette ligne-là précisément
    • pour les deux cas précédents, j'ai en plus le problème de ne pas parvenir correctement à utiliser des If-Then/Else : ça devrait marcher, mais au fond, puisque les commandes que je veux créer ne marchent pas, pourquoi se laisseraient-elles manier gentiment par les conditions ?


    Bref, je craque un peu. Et il y a pis, dans le message suivant.

  2. #2
    Candidat au Club Avatar de L'intendant zonard
    Homme Profil pro
    Intendant de lycée développant des outils à partager avec les collègues
    Inscrit en
    Septembre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Intendant de lycée développant des outils à partager avec les collègues
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2016
    Messages : 9
    Points : 3
    Points
    3
    Par défaut
    Problème suivant, qui rend ma fonction d'affichage de la date tout aussi inopérante : l'impression par lots. Pas question de lancer l'impression des cartes de lycéen de mes 1200 élèves une à une : j'ai mis au point un formulaire qui m'envoie toute une classe d'un seul coup. Dans le code VBA du bouton qui exécute cela, j'ai tenté de remettre le code ci-dessus qui crée donc des enregistrements dans la table de journalisation des impressions.

    Mais j'ai beau retourner le problème dans tous les sens, ce cochon ne me met qu'un seul élève par classe ! Qu'est-ce que j'ai raté ?

  3. #3
    Candidat au Club Avatar de L'intendant zonard
    Homme Profil pro
    Intendant de lycée développant des outils à partager avec les collègues
    Inscrit en
    Septembre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Intendant de lycée développant des outils à partager avec les collègues
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2016
    Messages : 9
    Points : 3
    Points
    3
    Par défaut MoveNext ne veut pas m'obéir !
    Bon, je persiste à me répondre à moi-même ; j'arriverai peut-être à inspirer la pitié.

    J'ai pas mal progressé, lu plein de trucs, acheté des bouquins, et ça commence à infuser mon petit-pois cervical. L'objectif principal de remplissage d'une table de journalisation des impressions de cartes est atteint, ça marche pas mal. En assurant des tris intelligents, j'arrive à faire s'afficher la valeur qui m'intéresse, ça correspond à mon cahier des charges.

    Mais je coince toujours sur le remplissage de *plusieurs* fiches par la même commande. J'ai appris à faire des boucles, et je pense avoir pigé. Ce qui précisément me semble ne pas marcher dans mon bouzin, c'est la commande MoveNext. Je décris le contexte aussi précisément que possible :

    - soit un formulaire de choix de la classe
    - j'ai ouvert dedans un sous-formulaire où se trouve le bouton lançant le code ci-dessous (impression et journalisation) : je n'ai trouvé que cela pour raccrocher l'information de chaque élève de la classe choisie dans le formulaire principal. Mais, pour l'impression, ça marche très bien.

    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
    Private Sub Commande_lot_cartes_Click()
     
    'Imprimer lot de cartes et noter pour chaque élève concerné que l'on a imprimé sa carte
     
        'Variables
        Dim stDocName As String
        Dim stLinkCriteria As String
     
        'On va pêcher les infos dans le sous-formulaire
        stDocName = "E1081_carte_lyceen"
        stLinkCriteria = "([CléClasse]=[Formulaires]![F055_Selection_classe]![Id_Classe])"
     
        'Maintenant on ouvre l'état pour imprimer
        DoCmd.OpenReport stDocName, acViewPreview, "", stLinkCriteria, acNormal
     
        'Ajouter une ligne dans la table-journal des éditions de cartes
     
        ' Variable
        Dim rst As DAO.Recordset
     
     
        ' Ouvrir la table en lecture/écriture
        Set rst = CurrentDb.OpenRecordset("T01010_journali_impr_cartes", dbOpenDynaset)
     
            ' Boucler aussi longtemps qu'on n'est pas arrivé au bout de la liste en mémoire
             While Not rst.EOF
     
                ' Créer un enregistrement dans la table
                rst.AddNew
     
                ' Alimenter les champs
                rst("Elève No Etab") = [Elève No Etab]
                rst("Date_dernière_édition_carte") = Now()
     
                ' Valider
                rst.Update
     
            'Passer à l'enregistrement suivant (ne marche pas ?)
            rst.MoveNext
     
            'Renvoyer en haut de la boucle
            Wend
     
            'Vider la mémoire
            rst.Close
            Set rst = Nothing
     
    End Sub
    Résultat : boucle infinie, qui me met des centaines de milliers d'enregistrements de toujours le premier élève de la classe (dans l'ordre alphabétique, comme demandé).

    Mon problème conceptuel très précis, c'est que pour moi c'est encore "magique" que les informations dans mon formulaire soient exploitées dans l'état que je lance. En l'espèce et plus précisément encore, c'est vexant parce que l'état sort bien les élèves que j'ai sélectionné, le numéro d'élève est parfaitement utilisé puisque j'ai celui du premier de la liste, mais pas moyen de le faire passer au suivant.

    Je n'aime pas trop la répétition de l'appel au recordset rst, que j'ai l'impression de voir à toutes les sauces. J'ai l'impression qu'il y a une autre ressource que je devrais appeler aussi, mais je ne vois pas laquelle.

    Quelqu'un peut-il m'aider à comprendre ce qui m'échappe encore ?

  4. #4
    Expert confirmé Avatar de nico84
    Homme Profil pro
    Consultant/développeur ERP
    Inscrit en
    Mai 2008
    Messages
    3 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant/développeur ERP
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 3 087
    Points : 5 203
    Points
    5 203
    Par défaut
    Bonjour

    Quand on parcourt un recordset il est toujours délicat d'ajouter ou supprimer des lignes car alors access "perd le fil de son parcours"
    En l'occurrence, addnew "crée un trou sous ses pieds" et movenext lui permet de retrouver sa place initiale

    Pour mémoriser la date dernière impression de carte, il serait plus simple d'ajouter un champ sur la fiche élève et de faire un update de ce champ à chaque impression.
    Exemple de syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    'modif date impression
    currentDB.Execute "UPDATE MaTable set MaDate='" & Date & "' WHERE MonEleve=" & num_eleve, dbFailOnError
    'lecture date impression
    dlookup("MaDate","MaTable","MonEleve=" & num_eleve)
    Utilisez Planet, gestion d'entreprise gratuite pour TPE / PME

  5. #5
    Candidat au Club Avatar de L'intendant zonard
    Homme Profil pro
    Intendant de lycée développant des outils à partager avec les collègues
    Inscrit en
    Septembre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Intendant de lycée développant des outils à partager avec les collègues
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2016
    Messages : 9
    Points : 3
    Points
    3
    Par défaut
    Merci, c'est intéressant comme information ! Un peu consternant aussi sur la limite du logiciel. Mais il n'y a donc pas d'autre variable que je devrais utiliser, ou d'erreur majeure dans mon code. Ouf, je n'ai pas tout raté !

    Hélas, je ne peux pas ajouter un champ dans ma base élèves, car c'est une base que j'importe des outils ministériels officiels, et que je dois pouvoir mettre à jour très souvent. Je suis contraint de faire cela dans une table séparée. Tu me conseillerais plutôt alors de faire une table journalisation avec une ligne par élève, et de seulement mettre à jour la date d'édition en face d'un numéro d'élève le moment venu ?

  6. #6
    Expert confirmé Avatar de nico84
    Homme Profil pro
    Consultant/développeur ERP
    Inscrit en
    Mai 2008
    Messages
    3 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant/développeur ERP
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 3 087
    Points : 5 203
    Points
    5 203
    Par défaut
    Citation Envoyé par L'intendant zonard Voir le message
    Merci, c'est intéressant comme information ! Un peu consternant aussi sur la limite du logiciel. Mais il n'y a donc pas d'autre variable que je devrais utiliser, ou d'erreur majeure dans mon code. Ouf, je n'ai pas tout raté !
    Ce n'est pas spécifique à access, c'est plutot ton algorithme qui fait un pli dans le tapis et se prend les pieds dedans

    Citation Envoyé par L'intendant zonard Voir le message
    Tu me conseillerais plutôt alors de faire une table journalisation avec une ligne par élève, et de seulement mettre à jour la date d'édition en face d'un numéro d'élève le moment venu ?
    Oui, cela veut dire qu'il faut regarder si l'élève existe déjà dans la table (dlookup) :
    - si oui : modif de la date > update
    - sinon : nouvelle ligne > insert
    Utilisez Planet, gestion d'entreprise gratuite pour TPE / PME

  7. #7
    Candidat au Club Avatar de L'intendant zonard
    Homme Profil pro
    Intendant de lycée développant des outils à partager avec les collègues
    Inscrit en
    Septembre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Intendant de lycée développant des outils à partager avec les collègues
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2016
    Messages : 9
    Points : 3
    Points
    3
    Par défaut
    Merci. J'ai commencé par revoir mon dispositif, et faire créer par mon logiciel une table avec le numéro de chaque élève qui attend sagement qu'on vienne lui coller une date dans le champ d'à-côté.

    Ensuite, le code que tu me proposes ci-dessus marche : il me permet de mettre, comme avant, le premier élève de la classe. Pour mettre les autres, je ne sais plus par quel bout attraper ma boucle : dois-je ressortir le tintouin du RecordSet, ou bien il y a-t-il un autre système que je dois utiliser ?

    J'ai essayé avec ce que j'avais, et ça m'a fait un beau plantage, avec le méchant code qui a écrasé tous les élèves existants pour mettre à l'infini le même numéro et la même date. Mais ce doivent être mes moufles qui me gênent...

  8. #8
    Expert confirmé Avatar de nico84
    Homme Profil pro
    Consultant/développeur ERP
    Inscrit en
    Mai 2008
    Messages
    3 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant/développeur ERP
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 3 087
    Points : 5 203
    Points
    5 203
    Par défaut
    Dans la boucle qui parcourt les élèves (de la classe ?) et imprime leur carte il suffit d'ajouter le code déjà indiqué :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    'modif date impression
    currentDB.Execute "UPDATE MaTable set MaDate=date() WHERE MonEleve=" & num_eleve, dbFailOnError
    Utilisez Planet, gestion d'entreprise gratuite pour TPE / PME

  9. #9
    Candidat au Club Avatar de L'intendant zonard
    Homme Profil pro
    Intendant de lycée développant des outils à partager avec les collègues
    Inscrit en
    Septembre 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Intendant de lycée développant des outils à partager avec les collègues
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2016
    Messages : 9
    Points : 3
    Points
    3
    Par défaut
    La boucle que j'ai , c'est celle que tu peux lire ci-dessus, et qui utilise un recordset pour parcourir la table. Comment dois-je procéder ? Est-ce que je continue mes essais avec cette technique, ou faut-il en utiliser une autre ?

    L'impression, elle, est lancée sans boucle : l'état fait plusieurs pages, une par fiche. Je ne suis pas sûr de bien m'exprimer, mais surtout je suis à peu près sûr de ne pas avoir compris vraiment comment ça marche.

  10. #10
    Expert confirmé Avatar de nico84
    Homme Profil pro
    Consultant/développeur ERP
    Inscrit en
    Mai 2008
    Messages
    3 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant/développeur ERP
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 3 087
    Points : 5 203
    Points
    5 203
    Par défaut
    Citation Envoyé par L'intendant zonard Voir le message
    L'impression, elle, est lancée sans boucle : l'état fait plusieurs pages, une par fiche. Je ne suis pas sûr de bien m'exprimer, mais surtout je suis à peu près sûr de ne pas avoir compris vraiment comment ça marche.
    Cela veut dire qu'il faut faire un update de toute la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    currentdb.execute "update table_journalisation t set Date_dernière_édition_carte=date() where exists (select * from TableDesEleves x where t.moneleve=x.moneleve and [CléClasse]=" & [Formulaires]![F055_Selection_classe]![Id_Classe] & ")", dbfailonerror
    (suppose que l'idclasse est numérique)
    Utilisez Planet, gestion d'entreprise gratuite pour TPE / PME

Discussions similaires

  1. [AC-2010] Mettre à jour une date
    Par Marinabo. dans le forum Access
    Réponses: 7
    Dernier message: 26/09/2016, 09h49
  2. report : mettre a jour une information en base ?
    Par Gregney dans le forum SSRS
    Réponses: 2
    Dernier message: 02/04/2015, 22h10
  3. [MySQL] Mettre à jour une donnée d'après une date
    Par padodanle51 dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 08/06/2009, 11h48
  4. Comment mettre à jour une date ?
    Par Hokagge dans le forum MFC
    Réponses: 6
    Dernier message: 22/03/2006, 12h30
  5. Mettre à jour une table depuis une autre
    Par rsc dans le forum SQL
    Réponses: 4
    Dernier message: 09/07/2004, 10h08

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