Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends August 31st. Request your voucher.

Reply
BlueSkies3
Frequent Visitor

Multiple null replacements from column pairs

Hi, I'm trying to solve a fairly simple problem, but I've not been able to find the right combination of commands in the forum so far.

 

I have many columns in the format {"A.1", "B.1", "C.1", ...}, some of which are filled with null - I'd like to replace these values from a corresponding column, let's call them {"A.2", "B.2", "C.2", ...}. I can replace them one by one, like in the toy example here: 

let
    Source = Table.FromRecords({
        [A.1 = 1, B.1 = null, C.1 = 3, A.2 = 1, B.2 = 2, C.2 = 3],
        [A.1 = null, B.1 = 2, C.1 = 3, A.2 = 4, B.2 = 5, C.2 = 6],
        [A.1 = 1, B.1 = null, C.1 = null, A.2 = 7, B.2 = 8, C.2 = 9]
    }),
    #"Replaced nulls in A.1" = Table.ReplaceValue(Source, each [A.1], each if [A.1] = null then [A.2] else [A.1], Replacer.ReplaceValue, {"A.1"}),
    #"Replaced nulls in B.1" = Table.ReplaceValue(#"Replaced nulls in A.1", each [B.1], each if [B.1] = null then [B.2] else [A.1], Replacer.ReplaceValue, {"B.1"}),
    #"Replaced nulls in C.1" = Table.ReplaceValue(#"Replaced nulls in B.1", each [C.1], each if [C.1] = null then [C.2] else [C.1], Replacer.ReplaceValue, {"C.1"})
in
  #"Replaced nulls in C.1"

 

i.e., I'd like to replace nulls in column A.1 with the corresponding row in column A.2, etc.

 

But as I have many tens of columns and thousands of rows, I'd like to do the above steps in in a more efficient manner, if possible. Is there a way to fill in the nulls from the paired columns in one step? I was thinking there must be a way to iterate through a paried mapping of columns or similar (such as in a zipped list), but I couldn't get the formula set up correctly. Please can you give me some advice?

1 ACCEPTED SOLUTION

Hi @BlueSkies3, try this:

 

Edit these 3 steps. You can probably delete ReplacedBlankToNull step.

dufoq3_2-1710759776499.png

 

Before

dufoq3_0-1710759697205.png

 

After

dufoq3_1-1710759710673.png

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WUtJRcjYCEcZAIsQQRIC4IcZKsTrRSs6GIBGwNEQeogCiAq7EEGwIWBSiCKoKqgyoLhYA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Cat1 [r]" = _t, #"Cat2 [r]" = _t, #"Cat3 [r]" = _t, TargetCat_No1 = _t, TargetCat_No2 = _t, TargetCat_No3 = _t]),
    nullReplacementColumns = {"Cat1 [r]", "Cat2 [r]", "Cat3 [r]"},
    valReplacementColumns = {"TargetCat_No1", "TargetCat_No2", "TargetCat_No3"},
    StepBack = Source,
    ReplacedBlankToNull = Table.ReplaceValue(StepBack,"",null,Replacer.ReplaceValue,{"Cat1 [r]", "Cat2 [r]", "Cat3 [r]"}),
    ReplaceValuesFromTarget = List.Accumulate( 
        List.Zip({ nullReplacementColumns, valReplacementColumns }),
        ReplacedBlankToNull,
        (s,c)=> Table.ReplaceValue(s, null, each Record.Field(_, c{1}) , (x,y,z)=> x??z, {c{0}}) )
in
    ReplaceValuesFromTarget

Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

View solution in original post

9 REPLIES 9
AlienSx
Super User
Super User

using Table.TransformRows

let
    s = your_table,
    nullReplacementColumns = {"Cat1 [r]", "Cat2 [r]", "Cat3 [r]"},
    valReplacementColumns = {"TargetCat_No1", "TargetCat_No2", "TargetCat_No3"},
    f = (r) => Record.TransformFields(
        r, List.Transform(
            List.Zip({nullReplacementColumns, valReplacementColumns}),
            (x) => {x{0}, (w) => w ?? Record.Field(r, x{1})}
        )
    ),
    z = Table.FromRecords(Table.TransformRows(s, f))
in
    z
BlueSkies3
Frequent Visitor

Thank you both for your suggestions. The column names were actually just examples. Please could you show me how I might be able to map from and to arbitrary columns, where a simple replacement of ".1" --> ".2" won't work? Thank you very much!

You should create column pairs table i.e.:

We can help you but you should create new sample with real column names - just use dummy data.

 

FromTo
Column1

Column5

Column2

Column6

Column3

ColumnXX


Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

Thank you very much! As an example, could I map from "nullReplacementColumns" to "valReplacementColumns"? I guess there is a way to zip the columns together or similar? 

 

nullReplacementColumns = {"Cat1 [r]", "Cat2 [r]", "Cat3 [r]"}
valReplacementColumns ={"TargetCat_No1", "TargetCat_No2", "TargetCat_No3"}

 

Hi @BlueSkies3, try this:

 

Edit these 3 steps. You can probably delete ReplacedBlankToNull step.

dufoq3_2-1710759776499.png

 

Before

dufoq3_0-1710759697205.png

 

After

dufoq3_1-1710759710673.png

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WUtJRcjYCEcZAIsQQRIC4IcZKsTrRSs6GIBGwNEQeogCiAq7EEGwIWBSiCKoKqgyoLhYA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Cat1 [r]" = _t, #"Cat2 [r]" = _t, #"Cat3 [r]" = _t, TargetCat_No1 = _t, TargetCat_No2 = _t, TargetCat_No3 = _t]),
    nullReplacementColumns = {"Cat1 [r]", "Cat2 [r]", "Cat3 [r]"},
    valReplacementColumns = {"TargetCat_No1", "TargetCat_No2", "TargetCat_No3"},
    StepBack = Source,
    ReplacedBlankToNull = Table.ReplaceValue(StepBack,"",null,Replacer.ReplaceValue,{"Cat1 [r]", "Cat2 [r]", "Cat3 [r]"}),
    ReplaceValuesFromTarget = List.Accumulate( 
        List.Zip({ nullReplacementColumns, valReplacementColumns }),
        ReplacedBlankToNull,
        (s,c)=> Table.ReplaceValue(s, null, each Record.Field(_, c{1}) , (x,y,z)=> x??z, {c{0}}) )
in
    ReplaceValuesFromTarget

Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

Thank you very much! I will try this out. Can I ask what the reason is for referencing StepBack to Source rather than passing Source directly? Thanks.

It is not necessary to use StepBack, but it is more readable with it, because you imediately notice that there are some "helper" steps.


Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

dufoq3
Super User
Super User

Hi @BlueSkies3, i know that slorin solved your task but maybe you will also need this:

 

If you have more than 2 pairs of columns and you want to fill all null columns with value from pair column with higher number, this should work.

dufoq3_1-1710165236961.png

 

Result

dufoq3_2-1710165323568.png

let
Source = Table.FromRecords({
   [A.1 = 1, B.1 = null, C.1 = 3, A.2 = 1, B.2 = null, C.2 = 3, A.3 = 6, B.3 = 3, C.3 = 8],
   [A.1 = null, B.1 = 2, C.1 = 3, A.2 = 4, B.2 = 5, C.2 = null, A.3 = 7, B.3 = 4, C.3 = 2],
   [A.1 = 1, B.1 = 3, C.1 = null, A.2 = 7, B.2 = null, C.2 = 9, A.3 = 6, B.3 = 9, C.3 = 8]
   }),
    Zip = [ a = Table.ColumnNames(Source),
    occurence = List.Skip(List.Reverse(List.Distinct(List.Transform(a, each Text.AfterDelimiter(_, "."))))),
    column = List.Distinct(List.Transform(a, each Text.BeforeDelimiter(_, "."))),
    result = List.Combine(List.Transform(occurence, each List.Zip({ List.Repeat({_}, List.Count(column)), column })))
  ][result],
    StepBack = Source,
    ReplaceNulls = List.Accumulate(Zip, StepBack,
        (s,c)=> Table.ReplaceValue(s, null, 
                      each Record.Field(_, c{1} & "." & Text.From(Number.From(c{0})+1)),
                      (x,y,z)=> x??z, {c{1} & "." & c{0}} ))
in
    ReplaceNulls

 


Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

slorin
Super User
Super User

Hi,

 

let
Source = Table.FromRecords({
[A.1 = 1, B.1 = null, C.1 = 3, A.2 = 1, B.2 = 2, C.2 = 3],
[A.1 = null, B.1 = 2, C.1 = 3, A.2 = 4, B.2 = 5, C.2 = 6],
[A.1 = 1, B.1 = null, C.1 = null, A.2 = 7, B.2 = 8, C.2 = 9]
}),
Replace_null=List.Accumulate(
List.Select(Table.ColumnNames(Source), each Text.EndsWith(_,".1")),
Source,
(state,current) => Table.ReplaceValue(state, null,
each Record.Field(_, Text.Replace(current, ".1", ".2")), (x, y, z) => x??z, {current}))
in
Replace_null

Stéphane

Helpful resources

Announcements
July PBI25 Carousel

Power BI Monthly Update - July 2025

Check out the July 2025 Power BI update to learn about new features.

Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.

June 2025 community update carousel

Fabric Community Update - June 2025

Find out what's new and trending in the Fabric community.

Top Solution Authors