2

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.

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?

3
  • Just to check here, you are trying to apply an excel formula against each row within PowerQuery? If so, things don't work like that. You can read the existing value of that cell, thats it. Any formula would have to be created in powerquery, and thats definitely not an M/powerquery formula Commented Sep 15, 2022 at 11:28
  • That is exactly what I'm trying to do! Okay @horseyride, could you please point me in the direction of where I could learn how to write a powerquery formula? I've tried to do it via looking up operations, but I must be getting the formatting wrong when it comes to referencing specific cells from a certain worksheet. That and the structure of the equations used (ie. I don't know if you can combine operations using brackets) Commented Sep 16, 2022 at 13:16
  • I don't even know where to start. There are millions of reference on powerquery, the microsoft one on functions is at learn.microsoft.com/en-us/powerquery-m/… If you need help. post a simple example of your source data, desired output, and show someone how you went from source to output without a bunch of confusing blue lines. Best of lick Commented Sep 16, 2022 at 13:20

1 Answer 1

1

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:

  1. How to create a custom function.
  2. How to apply a function to a new column.
  3. 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:

  1. Using the UI (follow steps here):

    Step Description Image
    1 Write your query
    2 Parameterise your query
    3 Create your function
  2. Using only code (follow steps here):

    1. 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
      
    2. 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:

How to apply a function to a new column

Also has two different ways to achieve:

  1. Custom Column (follow steps here):

    Step Description Image
    1 Create custom column
    2 Add function
  2. Custom Function (follow steps here):

    Step Description Image
    1 Invoke custom function

Sources:

How to apply a function to an existing column

Also has two different ways to achieve (unfortunately, only possible with pure code):

  1. Using Transformation:
    1. Example to uppercase an entire column:
      let
          Source = Table,
          #"Uppercased text" = Table.TransformColumns(Source, {{"Column", each Text.Upper(_), type nullable text}})
      in
          #"Uppercased text"
      
    2. 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"
      
    3. 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"
      
  2. Using Replacement
    1. Example to replace some text:
      let
          Source = Table,
          #"Replaced value" = Table.ReplaceValue(Source, "Admin", "Administrator", Replacer.ReplaceText, {"Column"})
      in
          #"Replaced value"
      
    2. 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, 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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.