Power Query column based on conditionals - if-statement

Hey guys new to Power BI here and I am having some trouble creating a column based on conditionals in Power Query.
I am trying to do something like if the previous letter was A,B,or C and the current letter is E,F,or G mark True, else False.
My code looks like this so far:
Custom Column =
IF List.Contains({“A”, “B”,”C”}), [PrevLetter]
AND list.Contains({“E”, “F”, ”G”}) , [Letters]
THEN “TRUE”
ELSE “FALSE”
Output would be so something like:
PrevLetter
Letter
CustomColumn
A
F
True
X
M
False
B
E
True
C
F
True
Any help is truly appreciated!

The answer depends on if you are looking for a letter within a word, or if that letter represents the entire text, but for your example, one answer could be
= if Text.PositionOfAny([PrevLetter], {"A", "B","C"})+Text.PositionOfAny([Letter], {"E", "F","G"})=0 then true else false
or if you want to plan around nulls
= try if Text.PositionOfAny([PrevLetter], {"A", "B","C"})+Text.PositionOfAny([Letter], {"E", "F","G"})=0 then true else false otherwise false
or
= Table.AddColumn(Source, "Custom", each if List.ContainsAny({[PrevLetter]},{"A","B","C"}) and List.ContainsAny({[Letter]},{"D","E","F"}) then true else false )

Related

List.contains not working with a column as second argument in Power query M

Gives F for everything as far as I can see when there are common values in columns A and B
each if List.Contains(List.RemoveNulls( { [A] } ),[B]) = true then "T" else "F"
Thanks for the help :)
In powerquery, to check if each row's value in column a matches column b in any row
add column .. custom column.. with formula
= if List.Contains(PriorStepNameHere[b],[a]) then "T" else "F"
Is that what you are looking for?

EXPAND MULTIPLE COLUMNS POWER BI

I´ve been struggling with this:
My table shows 3 records but when expanding there are like 100 columns. I used this code:
#"Expanded Data" = Table.ExpandTableColumn(#"Source", "Document", List.Union(List.Transform(#"Source"[Document]), each Table.ColumnNames(_))),
but it's not working. How can I expand simultaneously all columns? Also, inside those columns there are even more, for example I expand the first time end then those new columns have more records inside.
What could I do? Thanks in advance!
Try this ExpandAllRecords function - it recursively expands every Record-type column:
https://gist.github.com/Mike-Honey/0a252edf66c3c486b69b
This should work for Records Columns.
let
ExpandIt = (TableToExpand as table, optional ColumnName as text) =>
let
ListAllColumns = Table.ColumnNames(TableToExpand),
ColumnsTotal = Table.ColumnCount(TableToExpand),
CurrentColumnIndex = if (ColumnName = null) then 0 else List.PositionOf(ListAllColumns, ColumnName),
CurrentColumnName = ListAllColumns{CurrentColumnIndex},
CurrentColumnContent = Table.Column(TableToExpand, CurrentColumnName),
IsExpandable = if List.IsEmpty(List.Distinct(List.Select(CurrentColumnContent, each _ is record))) then false else true,
FieldsToExpand = if IsExpandable then Record.FieldNames(List.First(List.Select(CurrentColumnContent, each _ is record))) else {},
ColumnNewNames = List.Transform(FieldsToExpand, each CurrentColumnName &"."& _),
ExpandedTable = if IsExpandable then Table.ExpandRecordColumn(TableToExpand, CurrentColumnName, FieldsToExpand, ColumnNewNames) else TableToExpand,
NextColumnIndex = CurrentColumnIndex+1,
NextColumnName = ListAllColumns{NextColumnIndex},
OutputTable = if NextColumnIndex > ColumnsTotal-1 then ExpandedTable else #fx_ExpandIt(ExpandedTable, NextColumnName)
in
OutputTable
in
ExpandIt
This basically takes Table to Transform as the main argument,and then one by one checks if the Column Record is expandable (if column has "records" in it, it will expand it, otherwise move to next column and checks it again).
Then it returns the Output table once everything is expanded.
This function is calling the function from inside for each iteration.

DAX: How do I write an IF statement to return a calculation for multiple (specific) values selected?

This is driving me nuts. Let's say we want to use a slicer which has two distinct values to choose from a dimension. There is A and B.
Let us also say that my Fact table is connected to this dimension, however it has the same dimension with more options.
My slicer now has A, B and (Blank). No biggie.
Let's now say I want to list out all of the possible calculation outcomes by selecting the slicer in a DAX formula, but in my visual I need all those outcomes to be listed in an IF() branched formula:
I can list out A:
IF(MAX(SlicerDim[Column]) = "A", CALCULATE([Calculation], SlicerDim[Column] = "A")
I can list out B:
IF(MAX(SlicerDim[Column]) = "A", CALCULATE([Calculation], SlicerDim[Column] = "A")
I can list out the (Blank) calculation too:
CALCULATE([Calculation], SlicerDim[Column] = Blank())
And I've managed to get a calculation out of it even when all of the slicer elements are on or off, using:
NOT(ISFILTERED(SlicerDim[Column])), CALCULATE([Calculation], SlicerDim[Column] = "A" || SlicerDim[Column] = "B")
Notice I need this IF() branch to actually return a calculation using A & B values, so now I have returns for when A or B or (Blank) or All or None are selected; BUT NOT when multiple values of A & B are selected!
How do I write out this IF() branch for it to return the same thing, but when both A & B are selected? Since there are only two real options in the slicer - I managed to use MIN() and MAX() get it to work by using their names or Index numbers.
IF((MIN(SlicerDim[Column]) = "A" && MAX(SlicerDim[Column]) = "B") || NOT(ISFILTERED(Paslauga[Paslauga])), CALCULATE([Calculation], SlicerDim[Column] = "A" || SlicerDim[Column] = "B")
BUT - I want a more understandable/robust/reusable formula, so that I could list out many selectable values from the slicer and have it return a calculation for specifically selected slicer values.
Please, help.
I've been searching high and low and there seems to not be an easy way to fix this albeit scraping the IF route and just using a damn slicer for this type of dilemma.
TL;DR:
How do I write an IF() branch calculation using DAX to get an outcome when All/None or non-blank or Specific slicer values are selected?
My best effort:
I am looking to improve the first IF() branch to not have to use MIN/MAX, because I would like to be able to reuse this type of formula if there were more than two real options in the slicer:
IF_branch =
IF((MIN(SlicerDim[Column]) = "A" && MAX(SlicerDim[Column]) = "B" || NOT(ISFILTERED(SlicerDim[Column])), CALCULATE([Calculation], SlicerDim[Column] = "A" || SlicerDim[Column] = "B"),
IF(MAX(SlicerDim[Column]) = "A", CALCULATE([Calculation], SlicerDim[Column] = "A"),
IF(MAX(SlicerDim[Column]) = "B", CALCULATE([Calculation], SlicerDim[Column] = "B"),
CALCULATE([Calculation], SlicerDim[Column] = BLANK()))))
Think what you are looking for is CONTAINS and VALUES
VALUES will give you the distinct current selection in scope.
CONTAINS lets you check if a table contains any row with a set of values.
[]
Formulas:
selected Scenarios = CONCATENATEX(VALUES(DimScenario[ScenarioName]);[ScenarioName];";")
Contains Forecast and Budget? =
IF(
CONTAINS(VALUES(DimScenario[ScenarioName]);[ScenarioName];"Forecast") &&
CONTAINS(VALUES(DimScenario[ScenarioName]);[ScenarioName];"Budget")
;"Yes"
;"No"
)

How to Return Text with IF Function in an Array

In Google Sheets, I'm trying to query a column and look for a state abbreviation, and if that abbreviation is a match, then "East" if not then "West"
Wanting to return text values in my column based on state abbreviation. We have territory manager split into two domains--East and West. So, trying to easily sort my data by East/West.
Here's what I have:
=IF(M:M={"AL", "CA", "DE","FL","GA","IA","KY","ME","MD","MA","MN","MS","NH","NJ","NY","ND","RI","SD","TN","VT","VA","WV","WI"},"East","West")
But, when I fill down, it just fills down East, and does not seem to actually query M:M
Thoughts?
Not the cleanest code, but this should work:
=ARRAYFORMULA(IF(LEN(A:A), IF((A:A = "foo")+(A:A = "bar") = 1, "WEST", "EAST"), ))
To use IF with an OR in an ARRAYFORMULA, you evaluate the column with 1s and 0s. The A:A = "foo" will evaluate to 1 if foo is in the cell. So if one of your OR criteria is in the cell, the total value in the IF will be 1.
You have a lot of criteria so writing each of them in will take a while ...
E.g. IF( (A:A = "AL") + (A:A = "CA") ... (A:A = "WI") = 1, "East", "West")
Use ISERROR/MATCH():
=IF(ISERROR(MATCH(M:M,{"AL", "CA", "DE","FL","GA","IA","KY","ME","MD","MA","MN","MS","NH","NJ","NY","ND","RI","SD","TN","VT","VA","WV","WI"},0)),"West","East")

Crystal Report converting value to number with symbol

I have an issue with a Crystal Report that I'm creating. I am using fields from a database and am pulling in the result value where the analysis field is equal to certain values.
In the condition the first check looks at the analysis field and checks if its equal to "Conf". The result for this is "<10"
The second check looks at the analysis field and checks if its equal to "Original". The result for this is "20".
I want the results to display in the order above however with the following basic logic it returns the result of 20.
if analysis = "conf" then result
else if analysis = "Original" then result
I was having this issue with multiple records however solved it by converting both results to numbers (toNumber(Result)). However this record has the less than symbol contained within the field value which causes the conf result to "be skipped" and will display the original result instead. I've tried a few things without success. Here is the code for the condition of where I'm at below. I fell this is way to complex logic but I've just added to it as I've had ideas and it shows what I've tried.
if {UNITS} = "CFU_G" then
if {ANALYSIS} = "CONF" and
{RESULT}="" or
{RESULT} = "0" then 0
else if {ANALYSIS} = "CONF"
then if isNumeric({RESULT}) then
tonumber({RESULT}) else
tonumber(Replace ({RESULT}, "<", ""))
else
if {UNITS} = "CFU_G" then
if {ANALYSIS} = "Original" and
{RESULT}="" or
{RESULT} = "0" then 0
else if {ANALYSIS} = "Original"
then if isNumeric({RESULT}) then
tonumber({RESULT}) else
tonumber(Replace ({RESULT}, "<", ""))
Thanks,
Tom
This was the solution I came up with.
Field 1
whileprintingrecords;
stringvar vResult := "";
Field 2
whileprintingrecords;
stringvar vResult;
vResult := if {RESULT.UNITS} = "CFU_G"
and {RESULT.ANALYSIS} = "CRA_LIS_ENU_CONF_MPCRAM29"
then {RESULT.FORMATTED_ENTRY}
else if {RESULT.ANALYSIS} = "CRA_LIST_ENU_MPCRAM29"
and {RESULT.UNITS} = "CFU_G"
and vResult = ""
then {RESULT.FORMATTED_ENTRY}
Field 3
whileprintingrecords;
stringvar vResult;
vResult;