POWERQUERY :: CaseOf ou SelectCase ou Switch - Variante du CaseOf et application étendue

oguruma

XLDnaute Occasionnel
Bonjour,
dans ce post une variante du SelectCase ou de la dernière fonction présentée fnListPositionOfV20 décrite dans ce post https://excel-downloads.com/threads...un-element-dans-une-sous-liste-v2-0.20083542/

Pour varier les plaisirs je l'ai nommé fnCaseOf. C'est aussi une manière simplifiée de rechercher un élément dans liste de sous-listes.

Voici le source :
PowerQuery:
let fnCaseOf =
    (
      pList as list,
      pCaseElem as any,
      optional pIndexReturn as number
    ) as any =>

    let
        IndexReturn=if pIndexReturn is null then 1 else pIndexReturn,
        ListSelect=List.Select(pList, (elem) => elem{0}=pCaseElem),         
        Result = if List.IsEmpty(ListSelect) then "#OUT OF RANGE" else List.First(ListSelect){IndexReturn}
    in
        Result
in 
  fnCaseOf

La recherche de l'élément dans les sous-listes se fait via
PowerQuery:
List.Select(pList, (elem) => elem{0}=pCaseElem),

et enfin on récupère la valeur via
PowerQuery:
List.First(ListSelect){IndexReturn}

Utilisation étendue
Via cette fonction fnCaseOf tout comme fnListPositionOfV20 ou fnListPositionOfV10 (voir le lien en introduction) on peut en fait simuler un SELECT CASE en VBA et faire appel à une fonction interne ou externe, l'exécution d'une requête, bref appeler n'importe quel objet PowerQuery présentant du code M.

Cela nous évite d'écrire des {if then else} imbriqués comme on a tendance à le faire trop souvent et cela m'arrive encore.

Présentation de l'environnement PowerQuery
1719994117110.png


Exemple - 1

PowerQuery:
let
   List={{1,Sub10}, {2,Sub20}, {3,Sub30}},
   R= fnCaseOf(List,3)
in
   R

Au retour de la recherche la requête Sub30 est exécutée
1719994229300.png


Code de cette requête pour l'exemple
PowerQuery:
let
    Source = "EXEC REQ SUB30"
in
    Source

Exemple - 2
PowerQuery:
let

   FoncA = () =>
         let 
            r="Excec FoncA()"
         in
            r,

   FoncB = () =>
         let 
            r="Excec FoncB()"
         in
            r,

   FoncC = (param as text) =>
         let 
            r="Excec FoncC() " & param
         in
            r,

   ListCaseOf={
         {1,FoncA()},
         {2,FoncB()},
         {3,FoncC("ParamFoncC")}
         },

   R = fnCaseOf(ListCaseOf,1)     

in
   R

Ici nous faisons appel à des fonctions internes dans le code de la requête. La descriptions des fonctions à appeler en fonction de la valeur cherchée se trouve ici
PowerQuery:
   ListCaseOf={

         {1,FoncA()},

         {2,FoncB()},

         {3,FoncC("ParamFoncC")}

         },

puis la sélection de la fonction à lancer selon la valeur cherchée est ici : R = fnCaseOf(ListCaseOf,1) qui correspond à cet élément {1,FoncA()}.
Notez la syntaxe {1,FoncA()} ; les () symbolisent une fonction.
Nous aurions pu nous passer des () mais dans ce cas il aurait fallu procéder comme suit : R = fnCaseOf(ListCaseOf,1)() ==> l'ajout des () en fin de ligne. personnellement je préfère ma 1ère syntaxe qui me semble plus parlante.
Les fonctions appelées présentent là une seule de code mais elles peuvent bien entendu en comporter plusieurs. Ce sont les gros avantages du bloc d'instructions let...in.

Exemple - 3
Cet exemple est quasiment identique au précédent. On appelle ici des fonctions externes au code M de la requête.
PowerQuery:
let

   ListCaseOf={
         {1,fnMsg("appel Msg1")},
         {2,fnMsg("appel Msg2")},
         {3,fnMsg("appel Msg3")}
         },

  
   R = fnListPositionOfV10(ListCaseOf,2)   

in
   R

fnMSG
PowerQuery:
let fnMsg = (pText as text) =>
    let
        Msg=pText
    in 
        Msg
in
    fnMsg

Résultat :
1719995059861.png
 

Pièces jointes

  • CASE_OF_v0.006.xlsx
    38.8 KB · Affichages: 2

Discussions similaires

Statistiques des forums

Discussions
313 866
Messages
2 103 082
Membres
108 521
dernier inscrit
manouba