Forum Discussion

rsbin's avatar
rsbin
Icon for Community Champion rankCommunity Champion
6 years ago
Solved

Power Query Transform Fields into Records

I have imported a table into Power BI like shown below: The data comes from a CRM application.

Record No.Project AmountContract Start DateMilestone #1 - # of DaysMilestone 1 - PercentMilestone #2 - # of DaysMilestone #2 - % of $Milestone #3 - # of DaysMilestone #3 - % of $Milestone #4 - # of DaysMilestone #4 - % of $Milestone #5 - # of DaysMilestone #5 - % of $
16360000004/1/202002030206020902012020
14851401/1/202003090301203015010  
1560683410/1/201903090301203015010  

 

I need the data formatted as follows:

Record No.Project AmountContract Start DateMilestone# of DaysPercent
1636000004/1/20201020%
1636000004/1/202023020%
1636000004/1/202036020%
1636000004/1/202049020%
1636000004/1/2020512020%
14851401/1/20201030%
14851401/1/202029030%
14851401/1/2020312030%
14851401/1/2020415010%
1560683410/1/20191030%
1560683410/1/201929030%
1560683410/1/2019312030%
1560683410/1/2019415010%

 

I am hoping one of you Power Query experts out there can provide some guidance.  Each record can have anywhere from 1 to 6 Milestones.  I have shown just a select sample.  Once I have it in this format, I can add Days to Contract Start and calculate the Revenue for the Month.  I started down the path of creating a separate Table for each Milestone, I thought I would reach out to see if there might be a cleaner and elegant solution.

 

Much thanks and appreciation for your guidance and support!

 

 

  • If 'Milestone 1 - Percent' column heading is changed to follow the pattern of the other % columns then this will do it 

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("nY1LCsAgDESvUlwLmi96FvH+11CnJaXbBjI8CPMyRiKXlJNXzCYtVLjywbMACfKgHkT84Mxbp5ubkeLydUn05O3daMgTFxYqw0NvojhCRv2HbC4=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [#"Record No." = _t, #"Project Amount" = _t, #"Contract Start Date" = _t, #"Milestone #1 - # of Days" = _t, #"Milestone #1 - % of $" = _t, #"Milestone #2 - # of Days" = _t, #"Milestone #2 - % of $" = _t, #"Milestone #3 - # of Days" = _t, #"Milestone #3 - % of $" = _t, #"Milestone #4 - # of Days" = _t, #"Milestone #4 - % of $" = _t, #"Milestone #5 - # of Days" = _t, #"Milestone #5 - % of $" = _t]),
        #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Record No.", "Project Amount", "Contract Start Date"}, "Attribute", "Value"),
        #"Changed Type" = Table.TransformColumnTypes(#"Unpivoted Other Columns",{{"Value", Int64.Type}, {"Contract Start Date", type date}}),
        #"Split Column by Position" = Table.SplitColumn(#"Changed Type", "Attribute", Splitter.SplitTextByPositions({0, 13}, false), {"Attribute.1", "Attribute.2"}),
        #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Position",{{"Record No.", Int64.Type}, {"Project Amount", Int64.Type}, {"Attribute.1", type text}, {"Attribute.2", type text}}),
        #"Pivoted Column" = Table.Pivot(#"Changed Type1", List.Distinct(#"Changed Type1"[Attribute.2]), "Attribute.2", "Value", List.Sum),
        #"Sorted Rows" = Table.Sort(#"Pivoted Column",{{"Record No.", Order.Descending}, {"Attribute.1", Order.Ascending}})
    in
        #"Sorted Rows"

     A little bit of tidying still to do (filter out null values and rename columns as required)

6 Replies

  • HotChilli's avatar
    HotChilli
    Icon for Community Champion rankCommunity Champion

    If 'Milestone 1 - Percent' column heading is changed to follow the pattern of the other % columns then this will do it 

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("nY1LCsAgDESvUlwLmi96FvH+11CnJaXbBjI8CPMyRiKXlJNXzCYtVLjywbMACfKgHkT84Mxbp5ubkeLydUn05O3daMgTFxYqw0NvojhCRv2HbC4=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [#"Record No." = _t, #"Project Amount" = _t, #"Contract Start Date" = _t, #"Milestone #1 - # of Days" = _t, #"Milestone #1 - % of $" = _t, #"Milestone #2 - # of Days" = _t, #"Milestone #2 - % of $" = _t, #"Milestone #3 - # of Days" = _t, #"Milestone #3 - % of $" = _t, #"Milestone #4 - # of Days" = _t, #"Milestone #4 - % of $" = _t, #"Milestone #5 - # of Days" = _t, #"Milestone #5 - % of $" = _t]),
        #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Record No.", "Project Amount", "Contract Start Date"}, "Attribute", "Value"),
        #"Changed Type" = Table.TransformColumnTypes(#"Unpivoted Other Columns",{{"Value", Int64.Type}, {"Contract Start Date", type date}}),
        #"Split Column by Position" = Table.SplitColumn(#"Changed Type", "Attribute", Splitter.SplitTextByPositions({0, 13}, false), {"Attribute.1", "Attribute.2"}),
        #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Position",{{"Record No.", Int64.Type}, {"Project Amount", Int64.Type}, {"Attribute.1", type text}, {"Attribute.2", type text}}),
        #"Pivoted Column" = Table.Pivot(#"Changed Type1", List.Distinct(#"Changed Type1"[Attribute.2]), "Attribute.2", "Value", List.Sum),
        #"Sorted Rows" = Table.Sort(#"Pivoted Column",{{"Record No.", Order.Descending}, {"Attribute.1", Order.Ascending}})
    in
        #"Sorted Rows"

     A little bit of tidying still to do (filter out null values and rename columns as required)

    • rsbin's avatar
      rsbin
      Icon for Community Champion rankCommunity Champion

      Thank you HotChilli.

       

      I will give this a shot and let you know I make out.

       

      Thanks again.

    • rsbin's avatar
      rsbin
      Icon for Community Champion rankCommunity Champion

      Hello HotChilli 

      Thanks again for your response.  I'm finally at the point where I am trying to integrate your code into my existing Query Editor.  However, I am stuck.  I create my data table with the following line of code:

      = let
      Source = Table.SelectRows(#"OpptMaster v1", each [RevenueType]="Incremental" and [ContractStartDate]<>null and [ProjectAmount]<>0 and [Stage_Sort]<>8 and [Stage_Sort]<>7)
      in
      Source

       

      My next step is to incorporate your code.  I do not know where or how to combine your solution with the above.   I still have much to learn, but hoping you could provide me with a little guidance.  Any help is very much appreciated.

       

      Kind Regards,

      • rsbin's avatar
        rsbin
        Icon for Community Champion rankCommunity Champion

        Hi HotChilli 

         

        Great News!  Got it to work.   Thanks so much for the guidance and helpful advice.

         

        Stay safe wherever you may be!

         

        Kindest Regards,

  • dax's avatar
    dax
    Icon for Community Support rankCommunity Support

    Hi rsbin , 

    You also could refer to my sample for details.

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("lY1RCgAhCAWvsvQdlGlSZ4nuf4307eKynyv6GBDHtRIpp5y0ooykUGm1OfoAOEiDZhC1B3c2nRiPToLN18Vxx+/djR3pcWGg6niogwVLyGj+kXnvfQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [#"Record No." = _t, #"Project Amount" = _t, #"Contract Start Date" = _t, #"Milestone #1 - # of Days" = _t, #"Milestone 1 - Percent" = _t, #"Milestone #2 - # of Days" = _t, #"Milestone #2 - % of $" = _t, #"Milestone #3 - # of Days" = _t, #"Milestone #3 - % of $" = _t, #"Milestone #4 - # of Days" = _t, #"Milestone #4 - % of $" = _t, #"Milestone #5 - # of Days" = _t, #"Milestone #5 - % of $" = _t]),
        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Record No.", Int64.Type}, {"Project Amount", Int64.Type}, {"Contract Start Date", type date}, {"Milestone #1 - # of Days", Int64.Type}, {"Milestone 1 - Percent", Int64.Type}, {"Milestone #2 - # of Days", Int64.Type}, {"Milestone #2 - % of $", Int64.Type}, {"Milestone #3 - # of Days", Int64.Type}, {"Milestone #3 - % of $", Int64.Type}, {"Milestone #4 - # of Days", Int64.Type}, {"Milestone #4 - % of $", Int64.Type}, {"Milestone #5 - # of Days", Int64.Type}, {"Milestone #5 - % of $", Int64.Type}}),
        #"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Record No.", "Project Amount", "Contract Start Date"}, "Attribute", "Value"),
        #"Split Column by Delimiter" = Table.SplitColumn(#"Unpivoted Columns", "Attribute", Splitter.SplitTextByDelimiter("-", QuoteStyle.Csv), {"Attribute.1", "Attribute.2"}),
        #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Attribute.1", type text}, {"Attribute.2", type text}}),
        #"Split Column by Delimiter1" = Table.SplitColumn(#"Changed Type1", "Attribute.1", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"Attribute.1.1", "Attribute.1.2", "Attribute.1.3"}),
        #"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Attribute.1.1", type text}, {"Attribute.1.2", type text}, {"Attribute.1.3", type text}}),
        #"Replaced Value" = Table.ReplaceValue(#"Changed Type2","#","",Replacer.ReplaceText,{"Attribute.1.2"}),
        #"Replaced Value1" = Table.ReplaceValue(#"Replaced Value","% of $","Percent",Replacer.ReplaceText,{"Attribute.2"}),
        #"Pivoted Column1" = Table.Pivot(#"Replaced Value1", List.Distinct(#"Replaced Value1"[Attribute.2]), "Attribute.2", "Value"),
        #"Pivoted Column" = Table.Pivot(#"Pivoted Column1", List.Distinct(#"Pivoted Column1"[Attribute.1.1]), "Attribute.1.1", "Attribute.1.2"),
        #"Removed Columns" = Table.RemoveColumns(#"Pivoted Column",{"Attribute.1.3"})
    in
        #"Removed Columns"


    Best Regards,
    Zoe Zhi

    If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.