Actualisation d'un auto-incrément dans un formulaire

Bonjour.

Nouveau problème d’actualisation dans un formulaire…

Dans le formulaire F_VACATIONS, grâce à deux macros (que je ne parviens pas à fusionner en une seule, mais la question n’est pas là), lorsque je crée une nouvelle vacation (formulaire interne frmVacations), la date du jour se remplit (merci à un membre de ce forum) ainsi que deux dates englobant la période (du 1er au 31), dates qui sont récupérées dans la table T_PARAMÈTRES.

Ensuite, dans une liste déroulante, je sélectionne le “couple” bénéficiaire/salarié, défini dans la table T_AFFECTATIONS.

À partir de là, je suis bloqué. Je dois saisir le nombre d’heures effectuées dans le sous-formulaire interne frmVacationsSub (“Lignes de vacation”) mais un message d’erreur m’en empêche puisque le numéro de vacation (VAC_ID, auto-incrément) n’est pas validé. Et évidemment, le second sous-formulaire interne frmAgrements n’affiche rien.

Comment faire pour que VAC_ID se mette à jour et permette la suite une fois la sélection faite dans la liste déroulante ?

Merci.

Note : toutes les données des tables sont bidon.

dbTest01b.odb (452,1 Ko)

Voici le message d’erreur :

Attempt to insert null into a non-nullable column: column: AGR_ID table: T_VACATIONS in statement [INSERT INTO “T_VACATIONS” ( “AFF_ID”,“VAC_DATE”,“VAC_DATE_DEB”,“VAC_DATE_FIN”,“VAC_STT”) VALUES ( ?,?,?,?,?)]

Ce n’est donc pas la clé primaire qui manque. Elle est insérée automatiquement. Le champ “AGR_ID” est indiqué comme champ qui ne doit pas être vide. Tu devrais le modifier.

Je n’avais pas fait attention à la colonne qui ne se mettait pas à jour… :no_mouth:

Les agréments sont liés aux bénéficiaires. Un bénéficiaire peut avoir plusieurs agréments. Dans les faits, il n’y a que les nouveaux bénéficiaires qui n’en n’ont qu’un seul puisque les agréments ont une durée limitée ; ils sont renouvelés ensuite.

Donc, le numéro auto pour les agréments n’a pas lieu d’être. Lorsque l’on sélectionne un couple bénéficiaire/salarié avec la liste déroulante, le lien doit permettre d’afficher les agréments existants du bénéficiaire (comme c’est le cas dans formulaire F_BENEFICIAIRES). Là je constate effectivement que pour les vacations déjà saisies, seul le premier agrément s’affiche.

C’est plus chiant que je pensais et il faut que je revoie les relations…

Je pense avoir trouvé d’où le problème venait. Je précise avant tout qu’il s’agit d’une base qui a été créée à l’origine dans Access et que j’ai recréée dans Base.

  • Les agréments sont reliés aux bénéficiaires (BEN_ID).
  • Les affectations sont reliées aux bénéficiaires (BEN_ID).
  • Les vacations sont reliées aux affectations (AFF_ID).

J’avais relié les agréments aux vacations (AGR_ID), ce qui n’a pas lieu d’être puisqu’il n’y a aucun intérêt à savoir que telle vacation correspond à tel agrément. La table des agréments doit néanmoins figurer dans le formulaire de saisie des vacations, à des fins consultatives, afin de connaître les valeurs à saisir (caisse, heures accordées…) dans le sous-formulaire des lignes de vacation.

À suivre…

Bonjour.

Je remonte ce sujet…

Après avoir scrutté la base, je m’aperçois qu’il y a avait des erreurs de conception et qu’en définitive :

  • Les bénéficiaires sont reliés aux agréments.
  • Les caisses et les complémentaires sont reliées aux agréments.
  • Les agréments sont reliés aux vacations.
  • Les salariés sont reliés aux vacations, plus précisément, au sous-formulaire de lignes de vacation puisqu’il arrive qu’un bénéficiaire ait deux salariés durant le même mois (un exemple avec la dernière vacation du jeu de données test, l’ID 120).
  • Les affectations relient juste les bénéficiaires et leurs salariés titulaires (affectation à durée indéterminée) et les remplacements (affectation à durée déterminée). Utilisées pour imprimer les feuilles de travail à l’entête du salarié et du bénéficiaire (sans intérêt ici).

Tout à l’air ok du point de vue base de données mais reste deux points du côté du code.

Le formulaire F_VACATIONS frmVacations qui contient deux sous-formulaires :

  • frmAgrements
  • frmVacationsSub (lui-même contient frmVacationsSubTtl qui totalise les colonnes mais ne pose aucun problème).
  1. À la création d’une vacation (qui est en fait une facture), on sélectionne d’abord la personne dans la zdl lstAgrId1.

  2. Ensuite, un clic sur le bouton Insérer Agrément déclenche la macro InsererAgrement qui fait le boulot. La seule utilité d’afficher l’agrément correspondant est informatif et on pourrait même s’en passer. Néanmoins, je n’arrive pas à adapter la macro correctement pour que son déclenchement soit affecté à l’événement “Modifié” de lstAgrId1 puisque le bouton utilisé pour les tests est situé dans frmAgrements.

Note : à côté de lstAgrId1 figure une seconde zdl lstAgrId2 qui contient (presque) les mêmes valeurs et qui est désactivée en permanence. La raison est simple. La sélection du bénéficiaire est liée à son agrément. Un bénéficiaire ayant ses agréments renouvelés au fil du temps, j’ai défini cette requête :

SELECT BEN_NOM_1 || ' ' || BEN_PRENOM, MAX(AGR_ID) FROM T_AGREMENTS A INNER JOIN R_BENEFICIAIRES B ON A.BEN_ID = B.BEN_ID GROUP BY BEN_ID, BEN_NOM_1, BEN_PRENOM ORDER BY BEN_NOM_1

Afin que seul le dernier bénéficiaire/agrément soit sélectionnable (sinon au fil du temps on se retrouverait avec un grand nombre d’entrées pointant sur le même bénéficiaire, ce qui ne serait pas agréable, avec en plus le risque de se tromper de ligne). Conséquence : lorsqu’on navigue dans le formulaire d’un enregistrement à l’autre, les vacations qui ont été faites à partir des agréments précédents n’affichent naturellement plus le nom du bénéficiaire dans la zdl. C’est pour cette raison que j’ai placé une zdl “jumelle” avec le SQL suivant afin d’afficher les noms des agréments antérieurs :

SELECT BEN_NOM_1 || ' ' || BEN_PRENOM AS BEN_BENEFICIAIRE, AGR_ID FROM T_AGREMENTS A INNER JOIN R_BENEFICIAIRES B ON A.BEN_ID = B.BEN_ID

Il y a peut-être un moyen de régler ça mais ça n’est pas important.

  1. On sélectionne le salarié.

  2. Et c’est là où ça ne marche pas. Un clic sur le bouton Insérer Ligne Vacation déclenche la macro InsererLigneVacation qui est censée insérer AGR_THN, AGR_PHC, AGR_PHB et AGR_NHA de la table T_AGREMENTS (avec l’AGR_ID correspondant à celui de la vacation), dans VAC_THN, VAC_PHC, VAC_PHB et VAC_NHA de la table T_VACATIONS_SUB, l’opérateur n’ayant plus qu’ensuite à saisir le nombre d’heures effectuées (VAC_NHE). Mais un message d’erreur indique qu’il y a tentative d’insérer un NULL dans la colonne VAC_ID de T_VACATIONS_SUB alors que l’identifiant est bien affiché dans ladite colonne (et évidemment correspond à celui de T_VACATIONS). Il y a à coup sûr une erreur dans la requête de la macro mais je ne sais pas la résoudre.

Merci…

dbPrimus20240505.odb (83,1 Ko)

C’est la commande que tu essaies de donner :

INSERT INTO T_VACATIONS_SUB (VAC_THN, VAC_PHC, VAC_PHB, VAC_NHA) 
SELECT AGR_THN, AGR_PHC, AGR_PHB, AGR_NHA 
FROM T_AGREMENTS WHERE AGR_ID = 1

Tu as déclaré 2 clés primaires pour la table : VAC_ID et SAL_ID. Les champs clés ne sont pas des champs de valeurs automatiques. Ce n’est d’ailleurs pas possible avec deux champs. Ils doivent donc être présents lors de la commande d’insertion des données.

Cela donne le VAC_ID que tu n’as pas dans le code:

inVac_ID = objForm.getInt(objForm.findColumn("VAC_ID"))

Mais dès que tu le saisis dans la commande SQL, le champ suivant apparaît. C’est alors le SAL_ID qui manque.

Je ne comprends pas ce que tu veux dire. La double clé primaire est habituelle dans un sous-formulaire. Pour une ligne de facture, d’un côté elle est liée au corps de la facture et de l’autre aux produits. Là c’est le même principe. Les doublons étant interdits, ça empêche de saisir deux lignes avec le même “produit” (ici le même salarié ne peut être déclaré deux fois dans la même vacation, ce qui est normal).

Oui mais je sélectionne SAL_ID avant de lancer la macro. Je ne comprends donc pas non plus. Et d’ailleurs, le message d’erreur indique que c’est VAC_ID (et non pas SAL_ID) qui demeure NULL alors que la valeur est reportée dans la colonne après avoir exécuté la première macro. Pour moi l’insertion automatique des 4 colonnes revenait au même que de le faire à la main ; restait plus qu’à saisir VAC_NHE (nombre d’heures effectuées) et de tabuler pour valider la ligne.

Ça ne m’avance pas plus…

Avec la macro, tu fais une commande d’insertion directement dans SQL. Et il manque à cette commande les champs correspondants “VAC_ID” et “SAL_ID”.

Ta macro ne tient pas compte de ce qui se passe dans le formulaire mais doit créer un nouvel enregistrement dans la table “T_AGREMENTS”.

Tu ne veux probablement pas exécuter de commande SQL mais insérer des valeurs correspondantes dans des champs de formulaire. Pour cela, tu dois exécuter une commande Select et lire les différents champs.

Tout est traduit ici avec DeepL Je ne sais pas du tout lire et écrire le français.

OK. The query in itself works correctly (I made a test in another table, the 4 columns are filled).

What I would like : only “copy” the 4 columns from T_AGREMENTS to the 4 columns of T_VACATIONS_SUB, taking account of the AGR_ID specified in the query, after selected the maid in the listbox.

La requête en elle-même fonctionne correctement (j’ai fait un test avec une autre table, les 4 colonnes sont remplies).

Ce que je veux : juste “copier” les 4 colonnes de la table T_AGREMENTS dans la table T_VACATIONS_SUB en tenant compte de l’identifiant AGR_ID précisé dans la requête, ceci après avoir sélectionné le salarié dans la zone de liste.

Have a look at macro code. Copies new values in tablecontrol, but wont save it.
dbPrimus20240505.odb (83.1 KB)

Eh bien là c’est bon. Merci encore… :wink: