Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Champs calculés

4 réponses
Avatar
Gloops
Bonjour tout le monde,

Sur un formulaire, j'ai une zone de texte qui contient comme source une=20
formule bas=E9e sur les contenus de deux autres zones de texte, du m=EAme=
=20
formulaire. Dans un autre exemple l'un des deux champs sur lesquels est=20
bas=E9 le calcul est une zone de texte du formulaire parent.

=E7a, =E7a fonctionne tr=E8s bien en mode formulaire, avec un Requery dan=
s le=20
Form_Current.

Maintenant, le formulaire doit =EAtre affich=E9 en mode table. =E7a m'a l=
'air=20
bien plus d=E9licat de mettre tout =E0 jour =E0 la fois. Si l'utilisateur=
=20
place la souris successivement sur tous les champs calcul=E9s il finit pa=
r=20
avoir tous les champs =E0 jour, mais sa satisfaction d=E9croit =E0 mesure=
,=20
surtout si il faut revenir plusieurs fois sur le m=EAme champ car entre=20
deux il se remet =E0 blanc.

Une solution qui vient =E0 l'esprit est de baser le formulaire sur une=20
requ=EAte incluant les champs calcul=E9s, mais comme ils sont calcul=E9s =
entre=20
autres sur la base d'un champ saisi dans le m=EAme enregistrement, a=20
priori je me m=E9fie un peu. Le Requery, en tout cas dans le Form_Current=
,=20
ne s'applique qu'=E0 l'enregistrement courant.

On pourrait bien imaginer une boucle qui parcourt les enregistrements du =

formulaire pour les mettre =E0 jour, mais si c'est par DoCmd.Goto =E7a ne=
=20
fonctionne que pour le formulaire principal, ou alors j'ai loup=E9 un=20
truc. Habituellement je fais plut=F4t un requery apr=E8s avoir mis =E0 jo=
ur la=20
table, d'o=F9 dans ce cas retour =E0 ce que je viens d'=E9voquer juste av=
ant.

Quelqu'un aurait-il d=E9j=E0 explor=E9 ce type de terrain ?

4 réponses

Avatar
3stone
Salut,

Gloops wrote:
Bonjour tout le monde,

Sur un formulaire, j'ai une zone de texte qui contient comme source
une formule basée sur les contenus de deux autres zones de texte, du
même formulaire. Dans un autre exemple l'un des deux champs sur
lesquels est basé le calcul est une zone de texte du formulaire
parent.

ça, ça fonctionne très bien en mode formulaire, avec un Requery dans
le Form_Current.



Ce requery est inutile et même superflu...


Maintenant, le formulaire doit être affiché en mode table. ça m'a
l'air bien plus délicat de mettre tout à jour à la fois.



Si le deux premiers champs font bien partie de la source,
il n'y a pas de probleme, tant en formulaire unique, continu
ou en feuille de données.


Si
l'utilisateur place la souris successivement sur tous les champs
calculés il finit par avoir tous les champs à jour, mais sa
satisfaction décroit à mesure, surtout si il faut revenir plusieurs
fois sur le même champ car entre deux il se remet à blanc.




"Tous les champs champs calculés" ?
Tu aurais recréé une feuille Excel ??



Une solution qui vient à l'esprit est de baser le formulaire sur une
requête incluant les champs calculés,



Oui, autant que possible, il est préférable de faire les calculs dans la requête.

mais comme ils sont calculés
entre autres sur la base d'un champ saisi dans le même
enregistrement, a priori je me méfie un peu.




Un champ saisi dans le même enregistrement ? comprend pas...


Le Requery, en tout cas
dans le Form_Current, ne s'applique qu'à l'enregistrement courant.




Me.Requery rafraichi la source du formulaire, donc agit sur tous
les enregistrements !



On pourrait bien imaginer une boucle qui parcourt les enregistrements
du formulaire pour les mettre à jour, mais si c'est par DoCmd.Goto ça



Beeerg !!


ne fonctionne que pour le formulaire principal, ou alors j'ai loupé un
truc. Habituellement je fais plutôt un requery après avoir mis à jour
la table, d'où dans ce cas retour à ce que je viens d'évoquer juste
avant.



Ton problème semble plutôt provenir d'une mauvaise organisation
générale, mais avec une description si floue...

--
A+
Pierre (3stone) Access MVP
Perso: http://www.3stone.be/
MPFA: http://www.mpfa.info/ (infos générales)
Avatar
Gloops
3stone a écrit, le 02/12/2010 14:35 :
Salut,

Gloops wrote:
Bonjour tout le monde,

Sur un formulaire, j'ai une zone de texte qui contient comme source
une formule basée sur les contenus de deux autres zones de texte, du
même formulaire. Dans un autre exemple l'un des deux champs sur
lesquels est basé le calcul est une zone de texte du formulaire
parent.

ça, ça fonctionne très bien en mode formulaire, avec un Requery dans
le Form_Current.



Ce requery est inutile et même superflu...



Ah oui ?
Ah c'est pour une liste, qu'il est nécessaire, je crois ?
Je me rappelle avoir vu quelque chose qui ne se mettait à jour que sur
demande.



Maintenant, le formulaire doit être affiché en mode table. ça m' a
l'air bien plus délicat de mettre tout à jour à la fois.



Si le deux premiers champs font bien partie de la source,
il n'y a pas de probleme, tant en formulaire unique, continu
ou en feuille de données.




Ah, je ne sais pas ce que j'ai mal fait, mais ça n'a pas l'air probant.
A cette heure je ne sais plus les noms de champs précis mais je vais
prendre un exemple standard, en plus ça sera plus facile à suivre.
Mettons que dans la requête j'ai un prix unitaire et une quantité. J' ai
un champ texte qui calcule le prix total. En mode formulaire il se
réfère bien au prix unitaire et à la quantité de l'enregistrement en
cours. En mode table ça se met à jour un peu quand ça a le temps.

Après, j'ai aussi un autre champ texte qui calcule le prix TTC, en se
basant sur le taux de TVA fourni dans le formulaire parent.

En fait, dans l'exemple que j'ai à mettre sur pied, il s'agit de
calculer des intervalles de dates, mais le principe est le même.

Les dates sont bien stockées chacune dans un champ au format date, et
pas sur trois champs jour, mois, année, comme j'ai parfois vu expérim enter.



Si
l'utilisateur place la souris successivement sur tous les champs
calculés il finit par avoir tous les champs à jour, mais sa
satisfaction décroit à mesure, surtout si il faut revenir plusieur s
fois sur le même champ car entre deux il se remet à blanc.




"Tous les champs champs calculés" ?
Tu aurais recréé une feuille Excel ??



Il y a trois champs calculés. Deux intervalles de dates sur des dates d e
l'enregistrement courant (donc même principe que prix unitaire x
quantité), et un entre une date de l'enregistrement courant et une date
indiquée dans le formulaire parent (donc même principe, pour ce qui e st
de l'emplacement des données, que pour calculer une TVA avec le taux
indiqué dans le formulaire parent).





Une solution qui vient à l'esprit est de baser le formulaire sur une
requête incluant les champs calculés,



Oui, autant que possible, il est préférable de faire les calculs da ns la requête.



C'est plus lourd, mais je vais essayer ça. J'attendais de voir ce qui
allait être dit ici, des fois qu'il y ait une idée qui me dispense de
cet exercice.



mais comme ils sont calculés
entre autres sur la base d'un champ saisi dans le même
enregistrement, a priori je me méfie un peu.




Un champ saisi dans le même enregistrement ? comprend pas...



comme le prix total, basé sur prix unitaire et quantité




Le Requery, en tout cas
dans le Form_Current, ne s'applique qu'à l'enregistrement courant.




Me.Requery rafraichi la source du formulaire, donc agit sur tous
les enregistrements !



Ah, oui. C'est le changement d'enregistrement qui déclenche
Form_Current, mais effectivement ...

C'était trop pratique, le calcul fait dans une zone de texte. Bon, je
vais le faire dans la requête. ça va être assez simple pour la
différence entre deux champs de l'enregistrement courant (modèle prix
unitaire * quantité), pour appeler un champ du formulaire parent ça
risque d'imposer une syntaxe plus lourde. Ah ou je crée un champ de la
requête juste pour rappeler ce champ sur tous les enregistrements. ça
fait "ballot", conceptuellement, mais ça permet à Access de faire les
calculs au bon moment.

Ah oui alors du coup le Requery va refaire tous les calculs, sur tous
les enregistrements. Dommage, côté temps de réponse ?

Ah, je viens de me rendre compte de l'incohérence de ce que je dis.
Puisque ce qui m'amène est justement de pouvoir mettre à jour tous le s
champs ...

C'est vrai en fait que la valeur ne change que sur l'enregistrement
courant. Mais aussi bien peut-être qu'Access se débrouille pour
optimiser à l'exécution ?


On pourrait bien imaginer une boucle qui parcourt les enregistrements
du formulaire pour les mettre à jour, mais si c'est par DoCmd.Goto ç a



Beeerg !!



Ah, c'est sûr que côté classe, ça pêche.




ne fonctionne que pour le formulaire principal, ou alors j'ai loupé un
truc. Habituellement je fais plutôt un requery après avoir mis à jour
la table, d'où dans ce cas retour à ce que je viens d'évoquer ju ste
avant.



Ton problème semble plutôt provenir d'une mauvaise organisation
générale, mais avec une description si floue...




J'espère avoir un petit peu éclairci ?

Demain j'essaie avec les calculs dans la requête. J'y allais à reculo ns,
mais puisque c'est aussi ton idée ...
Avatar
3stone
Salut,

Gloops wrote:
3stone a écrit, le 02/12/2010 14:35 :
Salut,

Gloops wrote:
Bonjour tout le monde,

Sur un formulaire, j'ai une zone de texte qui contient comme source
une formule basée sur les contenus de deux autres zones de texte, du
même formulaire. Dans un autre exemple l'un des deux champs sur
lesquels est basé le calcul est une zone de texte du formulaire
parent.

ça, ça fonctionne très bien en mode formulaire, avec un Requery dans
le Form_Current.



Ce requery est inutile et même superflu...



Ah oui ?
Ah c'est pour une liste, qu'il est nécessaire, je crois ?
Je me rappelle avoir vu quelque chose qui ne se mettait à jour que sur
demande.




Lorsque l'on fait des modifications via l'interface, elles se
répercutent sur la source... mais, si tu modifies la source, directement
dans la table, par du VBA par exemple, alors il faut mettre à jour
l'interface qui est basé sur cette source.
Tant que tu reste dans l'interface, un Me.Recalc fait l'affaire
très souvent, si tant est que c'est nécessaire.


Maintenant, le formulaire doit être affiché en mode table. ça m'a
l'air bien plus délicat de mettre tout à jour à la fois.



Si le deux premiers champs font bien partie de la source,
il n'y a pas de probleme, tant en formulaire unique, continu
ou en feuille de données.




Ah, je ne sais pas ce que j'ai mal fait, mais ça n'a pas l'air
probant.
A cette heure je ne sais plus les noms de champs précis mais je vais
prendre un exemple standard, en plus ça sera plus facile à suivre.
Mettons que dans la requête j'ai un prix unitaire et une quantité.
J'ai
un champ texte qui calcule le prix total. En mode formulaire il se
réfère bien au prix unitaire et à la quantité de l'enregistrement en
cours. En mode table ça se met à jour un peu quand ça a le temps.

Après, j'ai aussi un autre champ texte qui calcule le prix TTC, en se
basant sur le taux de TVA fourni dans le formulaire parent.



Dans la requête, un champ calculé :

PTot: [PU] * [QT]

PTVAC: ([PU] * [Qt]) * [TVA]

en expriment la tva comme 1.21

Le formulaire sera basé sur cette requête, et aucun calcul ne
sera n'écessaire dans le formulaire.



En fait, dans l'exemple que j'ai à mettre sur pied, il s'agit de
calculer des intervalles de dates, mais le principe est le même.

Les dates sont bien stockées chacune dans un champ au format date, et
pas sur trois champs jour, mois, année, comme j'ai parfois vu
expérimenter.




Bien sûr, une date est une date, et permettra par la suite d'en extraire
bien plus que des nom ou numéro de mois...





Si
l'utilisateur place la souris successivement sur tous les champs
calculés il finit par avoir tous les champs à jour, mais sa
satisfaction décroit à mesure, surtout si il faut revenir plusieurs
fois sur le même champ car entre deux il se remet à blanc.




"Tous les champs champs calculés" ?
Tu aurais recréé une feuille Excel ??



Il y a trois champs calculés. Deux intervalles de dates sur des dates
de
l'enregistrement courant (donc même principe que prix unitaire x
quantité), et un entre une date de l'enregistrement courant et une
date
indiquée dans le formulaire parent (donc même principe, pour ce qui
est
de l'emplacement des données, que pour calculer une TVA avec le taux
indiqué dans le formulaire parent).




Parfois, et même souvent, une petite fonction VBA rend le tout beaucoup
plus simple et transparent...

Function fnCalculComplexe( date1, date2, valeur1, valeur2) as Double
'faire les test sur les valeurs... et traiter...
...
'les calculs de la fonction
...
' éventuellement pointer un formulaire ouvert pour récupérer
' une valeur si celle-ci ne peut être transmise à la fonction
' ou utilise une variable globale
...

'attribuer le résultat à la fonction
fnCalculComplexe = LeResultat
End Function

et alors, dans la requête ou ailleurs, un simple appel

ChampX: fnCalculComplexe(DateA;DateB;ValeurA;ValeurB)

et bien sûr, cela ne se sauve pas dans la base, mais sert à l'affichage
ou à la réalisation d'un état...



Une solution qui vient à l'esprit est de baser le formulaire sur une
requête incluant les champs calculés,



Oui, autant que possible, il est préférable de faire les calculs
dans la requête.



C'est plus lourd, mais je vais essayer ça. J'attendais de voir ce qui
allait être dit ici, des fois qu'il y ait une idée qui me dispense de
cet exercice.



mais comme ils sont calculés
entre autres sur la base d'un champ saisi dans le même
enregistrement, a priori je me méfie un peu.




Un champ saisi dans le même enregistrement ? comprend pas...



comme le prix total, basé sur prix unitaire et quantité





Voir plus haut...



Le Requery, en tout cas
dans le Form_Current, ne s'applique qu'à l'enregistrement courant.




Me.Requery rafraichi la source du formulaire, donc agit sur tous
les enregistrements !



Ah, oui. C'est le changement d'enregistrement qui déclenche
Form_Current, mais effectivement ...

C'était trop pratique, le calcul fait dans une zone de texte. Bon, je
vais le faire dans la requête. ça va être assez simple pour la
différence entre deux champs de l'enregistrement courant (modèle prix
unitaire * quantité), pour appeler un champ du formulaire parent ça
risque d'imposer une syntaxe plus lourde.




Dans la requête, il est préférable d'utiliser une fonction, la requête
restant beaucoup plus lisible et manipulable.
Et, en utilisant un nom de fonction "parlant" on sait ce qu'elle
va nous ramener comme valeur.



Ah ou je crée un champ de la
requête juste pour rappeler ce champ sur tous les enregistrements. ça
fait "ballot", conceptuellement, mais ça permet à Access de faire les
calculs au bon moment.

Ah oui alors du coup le Requery va refaire tous les calculs, sur tous
les enregistrements. Dommage, côté temps de réponse ?




un requery inutile re-exécute en effet la requête et ces calculs,
c'est pourquoi il ne faut pas utiliser de requery juste parce-que
l'on "pense" qu'il faut en coller partout.


--
A+
Pierre (3stone) Access MVP
Perso: http://www.3stone.be/
MPFA: http://www.mpfa.info/ (infos générales)
Avatar
Gloops
3stone a écrit, le 04/12/2010 15:29 :
Lorsque l'on fait des modifications via l'interface, elles se
répercutent sur la source... mais, si tu modifies la source, directem ent
dans la table, par du VBA par exemple, alors il faut mettre à jour
l'interface qui est basé sur cette source.
Tant que tu reste dans l'interface, un Me.Recalc fait l'affaire
très souvent, si tant est que c'est nécessaire.




Ah ben là je suis bon pour le bonnet d'âne : ça fait dix ans que je
programme sous Access, et je ne connaissais pas Form.Recalc

Dans la requête, un champ calculé :

PTot: [PU] * [QT]

PTVAC: ([PU] * [Qt]) * [TVA]

en expriment la tva comme 1.21

Le formulaire sera basé sur cette requête, et aucun calcul ne
sera n'écessaire dans le formulaire.




Oui alors il faut l'exprimer dans la requête source, j'imagine ?


Parfois, et même souvent, une petite fonction VBA rend le tout beauco up
plus simple et transparent...



Ah oui ça je pratique assez couramment.
Et je l'appelle aussi bien depuis un formulaire ou un état que depuis
une requête SQL.

Dans la requête, il est préférable d'utiliser une fonction, la re quête
restant beaucoup plus lisible et manipulable.
Et, en utilisant un nom de fonction "parlant" on sait ce qu'elle
va nous ramener comme valeur.



Bien entendu.

un requery inutile re-exécute en effet la requête et ces calculs,
c'est pourquoi il ne faut pas utiliser de requery juste parce-que
l'on "pense" qu'il faut en coller partout.



ou ... parce qu'on ne connaît pas Recalc, et que du coup les mises à
jour ne se font pas.


Merci pour ... la mise à jour.