Conditions imbriquées

Bonsoir,

Après avoir cherché des heures toutes les solutions qui me venaient en tête, je m'en remets à des expertises bien plus affutées que la mienne. Je m'explique : je cherche à ce qu'un guichet soit sélectionné en fonction de la disponibilité globale et de l'heure d'arrivée. Plus concrètement : un patient qui arrive à 7h30 se présentera nécessairement au guichet 1, le seul ouvert à cette heure. En revanche, celui qui arrive à 9h30 a 3 guichets ouverts, et doit se présenter au guichet le plus rapidement libre.

La formule que je cherche à vérifier est la suivante :

=SI(E25<480;0;

SI(ET(E25>=480;E25<=510);1;

SI(ET(E25>510;E25<=540);SI(MIN(J25;K25)=J25;1;SI(MIN(J25;K25)=K25;2;

SI(ET(E25>540;E25<=600);SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;SI(MIN(J25;K25;L25)=L25;3;

SI(ET(E25>600;E25<=720);SI(MIN(J25;K25;L25;M25;N25)=J25;1;SI(MIN(J25;K25;L25;M25;N25)=K25;2;SI(MIN(J25;K25;L25;M25;N25)=L25;3;SI(MIN(J25;K25;L25;M25;N25)=M25;4;SI(MIN(J25;K25;L25;M25;N25)=N25;5;

SI(ET(E25>720;E25<=780);SI(MIN(J25;K25;L25;M25)=J25;1;SI(MIN(J25;K25;L25;M25)=K25;2;SI(MIN(J25;K25;L25;M25)=L25;3;SI(MIN(J25;K25;L25;M25)=M25;4;

SI(ET(E25>780;E25<=840);SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;SI(MIN(J25;K25;L25)=L25;3;

SI(ET(E25>840;E25<=990);SI(MIN(J25;K25;L25;M25;N25)=J25;1;SI(MIN(J25;K25;L25;M25;N25)=K25;2;SI(MIN(J25;K25;L25;M25;N25)=L25;3;SI(MIN(J25;K25;L25;M25;N25)=M25;4;SI(MIN(J25;K25;L25;M25;N25)=N25;5;

SI(ET(E25>990;E25<=1020);SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;SI(MIN(J25;K25;L25)=L25;3;

SI(ET(E25>1020;E25<=1050);SI(MIN(J25;K25)=J25;1;SI(MIN(J25;K25)=K25;2;

SI(E25>1050;0))))))))))))))))))))))))))))))))))))))

Je vous joins le fichier, espérant que l'un d'entre vous saura m'éclairer (Feuille : "test_formules_simulation_5Serv ; colonne "Choix du guichet" [G21 et suivants]). Pour l'heure, la formule me renvoie "FAUX" dès que l'heure d'arrivée est supérieure à 540 minutes ; et même en me creusant la tête, je ne comprends pas où l'erreur réside.

En vous remerciant sincèrement de votre aide, par avance,

Bien à vous,

Zabko

Bonjour,

je comprends ta logique qui est très belle, mais excel interprête différemment

le début de la correction est la suivante :

SI(E25<480;0;
SI(ET(E25>=480;E25<=510);1;
SI(ET(E25>510;E25<=540);SI(MIN(J25;K25)=J25;1;2);
SI(ET(E25>540;E25<=600);SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;3);
etc.

compare bien

SI(ET(E25>510;E25<=540);SI(MIN(J25;K25)=J25;1;2);

et

SI(ET(E25>510;E25<=540);SI(MIN(J25;K25)=J25;1;SI(MIN(J25;K25)=K25;2;

SI s'écrit : SI(condition; valeur_si_vrai; valeur_si_faux)

et non : SI(condition; si cas1 alors x, si cas2 alors y, si cas3 alors z)

La correction va être longue ... regarde du côté SI.CONDITIONS ou SI.MULTIPLE si tu es en XL2016 ou 365 car cela ne fonctionne pas chez moi. C'est une fonction que tu as parfaitement anticipée dans ta logique !

Essaie ceci ...

=SI(E25<480;0;
SI(ET(E25>=480;E25<=510);1;
SI(ET(E25>510;E25<=540);SI(MIN(J25;K25)=J25;1;2);
SI(ET(E25>540;E25<=600);SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;3));
SI(ET(E25>600;E25<=720);SI(MIN(J25;K25;L25;M25;N25)=J25;1;SI(MIN(J25;K25;L25;M25;N25)=K25;2;SI(MIN(J25;K25;L25;M25;N25)=L25;3;SI(MIN(J25;K25;L25;M25;N25)=M25;4;5))));
SI(ET(E25>720;E25<=780);SI(MIN(J25;K25;L25;M25)=J25;1;SI(MIN(J25;K25;L25;M25)=K25;2;SI(MIN(J25;K25;L25;M25)=L25;3;4)));
SI(ET(E25>780;E25<=840);SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;3));
SI(ET(E25>840;E25<=990);SI(MIN(J25;K25;L25;M25;N25)=J25;1;SI(MIN(J25;K25;L25;M25;N25)=K25;2;SI(MIN(J25;K25;L25;M25;N25)=L25;3;SI(MIN(J25;K25;L25;M25;N25)=M25;4;5))));
SI(ET(E25>990;E25<=1020);SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;3));
SI(ET(E25>1020;E25<=1050);SI(MIN(J25;K25)=J25;1;2);
0))))))))))

mais tu as d'autres fonctions SI imbriquées

[b]Conseil =

  • soit tu peux utiliser SI.CONDITIONS ou SI.MULTIPLE
  • soit tu fais une fonction personnalisée en VBA avec Select Case[/b]

Bonjour Steelson,

Merci beaucoup de ce premier retour. J'ai essayé ta correction ce matin, après en avoir décortiqué la logique et compris mon erreur. Pourtant, Excel continue d'interpréter à sa guise, et la fonction corrigée me renvoie une valeur "0".

Pour l'utilisation de SI.CONDITIONS, je ne suis malheureusement pas sur la bonne version...

Je commence en effet à croire nécessaire de passer par une fonction VBA. Je vais m'y atteler. Seulement, ce sera la première, sans maîtrise aucune : je serai volontiers preneur des grandes lignes de la fonction, pour en comprendre l'architecture.

Je m'en remets à tout altruiste désireux de faire sa B.A. du jour

Bien à vous,

Je commence en effet à croire nécessaire de passer par une fonction VBA. Je vais m'y atteler. Seulement, ce sera la première, sans maîtrise aucune : je serai volontiers preneur des grandes lignes de la fonction, pour en comprendre l'architecture.

Justement, je vais y réfléchir car ce serait un réel progrès pour ceux qui comme moi ne peuvent appliquer les nouvelles fonctions.

Du reste, ta logique est très proche. Il faudra en effet mettre si alors, si alors, etc...

Mais cela va être à la fois simple d'écriture sans doute mais complexe à concevoir pour rester simple.

Je vais le faire pendant mes temps libres dans la journée après un moment de réflexion ...

à suivre (sujet intéressant).

Je n'ai pas réussi (pour le moment) à réaliser une fonction équivalente à SI.MULTIPLE

mais, j'ai trouvé plus simple

combiner CHOISIR et EQUIV comme ci-joint

Par exemple :

SI(MIN(J25;K25;L25)=J25;1;SI(MIN(J25;K25;L25)=K25;2;SI(MIN(J25;K25;L25)=L25;3;)))

devient

CHOISIR(EQUIV(MIN(J25;K25;L25);(J25:L25);0);1;2;3)

Merci Steelson !

Je teste cela et je reviens vers toi. Par ailleurs, je ne perds pas de l'idée de voir si je parviens à concevoir une macro qui corresponde à ce que je cherche. Sous réserve que je puisse terminer avant l'âge de 74 ans, vu mon niveau en VBA :p

Edit : La formule "CHOISIR(EQUIV(" me renvoie une valeur 0 même quand cela ne devrait pas être permis.... Je continue donc mes tests.

Formulation optimisée :

=CHOISIR(
EQUIV(E25;{0;480;510;540;600;720;780;840;990;1020;1050};1);
0;
1;
CHOISIR(EQUIV(MIN(J25:K25);(J25:K25);0);1;2;3;4;5);
CHOISIR(EQUIV(MIN(J25:L25);(J25:L25);0);1;2;3;4;5);
CHOISIR(EQUIV(MIN(J25:N25);(J25:N25);0);1;2;3;4;5);
CHOISIR(EQUIV(MIN(J25:M25);(J25:M25);0);1;2;3;4;5);
CHOISIR(EQUIV(MIN(J25:L25);(J25:L25);0);1;2;3;4;5);
CHOISIR(EQUIV(MIN(J25:N25);(J25:N25);0);1;2;3;4;5);
CHOISIR(EQUIV(MIN(J25:L25);(J25:L25);0);1;2;3;4;5);
CHOISIR(EQUIV(MIN(J25:K25);(J25:K25);0);1;2;3;4;5);
"??"
)

mais je ne garantis pas ton résultat ne sachant pas vraiment ce que tu cherches ... bon courage !

Merci Steelson pour le temps que tu as consacré à m'aider, sincèrement, et pour la stimulation que tes réponses ont pu m'apporter.

Quelques explications complémentaires sur le but recherché pourraient en effet aider. Désolé de ne les avoir pas données plus avant.

En gros, je cherche à modéliser une file d'attente face à des guichets. L'objectif est d'attribuer à chaque patient se présentant le guichet qui, d'une part, est ouvert (or, je n'ai pas 5 guichets ouverts toute la journée, d'où les plages horaires différenciées) et, d'autre part, sera le plus rapidement libre (d'où la fonction Min() d'origine).

Je suis passé par le VBA et je crois que je touche au but. Ma macro fonctionne pour une case définie. Seulement, je pense qu'il faut que je l'intègre dans une boucle while, qui se répète tant que les 350 patients estimés ne sont pas arrivés. Je la poste ci-dessous, si quelqu'un peut m'aider. Dans la négative, je continue mes recherches !

Merci d'avance !

Sub ChoixGuichet()

'Variables
Dim i As Integer
    i = 24
Dim Heure_Arrivee As Integer, Affectation_patient As Integer
    Heure_Arrivee = Range("E" & i)

'Déclaration des correspondances libération/guichet
Dim Guichet1 As Integer
    Guichet1 = Range("J" & i)
Dim Guichet2 As Integer
    Guichet2 = Range("K" & i)
Dim Guichet3 As Integer
    Guichet3 = Range("L" & i)
Dim Guichet4 As Integer
    Guichet4 = Range("M" & i)
Dim Guichet5 As Integer
    Guichet5 = Range("N" & i)

'Déclarations des plages de contrôle
Dim Plage_si_Cap_2 As Range
    Set Plage_si_Cap_2 = Range("J" & i & ":K" & i)
Dim Plage_si_Cap_3 As Range
    Set Plage_si_Cap_3 = Range("J" & i & ":L" & i)
Dim Plage_si_Cap_4 As Range
    Set Plage_si_Cap_4 = Range("J" & i & ":M" & i)
Dim Plage_si_Cap_5 As Range
    Set Plage_si_Cap_5 = Range("J" & i & ":N" & i)

If Heure_Arrivee <= 480 Then
    Affectation_patient = "0"

ElseIf Heure_Arrivee > 480 And Heure_Arrivee <= 510 Then
    Affectation_patient = "1"

ElseIf Heure_Arrivee > 510 And Heure_Arrivee <= 540 Then
    If (Application.Min(Plage_si_Cap_2) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_2) = Guichet2) Then
        Affectation_patient = "2"
    End If

ElseIf Heure_Arrivee > 540 And Heure_Arrivee <= 600 Then
    If (Application.Min(Plage_si_Cap_3) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet3) Then
        Affectation_patient = "3"
    End If

ElseIf Heure_Arrivee > 600 And Heure_Arrivee <= 720 Then
    If (Application.Min(Plage_si_Cap_5) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet3) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet4) Then
        Affectation_patient = "4"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet5) Then
        Affectation_patient = "5"
    End If

ElseIf Heure_Arrivee > 720 And Heure_Arrivee <= 780 Then
    If (Application.Min(Plage_si_Cap_4) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_4) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_4) = Guichet3) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Plage_si_Cap_4) = Guichet4) Then
        Affectation_patient = "4"
    End If

ElseIf Heure_Arrivee > 780 And Heure_Arrivee <= 840 Then
    If (Application.Min(Plage_si_Cap_3) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet3) Then
        Affectation_patient = "3"
    End If

ElseIf Heure_Arrivee > 840 And Heure_Arrivee <= 990 Then
    If (Application.Min(Plage_si_Cap_5) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet3) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet4) Then
        Affectation_patient = "4"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet5) Then
        Affectation_patient = "5"
    End If

ElseIf Heure_Arrivee > 990 And Heure_Arrivee <= 1020 Then
    If (Application.Min(Plage_si_Cap_3) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet3) Then
        Affectation_patient = "3"
    End If

ElseIf Heure_Arrivee > 1020 And Heure_Arrivee <= 1050 Then
    If (Application.Min(Plage_si_Cap_2) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_2) = Guichet2) Then
        Affectation_patient = "2"
    End If

ElseIf Heure_Arrivee > 1050 Then
    Affectation_patient = "0"

Else
    Affectation_patient = "00000"

End If

'Affectation du patient
    Range("G" & i) = Affectation_patient

End Sub

Ton écriture pourrait s'alléger avec Select Case

mais vu ton investissement et là où tu en es, poursuis comme cela !

Merci Steelson,

J'imagine bien que ce code pourrait être bien plus léger. Mais ne comprenant pas encore bien le fonctionnement de "Select Case", j'ai préféré garder la logique première de ma formule initiale.

Donc j'en conviens, c'est un sacré bazar, mais étonnamment je trouve la formule presque claire

N'empêche qu'il demeure un problème : j'ai ajouté la boucle que je cherchais à inscrire. Quand j'exécute la macro, le tableur "mouline" avant de m'inscrire dans une fenêtre "Erreur 1004 : impossible de modifier une partie d'une table de données".

Le débogueur VBA se lance et me surligne la fin de mes instructions (juste avant Wend) , comme ci-dessous :

Sub ChoixGuichet()

'Variables
Dim i As Integer
    i = 23
Dim Heure_Arrivee As Integer, Affectation_patient As Integer
    Heure_Arrivee = Range("E" & i)

'Variable pour boucle
Dim Num_patient As Integer
    Num_patient = Range("B" & i)

'Déclaration des correspondances libération/guichet
Dim Guichet1 As Integer
    Guichet1 = Range("J" & i)
Dim Guichet2 As Integer
    Guichet2 = Range("K" & i)
Dim Guichet3 As Integer
    Guichet3 = Range("L" & i)
Dim Guichet4 As Integer
    Guichet4 = Range("M" & i)
Dim Guichet5 As Integer
    Guichet5 = Range("N" & i)

'Déclarations des plages de contrôle
Dim Plage_si_Cap_2 As Range
    Set Plage_si_Cap_2 = Range("J" & i & ":K" & i)
Dim Plage_si_Cap_3 As Range
    Set Plage_si_Cap_3 = Range("J" & i & ":L" & i)
Dim Plage_si_Cap_4 As Range
    Set Plage_si_Cap_4 = Range("J" & i & ":M" & i)
Dim Plage_si_Cap_5 As Range
    Set Plage_si_Cap_5 = Range("J" & i & ":N" & i)

'Boucle
While Num_patient <= 350
    i = i + 1

If Heure_Arrivee <= 480 Then
    Affectation_patient = "0"

ElseIf Heure_Arrivee > 480 And Heure_Arrivee <= 510 Then
    Affectation_patient = "1"

ElseIf Heure_Arrivee > 510 And Heure_Arrivee <= 540 Then
    If (Application.Min(Plage_si_Cap_2) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_2) = Guichet2) Then
        Affectation_patient = "2"
    End If

ElseIf Heure_Arrivee > 540 And Heure_Arrivee <= 600 Then
    If (Application.Min(Plage_si_Cap_3) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet3) Then
        Affectation_patient = "3"
    End If

ElseIf Heure_Arrivee > 600 And Heure_Arrivee <= 720 Then
    If (Application.Min(Plage_si_Cap_5) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet3) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet4) Then
        Affectation_patient = "4"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet5) Then
        Affectation_patient = "5"
    End If

ElseIf Heure_Arrivee > 720 And Heure_Arrivee <= 780 Then
    If (Application.Min(Plage_si_Cap_4) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_4) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_4) = Guichet3) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Plage_si_Cap_4) = Guichet4) Then
        Affectation_patient = "4"
    End If

ElseIf Heure_Arrivee > 780 And Heure_Arrivee <= 840 Then
    If (Application.Min(Plage_si_Cap_3) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet3) Then
        Affectation_patient = "3"
    End If

ElseIf Heure_Arrivee > 840 And Heure_Arrivee <= 990 Then
    If (Application.Min(Plage_si_Cap_5) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet3) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet4) Then
        Affectation_patient = "4"
    ElseIf (Application.Min(Plage_si_Cap_5) = Guichet5) Then
        Affectation_patient = "5"
    End If

ElseIf Heure_Arrivee > 990 And Heure_Arrivee <= 1020 Then
    If (Application.Min(Plage_si_Cap_3) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet2) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Plage_si_Cap_3) = Guichet3) Then
        Affectation_patient = "3"
    End If

ElseIf Heure_Arrivee > 1020 And Heure_Arrivee <= 1050 Then
    If (Application.Min(Plage_si_Cap_2) = Guichet1) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Plage_si_Cap_2) = Guichet2) Then
        Affectation_patient = "2"
    End If

ElseIf Heure_Arrivee > 1050 Then
    Affectation_patient = "0"

Else
    Affectation_patient = "00000"

End If

'Affectation du patient
    Range("G" & i) = Affectation_patient 'C'est ici que ça coince visiblement...

'Fin boucle
Wend

End Sub

Je me demande si la boucle est bien placée : la macro fonctionnait bien sans, et buggue avec.

Quelle est mon erreur ?

ajoute une ligne 351 ou fais

While Num_patient < 350

Merci ! Plus de bug de ce côté.

En revanche, la macro m'inscrit 0 dans toutes les cases de ma colonne G... Je commence à croire que c'est son architecture globale qui pose problème...

Je vous rejoins le fichier, au cas où vous verriez quelque chose qui m'échappe totalement...

Je me demande si le Application.Min tel qu'il est inscrit dans ma formule renvoie véritablement à la bonne valeur...

Par avance, un grand merci !

Hello,

dans ta macro,

Guichet1 = Range("J" & i)

est figé avec i=23 au début du code et ne se mettra pas jour ...

il faut l'intégrer dans la boucle comme les autres variables aussi

Sub ChoixGuichet()

For i = 23 To 371

If Range("E" & i) <= 480 Then
    Affectation_patient = "0"

ElseIf Range("E" & i) > 480 And Range("E" & i) <= 510 Then
    Affectation_patient = "1"

ElseIf Range("E" & i) > 510 And Range("E" & i) <= 540 Then
    If (Application.Min(Range("J" & i & ":K" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":K" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    End If

ElseIf Range("E" & i) > 540 And Range("E" & i) <= 600 Then
    If (Application.Min(Range("J" & i & ":L" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":L" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Range("J" & i & ":L" & i)) = Range("L" & i)) Then
        Affectation_patient = "3"
    End If

ElseIf Range("E" & i) > 600 And Range("E" & i) <= 720 Then
    If (Application.Min(Range("J" & i & ":N" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("L" & i)) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("M" & i)) Then
        Affectation_patient = "4"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("N" & i)) Then
        Affectation_patient = "5"
    End If

ElseIf Range("E" & i) > 720 And Range("E" & i) <= 780 Then
    If (Application.Min(Range("J" & i & ":M" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":M" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Range("J" & i & ":M" & i)) = Range("L" & i)) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Range("J" & i & ":M" & i)) = Range("M" & i)) Then
        Affectation_patient = "4"
    End If

ElseIf Range("E" & i) > 780 And Range("E" & i) <= 840 Then
    If (Application.Min(Range("J" & i & ":L" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":L" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Range("J" & i & ":L" & i)) = Range("L" & i)) Then
        Affectation_patient = "3"
    End If

ElseIf Range("E" & i) > 840 And Range("E" & i) <= 990 Then
    If (Application.Min(Range("J" & i & ":N" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("L" & i)) Then
        Affectation_patient = "3"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("M" & i)) Then
        Affectation_patient = "4"
    ElseIf (Application.Min(Range("J" & i & ":N" & i)) = Range("N" & i)) Then
        Affectation_patient = "5"
    End If

ElseIf Range("E" & i) > 990 And Range("E" & i) <= 1020 Then
    If (Application.Min(Range("J" & i & ":L" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":L" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    ElseIf (Application.Min(Range("J" & i & ":L" & i)) = Range("L" & i)) Then
        Affectation_patient = "3"
    End If

ElseIf Range("E" & i) > 1020 And Range("E" & i) <= 1050 Then
    If (Application.Min(Range("J" & i & ":K" & i)) = Range("J" & i)) Then
        Affectation_patient = "1"
    ElseIf (Application.Min(Range("J" & i & ":K" & i)) = Range("K" & i)) Then
        Affectation_patient = "2"
    End If

ElseIf Range("E" & i) > 1050 Then
    Affectation_patient = "|000|"

Else
    Affectation_patient = "|00000|"

End If

'Affectation du guichet au patient
    Range("G" & i) = Affectation_patient

Next

End Sub

Waouh mais évidemment ! C'était tellement gros que je ne le voyais pas...

Merci infiniment pour cette aide ! Ça fonctionne parfaitement !

Me reste à faire de même avec l'utilisation de mes "taux de services" en colonne C, puisque la formule Excel, si elle ne renvoie pas d'erreur, renvoie des valeurs non cohérentes : charge à moi d'appliquer la logique de cette macro !!

Steelson, je te dois une fière chandelle ! Merci !

Merci pour ce retour

et clique sur un petit cœur

J'avoue m'être pris au jeu car le sujet est super intéressant

J'ai fait moi-même quelques simulations dites de Monte-Carlo

Ta dernière logique est tout à fait intéressante aussi, certains langage (javascript) fonctionne comme tu le faisais, à savoir une déclaration préalable qui ensuite s'incrémente. Excel le fait aussi dans les définition dynamique de zones. Mais pas VBA !

Me revoilà,

Bien que mon sujet initial soit résolu, je préfère, pour la continuité de la compréhension, ne pas ouvrir de nouveau sujet puisque celui-ci est lié.

Ce que je cherche à faire, c'est de demander à ce que si l'heure d'arrivée précédente est comprise dans une plage horaire, l'intervalle de temps entre l'arrivée précédente et la suivante dépendra d'une fréquence d'arrivée spécifique.

Sous Excel, la formule était simple :

SI(E22<480 ; -LN(1-ALEA())/C12)

La formule fonctionne parfaitement, mais comme pour le choix du guichet, les imbrications de conditions la rendent inopérante.

Je compte donc passer par une macro (encore !), et je souhaiterais avoir un avis éclairé sur la formule suivante :

If Range("E" & i - 1) <= 480 Then
    Frequence_arrivee = -Log(1 - Rnd()) / Range.Value("C12")

Cela semble-t-il correspondre à la formule Excel ?

If Range("E" & (i - 1)).value <= 480 Then  Frequence_arrivee = -Log(1 - Rnd) / Range("C12").Value

sur une seule ligne (évite le end if)

range("C12").value

attention à la première valeur

je pense qu'il faut ajouter une ligne randomize

https://www.excel-pratique.com/fr/astuces_vba/generer_nombres_aleatoires.php

rnd sans parenthèse

Sub aleatoire()

For i = 1 To 50
    Randomize
    'Nombre aléatoire entier entre 1 et 50 :
    nombre_aleatoire = Int(50 * Rnd) + 1
    Debug.Print nombre_aleatoire
Next

End Sub

après je me pose des questions sur log népérien ou décimal ==> edit, c'est ok

Merci Steelson pour tes premières corrections.

En poursuivant ta logique, j'ai abouti à la macro suivante (Frequence_arrivee) :

Sub Alea_frequence_arrivee()

Dim Alea As Currency
    Alea = -Log(1 - Rnd())

For i = 23 To 372

If Range("E" & i - 1).Value < 480 Then
    Range("C" & i).Value = Alea / Range("C13").Value

ElseIf Range("E" & i - 1).Value >= 480 And Range("E" & i - 1).Value < 540 Then
    Range("C" & i).Value = Alea / Range("D13").Value

ElseIf Range("E" & -1).Value >= 540 And Range("E" & -1).Value < 600 Then
    Range("C" & i).Value = Alea / Range("E13").Value

ElseIf Range("E" & -1).Value >= 600 And Range("E" & -1).Value < 660 Then
    Range("C" & i).Value = Alea / Range("F13").Value

ElseIf Range("E" & -1).Value >= 660 And Range("E" & -1).Value < 720 Then
    Range("C" & i).Value = Alea / Range("G13").Value

ElseIf Range("E" & -1).Value >= 720 And Range("E" & -1).Value < 780 Then
    Range("C" & i).Value = Alea / Range("H13").Value

ElseIf Range("E" & -1).Value >= 780 And Range("E" & -1).Value < 840 Then
    Range("C" & i).Value = Alea / Range("I13").Value

ElseIf Range("E" & -1).Value >= 840 And Range("E" & -1).Value < 900 Then
    Range("C" & i).Value = Alea / Range("J13").Value

ElseIf Range("E" & -1).Value >= 900 And Range("E" & -1).Value < 960 Then
    Range("C" & i).Value = Alea / Range("K13").Value

ElseIf Range("E" & -1).Value >= 1020 And Range("E" & -1).Value < 1020 Then
    Range("C" & i).Value = Alea / Range("L13").Value

ElseIf Range("E" & -1).Value >= 1020 And Range("E" & -1).Value < 1080 Then
    Range("C" & i).Value = Alea / Range("M13").Value

ElseIf Range("E" & -1).Value >= 1080 And Range("E" & -1).Value < 1140 Then
    Range("C" & i).Value = Alea / Range("N13").Value

ElseIf Range("E" & -1).Value >= 1140 Then
    Range("C" & i).Value = Alea / Range("O13").Value

Else
    Range("C" & i).Value = "|000|"

End If

Next

End Sub

Mais en la lançant, j'obtiens une MsgBox "Erreur d'exécution '1004' : La méthode Range de l'objet _Global a échoué"...

Et j'avoue ne pas comprendre pourquoi...

Saurais-tu (sauriez-vous, si une autre bonne âme venait à s'échouer dans ces lignes) où je me suis trompé ?

(Je re-re-joins à nouveau le fichier, histoire que vous puissiez constater ce que je cherche à obtenir en colonne C (Intervalle Temps), à ce jour obtenu par une formule Excel (mais qui, comme je disais, doit s'arrêter en route puisque les valeurs renvoyées ne sont pas cohérentes aux taux de service (ligne 13).)

Rechercher des sujets similaires à "conditions imbriquees"