Liste déroulante ou une case blanche sous condition
Bonjour à tous,
Merci à vous de prendre le temps de lire ma demande.
J'ai créé un fichier sous Excel 2010 devant me servir à prescrire des médicaments à un patient (fichier de démo en annexe).
Les cases A4 à A13 disposent d'une liste déroulante reprenant la liste des médicaments possibles (onglet "médicaments").
Les cases C4 à Z13 représentent une grille horaire journalière. Dans ces cases, je souhaiterais que, si un médicament (peu importe lequel) est défini en début de ligne (colonne A), les cellules C à Z de la ligne correspondante permettent l'affichage d'une autre liste déroulante reprenant les codes de prescription de l'onglet "codes", servant à définir,par exemple, l'heure à laquelle un traitement doit être administré (code X) ou arrêté (code //). L'affichage final devrait en pratique ressembler à la ligne 9 du fichier de démo.
Vous trouverez mon idée de départ illustrée en ligne 12 : j'ai indiqué la formule =SI($A$12="";"";Codes!$A$2:$A$6) pour définir la source de la liste déroulante à afficher pour chacune des cases de la grille horaire. Ca marche pas mal sauf que, si je choisis un médicament et que je place des codes à certaines heures puis que je choisis de supprimer le médicament en question, les codes restent affichés. Or je voudrais que les codes disparaissent et que toute la ligne redevienne blanche si aucun médicament n'est plus affiché en tête de ligne.
Merci pour votre aide..
Bonsoir,
j'ai modifié votre fichier en créant un tableau à double entrée pour les médicaments et les codes d'utilisation en fonction des plages horaires, tout ceci sur la feuille "BD".
En suite sur le tableau de suivi de prescription, une formule de recherche verticale dans le tableau du médicament sélectionné permet de trouver son code d'utilisation en fonction de la plage horaire :
=recherchev(nom_du_médicament;tableau;colonne_voulu;faux)
Je vous joins le fichier modifier... Il y aurait des amélioration à faire, comme avoir une plage dynamique de la liste des médicaments en cas d'ajout de nouveau, une plage de tableau dynamique afin qu'il s'adapte au nombre de médicaments.
De même pour le tableau récapitulatif de prescription.
Mais il faut bien que vous cherchiez un peu, non ?
Mais il est vrai que ce n'est pas ce que vous avez demandez !
Alors pour cela il y a le deuxième fichier...
@ bientôt
Loureed
Bonsoir,
Merci beaucoup pour votre réponse rapide.
Effectivement, le 1er fichier ne me semble pas utilisable en pratique. Ce document sert à générer une feuille personnalisée pour différents patients hospitalisés dans un service hospitalier. Le document est imprimé pour que l'infirmière sache la liste des traitements à donner et l'heure d'administration. La liste des médicaments envisageable est beaucoup plus longue que dans l'exemple (plus de 100). Chaque médicament doit pouvoir être administré à n'importe quelle heure de la journée et non à des heures "prédéfinies par médicament" comme indiqué dans le tableau à double entrée. Ainsi les heures d'administration du traitement B pour le patient Jacques peuvent être différentes des heures d'administration de ce même traitement B pour le patient Yves.
Votre second fichier se rapproche vraiment du but. J'ai vu que vous utilisiez une dénomination particulière (_M et codes) pour les plages de cellules définissant les listes déroulantes. Il manquait la fonction pour que la liste déroulant des codes ne soit sélectionnable que sur les lignes pour lesquelles un médicament est présent en colonne A. J'ai donc modifié votre ligne 5 (seconde ligne de médicaments) en entrant =SI($A$5="";"";codes) à la source plutôt que "codes". Ca marche nickel (cf ligne 5 du fichier annexe). Malheureusement, lorsque je repars moi-même d'un nouveau document, je ne parviens pas à obtenir que les codes s'effacent dans la grille horaire lorsque je supprime les médicament en colonne A. A quoi cela tient-il dans vos formules ?
D'avance merci.
Bonjour,
Cela tien au fait que le fichier est en .xlsM : M comme macro
si vous faites un clic droit sur l'onglet "prescription" et que vous sélectionnez "afficher le code"
vous verrez le bout de code de surveillance événementielle de cette feuille :
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("A:A")) Is Nothing And Target.Row > 3 Then
If Target.Value = "" Then
Range(Cells(Target.Row, 2), Cells(Target.Row, 13)).ClearContents
End If
End If
End Subelle surveille tout changement (Worksheet_Change) de valeur sur la feuille sur la colonne A (Range("A:A")) :
explication
Target : adresse de la cellule active
A:A : toute la colonne A
Target.Row : numéro de la ligne active
Target.value : valeur de la cellule active
Target.count : nombre de cellule sélectionnée
Exit sub : on quitte la procédure
Range(Cells(Target.Row, 2), Cells(Target.Row, 13)).ClearContents : on efface les données de la ligne de la cellule active, de la colonne 2 à la colonne 13
If Target.Value = "" Then : l'effacement se produit que si le changement dans la colonne A abouti à une valeur égale à rien ("") donc pas de médicament...
Le seul soucis c'est que si vous changer de médicament... les valeurs précédemment écrites reste... il faudrait travailler sur ce problème et en attendant passez par une valeur nulle pour effacer les données.
Avec un peu de temps...
Je verrais ce soir à moins qu'une personne vous réponde d'ici là
@ bientôt
Loureed
Re Bonjour,
Voici donc une ultime version.
Cette version met en place la surveillance événementielle de changement de sélection, ainsi on met en mémoire la valeur de la cellule sélectionnée.
Si cette valeur de cellule change pour être effacée ou modifiée alors on efface les codes de la ligne de la cellule sélectionnée. Ce la ne marche que pour les cellules de la colonne A à partir de la ligne 3.
Sur la feuille prescription, vous sélectionnez un médicament dans la liste déroulante, et en face des heures vous pouvez sélectionner les codes qui se rapporte uniquement à ce médicament.
Pour ajouter une nouvelle ligne au tableau, vous pouvez vous mettre sur la dernière cellule en bas à droite et appuyer sur la touche , une nouvelle ligne se crée et elle reprend toutes les conditions de celle du dessus.
Sur la feuille BD, c'est la base de données : il vous suffit en colonne A de rajouter / modifier les noms des médicaments pour que ce soit pris en compte dans le menu déroulant de la feuille Prescription. Sur la droite en face des noms de médicaments, il vous suffit de mettre les codes qui se rapporte à ce médicament. c'est cette liste qui apparaît dans les cellule horaire de la feuille prescription et là encore c'est le seul fait de rajouter qui fait que c'est pris en compte automatiquement. Dans les deux cas il ne faut pas de cellule vide.
@ bientôt
Loureed
Bonsoir,
Merci énormément pour tout ce travail.
Je progresse dans l'élaboration de la feuille tout en apprenant beaucoup !
J'ai recopié la macro dans ma feuille originale et j'ai tenté de modifier les paramètres pour que tout fonctionne mais quelque chose coince. Je vous envoie cette fois-ci le fichier de prescription original (et non un fichier servant à illustrer mes souhaits).
La feuille est plus complexe mais on y retrouve les éléments dont nous discutons à partir de la cellule C40.
Différents traitements peuvent être prescrits,faisant appel à des listes différentes selon la voie d'administration du produit (IC continue,discontinue, per os,...).
Si aucun médicament n'est choisi, pas possible de placer un code sur la grille horaire.
Si un médicament est choisi, on a le choix entre 3 codes (ce sont toujours les mêmes codes, ils ne varient pas en fonction du médicament mais merci d'y avoir pensé,ça pourrait arriver à l'avenir).
J'ai effectué quelques modifications à la macro pour tenter de l'adapter mais je dois m'être planté quelque part car, lorsque je veux prescrire un traitement, il me marque "erreur d'exécution '1004' Impossible de modifier une cellule fusionnée
En rouge les paramètres modifiés et en bleu les raisons qui m'ont poussé à les modifier (de façon intuitive) :
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 9 Then Exit Sub ' comme ma case de prescription de médicament est une fusion de 9 cellules, j'ai pensé qu'il fallait peut-être spécifier 9 à Target.Count (cf message d'erreur ?)
Valeur_cellule = Target.Value ' on met en mémoire la valeur de la cellule sélectionnée
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 9 Then Exit Sub ' idem cellule fusionnées ?
If Not Intersect(Target, Range("C:C")) Is Nothing And Target.Row > 39 Then
' traduction : si cellule changée est dans colonne C et la ligne supérieur à 39 donc on est dans
' la liste des médicaments
If Target.Value <> Valeur_cellule Then
' traduction : si nouvelle valeur de la cellule est différente de la valeur d'origine
' alors on efface les codes de prescription de la ligne concernée
Range(Cells(Target.Row, 30), Cells(Target.Row, 53)).ClearContents
' avec ce système la ligne de code s'efface si il y a changement de médicament ou suppression
je ne comprend pas bien les valeurs à renseigner : faut-il spécifier les lignes concernées (row) ou les colonnes ?
End If
End If
End Sub
J'espère que le problème ne vient pas de l'utilisation de cellules fusionnées car il me serait difficile de modifier l'apparence de la feuille, que nous utilisons depuis longtemps et à laquelle l'équipe infirmière est habituée.
En espérant pouvoir compter sur vos pouvoirs magiques pour trouver la solution finale...
D'avance merci
Voici le fichier
Bonsoir,
Il est vrai que je vous aie répondu en deux fois mais ceci n'est pas nécessaire !
Stop pour la plaisanterie et revenons à non moutons !
Le Target est la valeur de l'adresse de la cellule changée (ou sélectionnée).
Dans votre cas l'adresse de la première ligne de médicament est la 40
Target est donc égal à : C40:K40
Hors nous faisons un test "d'intersection" entre Target (C40:K40) avec la colonne C ! forcément il y a une erreur !
Solution : testons non pas la colonne "C:C" mais "C:K" !
et voilà !
Réponse à la deuxième partie :
Range = je sélectionne la cellule
Range("D4") = je sélectionne la cellule D4
Cells = je travaille sur la cellule (sans la sélectionnée)
Cells(4,4) = je travail sur la cellule D4 = Cells(ligne, colonne) donc quatrième ligne et quatrième colonne
Donc une petite erreur dans votre interprétation, vos colonnes de créneau horaire vont de la colonne AG à BD
c'est à dire AG = 26+7=33 et BD = 26+26+4 = 56
Et un point positif
par exemple adresse A1:C2
Target.count = 6
Target.Rows = 2 ' avec un S
Target.columns = 3 ' avec un S
Target.row = 1 ' sans S
Target.column = 1 ' sans S
Les deux dernière info donne la case de "référence" de l'adresse Target qui se trouve toujours en haut à gauche de la sélection quelque soit le sens de sélection de la plage de cellule !
Voilà
@ bientôt
Loureed
Nota : fichier complexe !!!
Génial,
Voici donc la macro corrigée :
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 9 Then Exit Sub ' si plusieurs plusieurs cellules on quitte la procédure
Valeur_cellule = Target.Value ' on met en mémoire la valeur de la cellule sélectionnée
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 9 Then Exit Sub ' si plusieurs plusieurs cellules on quitte la procédure
If Not Intersect(Target, Range("C:K")) Is Nothing And Target.Row > 39 Then
' traduction : si cellule changée est dans colonne C et la ligne supérieur à 39 donc on est dans
' la liste des médicaments
If Target.Value <> Valeur_cellule Then
' traduction : si nouvelle valeur de la cellule est différente de la valeur d'origine
' alors on efface les codes de prescription de la ligne concernée
Range(Cells(Target.Row, 33), Cells(Target.Row, 56)).ClearContents
' avec ce système la ligne de code s'efface si il y a changement de médicament ou suppression
End If
End If
End Sub
Avec ça, les codes de la grille horaire disparaissent désormais lorsque je modifie le médicament pour un autre.
Par contre, si je supprime le médicament (touche "delete"), j'ai un nouveau message d'erreur :
"Erreur d'exécution 13
Incompatibilité de type"
Si j'ouvre le débogueur, il me surligne la ligne "If Target.Value <> Valeur_cellule Then"
Y a-t-il un dernier point à modifier ?
Oupss il y a eu un bug...
ma réponse précédente, un vrai roman... perdu...
Celle-ci plus courte
fichier joint, merci
@ bientôt
Loureed
Nota : important vérifiez de bien copier le module qui permet d'initialiser la variable Valeur_cellule en Public !
Tout fonctionne parfaitement.
Je vous dois une fière chandelle !
Mille fois merci pour le temps consacré à résoudre mon problème.
Bon dimanche !
Merci et bon dimanche à vous également
LouReeD