Forum Discussion

Jacb's avatar
Jacb
Frequent Visitor
1 year ago
Solved

How to deal with multiple headers in data in Power BI

Hi, 
I am trying to read in the data from PDF document that contains operational stats. 
The data from the PDF file looks like this.  

When the PDF file is read into Power BI - Power BI identifies that the data contains 4 headers Login etc, Agent ID, Agent Name and Date as shown below:

Column1Column2Column3Column4Column5Column6Column7Column8Column9Column10Column11Column12
Log InLog OutLogin

Duration
Available TReleased TAvailable

In Call T
Released

In Call T
In Call TMedia TypeCalls

Handled
Avg T To

Answer
Max T To

Answer
Agent Id:1111nullnullnullnullnullnullnullnullnullnull
Agent Name:Joe Blogsnullnullnullnullnullnullnullnullnullnull
06/01/2025nullnullnullnullnullnullnullnullnullnullnull
09:55:5114:36:5704:41:0603:35:1601:05:5000:00:0000:00:0000:00:00(All)000:00:0000:00:31
14:45:5618:13:0503:27:0903:22:0600:05:0300:00:0000:00:0000:00:00(All)000:00:0000:00:15
nullTotal:08:08:1506:57:2201:10:5300:00:0000:00:0000:00:00null000:00:0000:00:31
Agent Id:9999nullnullnullnullnullnullnullnullnullnull
Agent Name:Millie Smithnullnullnullnullnullnullnullnullnullnull
06/01/2025nullnullnullnullnullnullnullnullnullnullnull
10:02:3112:53:3502:51:0400:00:0002:51:0400:00:0000:00:0000:00:00(All)000:00:0000:00:00
13:21:1814:25:3301:04:1500:00:0001:04:1500:00:0000:00:0000:00:00(All)000:00:0000:00:00
16:04:2216:39:0100:34:3900:00:0000:34:3900:00:0000:00:0000:00:00(All)000:00:0000:00:00
nullTotal:04:29:5800:00:0004:29:5800:00:0000:00:0000:00:00null000:00:0000:00:00
Agent Id:1122nullnullnullnullnullnullnullnullnullnull
Agent Name:Joe Blacknullnullnullnullnullnullnullnullnullnull
06/01/2025nullnullnullnullnullnullnullnullnullnullnull
09:33:0211:09:3101:36:2900:45:5900:50:3000:00:0000:00:0000:00:00(All)000:00:0000:00:16
12:23:3812:56:0500:32:2700:32:2600:00:0100:00:0000:00:0000:00:00(All)000:00:0000:00:00
nullTotal:02:08:5601:18:2500:50:3100:00:0000:00:0000:00:00null000:00:0000:00:16


What is the most efficient way to get the data into a meaningful table to extract the operational stats for each agents profile per date?

Any help you can provide will be greatly appreciated. 

Thanks




  • Use this

    let
        Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
        #"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
        #"Filtered Rows" = Table.SelectRows(#"Promoted Headers", each [Log In] <> null),
        #"Added Agent Id" = Table.AddColumn(#"Filtered Rows", "Agent Id", each if Text.StartsWith(Text.From([Log In]),"Agent Id",Comparer.OrdinalIgnoreCase) then [Log Out] else null),
        #"Added Agent Name" = Table.AddColumn(#"Added Agent Id", "Agent Name", each if Text.StartsWith(Text.From([Log In]),"Agent Name",Comparer.OrdinalIgnoreCase) then [Log Out] else null),
        #"Added Date" = Table.AddColumn(#"Added Agent Name", "Date", each if [Log Out] = null then [Log In] else null),
        #"Filled Down" = Table.FillDown(#"Added Date",{"Agent Id", "Agent Name", "Date"}),
        #"Filtered Data Rows Only" = Table.SelectRows(#"Filled Down", each [Log In] <> "Agent Id:"and [Log In] <> "Agent Name:"and [Log Out] <> null),
        #"Reordered Columns" = Table.ReorderColumns(#"Filtered Data Rows Only",{"Agent Id", "Agent Name", "Date", "Log In", "Log Out", "Login", "Available T", "Released T", "Available", "Released", "In Call T", "Media Type", "Calls", "Avg T To", "Max T To"})
    in
        #"Reordered Columns"

     

    to produce this:

     

    from this Excel Data:

     

     

6 Replies

  • Use this

    let
        Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
        #"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
        #"Filtered Rows" = Table.SelectRows(#"Promoted Headers", each [Log In] <> null),
        #"Added Agent Id" = Table.AddColumn(#"Filtered Rows", "Agent Id", each if Text.StartsWith(Text.From([Log In]),"Agent Id",Comparer.OrdinalIgnoreCase) then [Log Out] else null),
        #"Added Agent Name" = Table.AddColumn(#"Added Agent Id", "Agent Name", each if Text.StartsWith(Text.From([Log In]),"Agent Name",Comparer.OrdinalIgnoreCase) then [Log Out] else null),
        #"Added Date" = Table.AddColumn(#"Added Agent Name", "Date", each if [Log Out] = null then [Log In] else null),
        #"Filled Down" = Table.FillDown(#"Added Date",{"Agent Id", "Agent Name", "Date"}),
        #"Filtered Data Rows Only" = Table.SelectRows(#"Filled Down", each [Log In] <> "Agent Id:"and [Log In] <> "Agent Name:"and [Log Out] <> null),
        #"Reordered Columns" = Table.ReorderColumns(#"Filtered Data Rows Only",{"Agent Id", "Agent Name", "Date", "Log In", "Log Out", "Login", "Available T", "Released T", "Available", "Released", "In Call T", "Media Type", "Calls", "Avg T To", "Max T To"})
    in
        #"Reordered Columns"

     

    to produce this:

     

    from this Excel Data:

     

     

    • Jacb's avatar
      Jacb
      Frequent Visitor

      Thank you - this worked! 
      I just had to follow your steps as my source was a PDF document but I was still able to use the other steps and it worked. 
      Thanks again 
      JB

    • Jacb's avatar
      Jacb
      Frequent Visitor

      Thank you for your link to your video. 
      Your video helped me to understand the methodology.   My source was not an originally table though as it was table contain pages and tables but I still understood your methodology and how it worked. 
      Thanks again for all your help 
      JB

  • It is always a bit of trial and error.

    Here Iwould probaly

    • start by removing empty lines.
    • Then Transpose
    • Creeate 3 new columns for AgentId, Agent Name and the data
      Using an if expression to do that only for the lines where they actually occur
    • Then do a fill down on these columns
    • Then remove the AgentId, name and Date rows

    This would be a good start I think...

     

    Did I answer your question? Then please mark my post as the solution and make it easier to find for others having a similar problem.
    If I helped you, please click on the Thumbs Up to give Kudos.

     

    Kees Stolker

    A big fan of Power Query and Excel

  • dufoq3's avatar
    dufoq3
    Community Champion

    Hi Jacb, another solution:

     

    Output (first few columns)

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("1VVNb9QwEP0r1p5AqlR/xNlkbgscWERBgtyWHgyxlgg3Qd0sH/+eN46lZNtQtd3uoUkkP4/tefb4zWSzWbzvtmLdLs4i+LjvB9S0X/C+2V+7vul4dPXLNcF9DV5U6H3ywbudr2NnHFq34rUL4XDK1DjFF75unKj+/vTosHUn3rq2Dr6OPreiElUnVu3ut7/m6e7PgeXybLNYbX3bi3VNGFd40LT7EI5tRtcf3JVn5+86L16Fbrt7QgaZn0t1rqW2T+R06rska8lyQFRGJie7BJQZZYpkztCQsaQihAlzJUNJ8fsvfLEK4SWb5mYYFblBmMEfu1YFKQPvA6FekiwT1GkbkrmlOZpb2cid4lB1vQt8b7IgfCpugIMA4uHESpK9F2vyeNeBpyos8ZxMhRdNCI0Xn6+a/vszESLiLDUHCmLQCDlUx+EDhOqyG0Gdtz5cDICRGzrDTRdDEmhLxiS5Z0kSk4Xz1sdz5+wvqg3QlCTVMMUgHctbC+etj+S+lQTYCOpBcWPJvPXBSZBID0txPPgpS7H79uOZZABKsUENjEqAyMohGaA3VGWd7pzrZYIWYji+FKOwRxVq0ki5ImVfnkoxKDCwHGE++lAnU6HmUmzTHwd/Bm3HE9+L9S4V8oEv/wE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t, Column5 = _t, Column6 = _t, Column7 = _t, Column8 = _t, Column9 = _t, Column10 = _t, Column11 = _t, Column12 = _t]),
        ReplacedNulls = Table.TransformColumns(Source, {}, each List.ReplaceMatchingItems({_}, {{"null", null}}){0}),
        PromotedHeader = Table.PromoteHeaders(ReplacedNulls),
        TransformedHeader = Table.TransformColumnNames(PromotedHeader, each Text.Combine(List.RemoveMatchingItems(Text.Split(_, "#(lf)"), {""}), " ") ),
        GroupedRows = Table.Group(TransformedHeader, "Log In", {{"T", each 
            [ a = Table.RemoveLastN(_, 1),
              b = Table.FromRows(List.Transform(List.Skip(Table.ToRows(a), 3), (x)=> {a{0}[Log Out], a{1}[Log Out], a{2}[Log In]} & x), {"Agent Id", "Agent Name", "Date"} & Table.ColumnNames(a) )
            ][b], type table}}, 0,
            (x,y)=> Byte.From( y = "Agent Id:" ) ),
        CombinedT = Table.Combine(GroupedRows[T])
    in
        CombinedT