Excel Power Query M: passing a header as function parameter? - excel

In Excel Power Query, in the M language:
How do I pass a column name as a parameter to a function? As a (contrived) example, supposed I have a table:
Fish Fowl
1
2 1
1
2
I want a function which will take the table and one of the column-names, and return the sum of that column. I tried this implementation
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
SumType = (Tbl, ColumnName) =>
List.Sum(Tbl[ColumnName]),
FowlSum = SumType(ChType, "Fowl")
in
FowlSum
But it fails with an error: "The column 'ColumnName' wasn't found."
So how can I pass a column name (as a string) to a function, and then access that column within the functions?

Use Table.Column. In your case the line would look like List.Sum(Table.Column(Tbl, ColumnName)).

Related

Error: Splitting rows into separate rows on all columns in Power Query

I had a problem spliting data in rows, used the solution provided by horseyride in the following link
Splitting rows into separate rows on all columns in Power Query.
Basically I am loocking to separete a row as breaks there are.
Many thanks #horseyride. The solution works in a simular problem. However, it's poping up the following error:
Expression.Error: We cannot convert a value of type Table to type Text.
Details:
Value=[Table]
Type=[Type]
My table is this one:
let
Source = Pdf.Tables(File.Contents("C:\Users\gmall\OneDrive\EF personales\EF\Temporales\IBK_Sueldo_PEN.pdf"), [Implementation="1.3"]),
Table002 = Source{[Id="Table002"]}[Data],
TableTransform = Table.Combine(List.Transform(List.Transform(Table.ToRecords(Source),
(x) => List.Transform(Record.ToList(x),each Text.Split(_,"#(lf)"))),
each Table.FromColumns(_,Table.ColumnNames(Source))))
in
TableTransform
Please let me know how to solve this issue:
Expression.Error: We cannot convert a value of type Table to type Text.
Details:
Value=[Table]
Type=[Type]
You need to use Table002 in step3 since that is the prior step name, not Source, which was the prior step name in my other answer
let
Source = Pdf.Tables(File.Contents("C:\Users\gmall\OneDrive\EF personales\EF\Temporales\IBK_Sueldo_PEN.pdf"), [Implementation="1.3"]),
Table002 = Source{[Id="Table002"]}[Data],
TableTransform = Table.Combine(List.Transform(List.Transform(Table.ToRecords(Table002),
(x) => List.Transform(Record.ToList(x),each Text.Split(_,"#(lf)"))),
each Table.FromColumns(_,Table.ColumnNames(Table002))))
in
TableTransform

How to separate stringin databricks

I try to separete a string like LESOES DO OMBRO (M75) using a function split_part in databricks, but occurs an error: AnalysisException: Undefined function: 'SPLIT_part'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'. I need to separate the code in parentheses of the rest of the text.
I have a column "patologia" the column is for example LESOES DO OMBRO (M75) and I need a new column with the value M75
If I understood correctly and you need a new column with the value that's between parentheses in another column, then you can extract such value with regular expression, like this
from pyspark.sql.functions import regexp_extract
regex_df = spark.createDataFrame([("LESOES DO OMBRO (M75)",)], "patologia: string")
extracted_col_df = regex_df.withColumn("extracted_value", regexp_extract("patologia", r'\(([^)]+)\)', 1))
extracted_col_df.show()
+---------------------+---------------+
|patologia |extracted_value|
+---------------------+---------------+
|LESOES DO OMBRO (M75)|M75 |
+---------------------+---------------+

Applying function to each row in Query Custom Column

Summary of problem:
I have a PowerQuery Table in Excel that contains 13 columns. The 13th Column is a custom column "Task Start Week Number". I want the PowerQuery to apply a formula to each of the rows generated for this Query. The formula is as follows:
=IFS(AND('Program Dates'!$B$2<WEEKNUM(New_Items_to_Save[Start Date]),
WEEKNUM(New_Items_to_Save[Start Date])<54),
'Program Dates'!$G$2-('Program Dates'!$D$2-(-53+WEEKNUM(New_Items_to_Save[Start Date]))),
WEEKNUM(New_Items_to_Save[Start Date])<'Program Dates'!$B$2,
'Program Dates'!$G$2-('Program Dates'!$D$2-(-53+WEEKNUM(New_Items_to_Save[Start Date])))+53)
What I've done here is reference a cell which contains the formula, that way I can just run the GetValue() function for a named range. I can't get this to work and I don't know what I'm doing wrong.
Thank you in advance for your help!
Context:
This is the query table I need to add the calculation to.
The last column is the custom column, and those values should be calculated using the following cells:
This is the source of the other info needed to calculate the week number of the program, with reference arrows shown.
Note: The dates referenced in the function have already been converted using the WEEKNUM() operation. I am comparing Week# to Week#, not Date to Week#
Function Logic:
AND: if the date falls within the range of the current year ie. week# is less than 54, but after the start of the program, then perform this calc.
IFS: otherwise, if week# is before the end of the program ie. 2023, then perform this calculation.
Edit:
Here is the PowerQuery function I want to call for each of the new cells in this custom column:
Parameter2 = Date.WeekOfYear(StartWeek)
let
GetWeek = ()
if GetValue("Start_Week") < Parameter2 < 54
then (GetValue("Program_Duration") - GetValue("End_Week") + 53 - Parameter2))
else
(GetValue("Program_Duration") - GetValue("End_Week") + 53 - Parameter2 +53))
in
GetWeek
I don't know if I need the let statement or if I should just put it in a function
f(x) => [equation]
and then call "...each f([column name])" in power query?
I think that there are actually three different parts to your question, and maybe your confusion is coming from combining them all together.
The way I see it is in these parts:
How to create a custom function.
How to apply a function to a new column.
How to apply a function to an existing column.
How to create a custom function
There are two main ways to create a custom function in Power Query:
Using the UI (follow steps here):
Step
Description
Image
1
Write your query
2
Parameterise your query
3
Create your function
Using only code (follow steps here):
Example to filter a table:
let fun_FilterTable = (tbl_InputTable as table, txt_FilterValue as text) as table =>
let
Source = tbl_InputTable,
Filter = Table.SelectRows(DayCount, each Text.Contains([Column], txt_FilterValue))
in
Filter
in
fun_FilterTable
Example to check if one string contains another:
let fun_CheckStringContains = (txt_String as text, txt_Check as text) as nullable logical =>
let
Source = txt_String,
Check = Text.Contains(Source, txt_Check)
in
Check
in
fun_CheckStringContains
More resources:
Using custom functions
Custom Functions Made Easy in Power BI Desktop
PowerQuery best practices
DataFlow best practices
How to apply a function to a new column
Also has two different ways to achieve:
Custom Column (follow steps here):
Step
Description
Image
1
Create custom column
2
Add function
Custom Function (follow steps here):
Step
Description
Image
1
Invoke custom function
Sources:
Add a custom column
Using custom functions
Custom Functions Made Easy in Power BI Desktop
How to apply a function to an existing column
Also has two different ways to achieve (unfortunately, only possible with pure code):
Using Transformation:
Example to uppercase an entire column:
let
Source = Table,
#"Uppercased text" = Table.TransformColumns(Source, {{"Column", each Text.Upper(_), type nullable text}})
in
#"Uppercased text"
Example to add a prefix to all rows in one column:
let
Source = Table,
#"Added prefix" = Table.TransformColumns(Source, {{"Column", each "test_" & _, type text}})
in
#"Added prefix"
Example to coerce column to date in Australian format:
let
Source = Table,
#"Fix date" = Table.TransformColumns(Source, {{"DateColumn", each Date.From(_, "en-AU"), type date}})
in
#"Fix date"
Using Replacement
Example to replace some text:
let
Source = Table,
#"Replaced value" = Table.ReplaceValue(Source, "Admin", "Administrator", Replacer.ReplaceText, {"Column"})
in
#"Replaced value"
Example to replace with values from another column
let
Source = Table,
#"Replaced value" = Table.ReplaceValue(Source, each [FixThisColumn], each [OtherColumn], Replacer.ReplaceText, {"FixThisColumn"})
in
#"Replaced value"
Your Specific Problem
Without some dummy data to use, I have created some here. Please note, in future, please provide some data in a minimum reproducible example (see here), so that we can easily recreate the scenario from your example.
Data:
ID
ProgramStartDate
ProgramEndDate
1
1/Jan/2020
1/Dec/2021
2
1/Jan/2022
1/Mar/2023
3
1/Mar/2022
1/Dec/2022
4
1/Sep/2021
1/Dec/2023
5
1/Jan/2023
1/Dec/2023
I think that you should be using a combination of the PowerQuery in-build date functions (see here) and some of the PowerQuery conditional processes (see here).
My code would look something like this:
let
Source = Table.FromColumns({{1,2,3,4,5},{"1/Jan/2020","1/Jan/2022","1/Mar/2022","1/Sep/2021","1/Jan/2023"},{"1/Dec/2021","1/Mar/2023","1/Dec/2022","1/Dec/2023","1/Dec/2023"}},{"ID","ProgramStartDate","ProgramEndDate"}),
fix_Types = Table.TransformColumnTypes(Source,{{"ID", Int64.Type}, {"ProgramStartDate", type date}, {"ProgramEndDate", type date}}),
add_Today = Table.AddColumn(fix_Types, "DateToday", each Date.From(DateTime.LocalNow()), type date),
add_CheckCurrentYear = Table.AddColumn(add_Today, "IsInCurrentYear", each Date.IsInCurrentYear([DateToday]), type logical),
add_CheckProgramRunning = Table.AddColumn(add_CheckCurrentYear, "ProgramIsCurrent", each [DateToday]>[ProgramStartDate] and [DateToday]<[ProgramEndDate], type logical),
add_ConditionalCheck = Table.AddColumn(add_CheckProgramRunning, "DoSomething", each if [IsInCurrentYear] and [ProgramIsCurrent] then "Do Something" else null, type text)
in
add_ConditionalCheck
And the final output would look something like this:
ID
ProgramStartDate
ProgramEndDate
DateToday
IsInCurrentYear
ProgramIsCurrent
DoSomething
1
1/01/2020
1/12/2021
22/12/2022
TRUE
FALSE
null
2
1/01/2022
1/03/2023
22/12/2022
TRUE
TRUE
Do Something
3
1/03/2022
1/12/2022
22/12/2022
TRUE
FALSE
null
4
1/09/2021
1/12/2023
22/12/2022
TRUE
TRUE
Do Something
5
1/01/2023
1/12/2023
22/12/2022
TRUE
FALSE
null
This should help you work towards resolving your issue.

SELECT statement returning the column name instead of the VALUE (for that said column)

I'm trying to parse information in to a SELECT statement using the two column names 'id' and 'easy_high_score' so I can manipulate values of them two columns in my program, but when trying to get the value of the column 'easy_high_score', which should be an integer like 46 or 20, it instead returns a string of ('easy_high_score',).
Even though there is no mention of [('easy_high_score',)] in the table, it still prints this out. In the table, id 1 has the proper values and information i'm trying get but to no avail. I am fairly new to SQLite3.
if mode == "Easy":
mode = 'easy_high_score'
if mode == "Normal":
mode = "normal_high_score"
if mode == 'Hard':
mode == "hard_high_score"
incrementor = 1 ##This is used in a for loop but not necessary for this post
c.execute("SELECT ? FROM players WHERE id=?", (mode, incrementor))
allPlayers = c.fetchall()
print(allPlayers) #This is printing [('easy_high_score',)], when it should be printing an integer.
Expected Result: 20 (or an integer which represents the high score for easy mode)
Actual Result: [('easy_high_score',)]
Column name cannot be specified using a parameter it should be present verbatim in the query. Modify the line that executes the query like this:
c.execute("SELECT %s FROM players WHERE id=?" % mode, (incrementor,))
A possible cause of this is double quotes vs single quotes.
'SELECT "COLUMN_NAME" FROM TABLE_NAME' # will give values as desired
"SELECT 'COLUMN_NAME' FROM TABLE_NAME" # will give column name like what you got

Displaying retrieved value in excel file into ALV

Good Day Everyone,
There is this something i've been trying to exercise in abap and that is the Displaying of column datas in ALV by retrieving the values from excel file into an internal table. I've been trying to debug my program for quite some time now and i can't seem to solve the error it's been stating which is "Field symbol has not yet been assigned" please guide me. I already made some research on how to solve this short dump error but most of the other issues posted on the net is selected from some specific table with column fields. I was just wondering that maybe my case is a little bit different from others.
The function that retrieved the values from excel is properly working and i have no problem at all in displaying them.Below is the code i constructed.
TYPE-POOLS: truxs,
slis.
TYPES: BEGIN OF t_itab,
col1 TYPE char20,
col2 TYPE char20,
col3 TYPE char20,
col4 TYPE char20,
col5 TYPE char20,
END OF t_itab,
t_it_itab type STANDARD TABLE OF t_itab.
Data: gt_tab TYPE t_it_itab,
wa_tab TYPE t_itab,
g_numrows TYPE i.
PARAMETERS: p_fname TYPE c LENGTH 50.
INITIALIZATION.
AT SELECTION-SCREEN OUTPUT.
AT SELECTION-SCREEN.
AT SELECTION-SCREEN on VALUE-REQUEST FOR p_fname.
DATA: l_filename LIKE IBIPPARMS-PATH.
CALL FUNCTION 'F4_FILENAME'
EXPORTING
PROGRAM_NAME = SYST-CPROG
DYNPRO_NUMBER = '1000'
IMPORTING
FILE_NAME = l_filename
.
p_fname = l_filename.
START-OF-SELECTION.
DATA: lc_fname TYPE RLGRAP-FILENAME,
lt_tab TYPE TRUXS_T_TEXT_DATA.
lc_fname = p_fname.
CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
EXPORTING
I_TAB_RAW_DATA = lt_tab
I_FILENAME = lc_fname
TABLES
I_TAB_CONVERTED_DATA = gt_tab
EXCEPTIONS
CONVERSION_FAILED = 1
OTHERS = 2
.
IF SY-SUBRC <> 0.
WRITE 'Error'.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
" Delete First Row / HEADER
DELETE gt_tab INDEX 1.
IF gt_tab[] is INITIAL.
MESSAGE 'No Record(s) found' TYPE 'I'.
EXIT.
ELSE.
PERFORM DisplayALv.
ENDIF.
FORM DISPLAYALV.
DATA: l_it_fcat type SLIS_T_FIELDCAT_ALV,
l_wa_fcat TYPE SLIS_FIELDCAT_ALV.
l_wa_fcat-fieldname = 'col1'.
l_wa_fcat-ref_tabname = 'gt_tab'.
l_wa_fcat-reptext_ddic = 'Column 1'.
l_wa_fcat-outputlen = '30'.
APPEND l_wa_fcat TO l_it_fcat.
CLEAR l_wa_fcat.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = sy-repid
IT_FIELDCAT = l_it_fcat
I_DEFAULT = 'X'
I_SAVE = 'A'
TABLES
T_OUTTAB = gt_tab[].
IF SY-SUBRC <> 0.
WRITE: 'SY-SUBRC: ', SY-SUBRC .
ENDIF.
ENDFORM.
Any tips, tricks and advice in my program would be highly sought. Thanks in Advance
You're using a type which is not defined in the data dictionary. This requires a different approach when creating the ALV fieldcat. Try this:
l_wa_fcat-fieldname = 'COL1'.
l_wa_fcat-inttype = 'C'.
l_wa_fcat-outputlen = '30'.
l_wa_fcat-text_fieldname = 'Column 1'.
l_wa_fcat-seltext_s = 'Column 1'.
Also make sure you enter the fieldname value with capitalized letters.
I'm no ABAP expert but I noticed 2 things in the code you posted:
you said the error is "Field symbol has not yet been assigned" but you have no field symbol in your code. Maybe it's used inside one of the function modules you call. If so, try to post the code where the error pops up;
you use gt_tab[] which, if I remember well, is the way to access the body of an internal table with header line. In your code gt_tab is not an internal table with header line, but you use it to store one with function 'TEXT_CONVERT_XLS_TO_SAP' ;
Try to post the code where the error is being generated.
Regards,
Sergiu

Resources