Forum Discussion
Power Query - Table.ReplaceValue - Behavior ?
- 1 year ago
Sur les points 1 et 3
quand vous ajoutez une colonne à une table, vous ne vous demandez pas ce que veut dire le [xxxx]
exemple, si vous créez une nouvelle colonne avec les 2 derniers caractères d'une autre colonne
= Table.AddColumn(Source, "Column2", each Text.End([Column1], 2), type text)
le [Column1] désigne le texte contenu dans le champ intitulé "Column1" de votre ligne en cours
cela vous semble naturel !
vous pourriez également écrire :
= Table.AddColumn(Source, "Column2", (_) => Text.End(_[Column1], 2), type text)
ici j'ai mis un _ mais vous auriez pu mettre un x ou informer
cette syntaxe est valable
= Table.AddColumn(Source, "Column2", (informer) => Text.End(informer[Column1], 2), type text)
il est implicite que "informer" est l'enregistrement en cours (de l'étape "source")
La fonction Table.ReplaceValue est plus complexe car la fonction du 4e argument utilise les 3 arguments précédents pour elle-même. quelque soit les noms qu'on leur donne (x,y,z) ou (a,b,c) ou (informer1,informer2,informer3)
= Table.ReplaceValue(Source, Argument2, Argument3, (informer1,informer2,informer3)=>informer2, {"Column1"}ici on remplacera la column1 par le valeur du 2e argument
ce peut être du texte, un nombre, une liste... lié à la ligne en cours si on a un each...
mais également une valeur d'une autre requête
un exemple tiré par les cheveux pour bien comprendre,
let
Source = Table.FromColumns({{1..3}},{"Column1"}),
Replace = Table.ReplaceValue(Source, Source[Column1], (toto)=> Source , (a,b,c)=>a, {"Column1"})
in
Replacene changera rien à la column1, on prend la valeur du premier argument (donc la column1) et on le remet.
let
Source = Table.FromColumns({{1..3}},{"Column1"}),
Replace = Table.ReplaceValue(Source, Source[Column1], (toto)=> Source , (a,b,c)=>b, {"Column1"})
in
Replaceon n'a pas de each, on n'est donc pas dans la ligne en cours, on prendre la colonne "Column1" de la table "Source" c'est à dire la colonne elle-même (en entier !)
on aura donc une liste {1..3} dans chaque cellule.
enfin,
let
Source = Table.FromColumns({{1..3}},{"Column1"}),
Replace = Table.ReplaceValue(Source, Source[Column1], (toto)=> Source , (a,b,c)=>c, {"Column1"})
in
Replaceici la fonction renvoie c, le 3eme argument que j'ai volontairement écrit (toto)=> (toto ou _ ou each, c'est la même chose, c'est la ligne en cours
sauf que là, je ne renvoie pas un champ spécifique de la ligne avec des [ ] mais Source, donc l'étape précédente.
Dans toutes les cellules j'aurais donc la table Source avec sa seule colonne de trois valeurs, 1, 2, 3.
Quant au point 2, Power Query ne génère pas d'erreur lorsqu'il n'y a pas assez d'argument, mais les modifications ne sont pas effectuées
Si par exemple j'écris := Table.ReplaceValue(Source, each null, each null , Date.Day, {"Column1"})Date.Day est une fonction avec un seul argument, je n'ai aucune erreur, mais la fonction ne remplace rien.
= Table.ReplaceValue(Source, each null, each null , List.Accumulate, {"Column1"})pas d'erreur non plus avec List.Alternate qui demande pourtant 3 arguments. la fonction renvoie un erreur, il ne se passe rien. peut-être un bug de Power Query ?
Est-ce plus clair ?
Stéphane
This is an interesting question. It seems that you are very interested in the second example.
Before explaining this question, you should know that if a table function needs a function as a parameter, it usually passes the parameters in order, which I call implicit parameter passing. For example, the third parameter of the Table.AddColumn function needs to specify a function. During the execution of the Table.AddColumn function, it passes the table row (a record value) as a parameter to the third parameter (a function), and then calculates a result as the value of the new column.
The same is true for the Table.ReplaceValue function, which implicitly passes the value of each row of the column specified in the fifth parameter, the second parameter, and the third parameter to the fourth parameter (a function).The fourth argument (a function) computes a result based on the three provided arguments, which is then used as the new value to replace the original value.
In the second example, your result is a fixed value (newval), so it will always replace the original value in the table with newval(it corresponds to the third parameter).
Here are some examples I learned before, maybe they can help you.
Table.ReplaceValue(
#table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}),
11,
666,
Replacer.ReplaceValue,
{"A"}
)
Table.ReplaceValue(
#table({"A", "B"}, {{1, "take"}, {11, "make"}, {111, "like"}}),
"ak",
"****",
Replacer.ReplaceText,
{"B"}
)
Table.ReplaceValue(
#table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}),
888,
666,
(x, y, z) => if x = 11 then y else z,
{"A"}
)
Table.ReplaceValue(
#table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}),
null,
null,
(x, y, z) => if x = 11 then x * 100 else x / 100,
{"A"}
)
Table.ReplaceValue(
#table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}),
each [B],
666,
(x, y, z) => if y = 102 then 777 else x,
{"A"}
)
- AntrikshSharma1 year ago
Community Champion
ZhangKun Greate examples! For the last example I believe you wanted to write:
(x, y, z) => if y = 102 then z else xFor those who might find x, y, z difficult to understand at first.
Table.ReplaceValue ( #table ( { "A", "B" }, { { 1, 2 }, { 11, 11 }, { 101, 102 } } ), each [B], 666, ( CurrentValue, OldValue, NewValue ) => if OldValue = 102 then NewValue else CurrentValue, { "A" } )- ZhangKun1 year ago
Super User
This is an example from a little back ago, and I was trying to say that the second and third parameters of Table.ReplaceValue do not necessarily have to be used in the fourth parameter.