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

The Power BI DataViz World Championships are on! With four chances to enter, you could win a spot in the LIVE Grand Finale in Las Vegas. Show off your skills.

Reply
BenHoward
Helper I
Helper I

Replace null values in multipe columns with a different column

Hi, I am trying to replace the null values in only one of several columns with a single value from the row.  This is to help produce a heiarchy (and I am not able to do this in DAX due to data integrity issues, so am left with the conundrum in Power Query).
Each person has a name, and a reporting hierachy as defined in L1, L2, L3 and L4.

BenHoward_0-1694089893934.png


I need to write the Name into the 1st of the L2, L3 or L4 columns which is not null, for example, the L2 column is null for Ben, and so I'd like write "Ben" into the L2 colum.  A similar process would work for each row, where because the L2 column already has a name, the first null column is L3, and therefore L3 would contain "Fred"

The resulting table would look like (and I have highlighted the changes)

BenHoward_1-1694090161757.png


I've tried a few options but cannot get it to work.  In my actual real-world scenario I have 8 levels 🙂

1 ACCEPTED SOLUTION
jennratten
Super User
Super User

Hello - this is one way you can do it.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WckrNU9JRci3KTAZSUBSrE63kVpSagpCAqILJeWXm5laiS0I1gBUEJ+eXlGAaGwsA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Name = _t, L1 = _t, L2 = _t, L3 = _t, L4 = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Name", type text}, {"L1", type text}, {"L2", type text}, {"L3", type text}, {"L4", type text}}),
    #"Replaced Value" = Table.ReplaceValue(#"Changed Type","",null,Replacer.ReplaceValue,{"L2", "L3", "L4"}),
    Custom3 = Table.AddColumn ( #"Replaced Value", "FieldValues", each Record.FieldValues ( _ ) ),
    ReplFirstNull = Table.AddColumn ( 
        Custom3, 
        "New", each 
        let 
            varFirstNonNullPosition = List.NonNullCount ( [FieldValues] ),
            ReplaceFirstNull = Text.Combine ( List.ReplaceRange ( [FieldValues], varFirstNonNullPosition, 1, { [FieldValues]{0} } ), "|" )
        in
            ReplaceFirstNull
    ),
    #"Removed Other Columns" = Table.SelectColumns(ReplFirstNull,{"New"}),
    #"Split Column by Delimiter" = Table.SplitColumn ( #"Removed Other Columns", "New", Splitter.SplitTextByDelimiter("|", QuoteStyle.Csv), Table.ColumnNames ( Source ) )
in
    #"Split Column by Delimiter"

jennratten_0-1694095604938.png

 

If this post helps to answer your questions, please consider marking it as a solution so others can find it more quickly when faced with a similar challenge.

Proud to be a Microsoft Fabric Super User

View solution in original post

4 REPLIES 4
slorin
Super User
Super User

Hi,

 

Table.FromRows(
List.Transform(
Table.ToRows(Source),
each List.RemoveNulls(_) & {List.First(_)} & List.Repeat({null}, List.Count(_)-List.NonNullCount(_)-1)
),
Table.ColumnNames(Source))

 

Stéphane 

jennratten
Super User
Super User

Hello - this is one way you can do it.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WckrNU9JRci3KTAZSUBSrE63kVpSagpCAqILJeWXm5laiS0I1gBUEJ+eXlGAaGwsA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Name = _t, L1 = _t, L2 = _t, L3 = _t, L4 = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Name", type text}, {"L1", type text}, {"L2", type text}, {"L3", type text}, {"L4", type text}}),
    #"Replaced Value" = Table.ReplaceValue(#"Changed Type","",null,Replacer.ReplaceValue,{"L2", "L3", "L4"}),
    Custom3 = Table.AddColumn ( #"Replaced Value", "FieldValues", each Record.FieldValues ( _ ) ),
    ReplFirstNull = Table.AddColumn ( 
        Custom3, 
        "New", each 
        let 
            varFirstNonNullPosition = List.NonNullCount ( [FieldValues] ),
            ReplaceFirstNull = Text.Combine ( List.ReplaceRange ( [FieldValues], varFirstNonNullPosition, 1, { [FieldValues]{0} } ), "|" )
        in
            ReplaceFirstNull
    ),
    #"Removed Other Columns" = Table.SelectColumns(ReplFirstNull,{"New"}),
    #"Split Column by Delimiter" = Table.SplitColumn ( #"Removed Other Columns", "New", Splitter.SplitTextByDelimiter("|", QuoteStyle.Csv), Table.ColumnNames ( Source ) )
in
    #"Split Column by Delimiter"

jennratten_0-1694095604938.png

 

If this post helps to answer your questions, please consider marking it as a solution so others can find it more quickly when faced with a similar challenge.

Proud to be a Microsoft Fabric Super User

@BenHoward Can you please review the proposed solution and let me know if this answers your question?  Thanks!

If this post helps to answer your questions, please consider marking it as a solution so others can find it more quickly when faced with a similar challenge.

Proud to be a Microsoft Fabric Super User

Hi @jennratten , thanks for the answer, it helped a lot. 

Helpful resources

Announcements
Las Vegas 2025

Join us at the Microsoft Fabric Community Conference

March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!

FebPBI_Carousel

Power BI Monthly Update - February 2025

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

Feb2025 NL Carousel

Fabric Community Update - February 2025

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

Top Solution Authors