2014-08-29 44 views
0

我有一个看起来像这样的文件:电源查询 - 解析一个非常奇怪的文件

AA,DATA,DATA,DATA 
BB,DATA,DATA,DATA,DATA 
ZZ,DATA,DATA,DATA,DATA,DATA,DATA 
ZZ,DATA,DATA,DATA,DATA,DATA 
CC,DATA,DATA 
ZZ,DATA,DATA,DATA 
ZZ,DATA,DATA,DATA 
ZZ,DATA,DATA,DATA,DATA 

正如你所看到的,这是非常不友好的。 ZZ的起始线意味着它们与之前的记录有关;因此在我的例子中,BB分成3行,CC分成4行。 我想在Power Query(Excel 2013)中实现的目标是获取仅包含AA,BB和CC记录的表。 ZZ将被连接到它们各自的BB和CC记录。 ZZ记录的数量可能会有所不同。
我是Power Query的新手,我想我开始处理的问题太多了;)关于如何构建表格和/或列表来帮助我的任何特定想法将不胜感激。

谢谢。

问候, 马丁

回答

0

我敢肯定的,你不能这样做,在PowerQuery。您可以使用VBA来获取正确的数据,然后将其放入PowerQuery中。这里有一些代码可以做到这一点。

Sub NormalizeData() 

    Dim sFile As String, lFile As Long 
    Dim vaLines As Variant 
    Dim vaData As Variant 
    Dim i As Long, j As Long 
    Dim dc As Scripting.Dictionary 
    Dim lStart As Long 

    'Open file and read in all the data 
    sFile = "K:\testfile.txt" 
    lFile = FreeFile 

    Open sFile For Input As lFile 
    vaLines = Split(Input$(LOF(lFile), lFile), vbNewLine) 
    Close lFile 

    For i = LBound(vaLines) To UBound(vaLines) 

     vaData = Split(vaLines(i), ",") 

     If vaData(0) <> "ZZ" Then 
      'Output existing dictionary if it exists 
      If Not dc Is Nothing Then Debug.Print Join(dc.Items, ",") 

      'Create a new dictionary and start at the first column (0) 
      Set dc = New Scripting.Dictionary 
      lStart = 0 
     Else 
      'starts with ZZ so skip the first column 
      lStart = 1 
     End If 

     'Add the data to the dictionary 
     For j = lStart To UBound(vaData) 
      dc.Add dc.Count + 1, vaData(j) 
     Next j 

    Next i 

    'Output the last dictionary 
    If Not dc Is Nothing Then Debug.Print Join(dc.Items, ",") 

End Sub 
+0

我明白你的VBA逻辑,这就是我想用Power Query完成的。我很积极,这可以做:)我正在考虑尝试导出一个索引的行号,然后定义另一列的行号是与前一个相同的情况下,第一列是ZZ ..我然后可以将记录组合​​在一起,并使用列表/表格来操纵字符串... – Martin 2014-08-29 15:12:02

0

我知道这是一个古老的问题,而且可能我的解决方案无法正常工作。但是,当我在PowerBI Desktop中尝试使用时,此PQFL运行良好。

let 
    RecordKey = (t,n) => Table.Range(t,n,1){0}[Key], 

    NeedsMerged = (t,n) => 
    try 
     if RecordKey(t,n+1) = "ZZ" then true else false 
    otherwise false, 

    MergeWithNext = (t,n) => 
    if NeedsMerged(t,n) then 
     let 
     thisRow = Table.Range(t, n, 1), 
     nextRow = Table.Range(t, n+1, 1) 
     in 
     { 
     true, 
     Table.Range(t, 0, n) & 
     Table.TransformColumns(thisRow, {"Data", (_) => _ & nextRow{0}[Data] }) & 
     Table.Range(t, n + 2) 
     } 
    else {false,t}, 

    DoNeededMerging = (t,n) => 
    if Table.RowCount(t) < n then t 
    else 
     let 
     res = MergeWithNext(t,n), 
     resp = res{0}, 
     tbl = res{1} 
     in 
     if resp then 
      @DoNeededMerging(tbl,n) 
     else 
      @DoNeededMerging(tbl,n+1), 

    Filename = "C:\the_data_file.csv", 
    DataTable = Table.FromList(Lines.FromText(Text.FromBinary(File.Contents(Filename))), Splitter.SplitTextByDelimiter(","), {"Key","Data"}, null, ExtraValues.List), 
    DataTable2 = DoNeededMerging(DataTable , 0) 

in 
    DataTable2