将一列按多个条件分割成一个包含多个条件的表格。

huangapple go评论65阅读模式
英文:

Excel: Dividing a column into a table with multiple criteria

问题

I can help with the translation of the provided text. Here's the translated content:

我有一些条形码扫描器,它们在Excel的一列中列出了条形码。

目标是根据以下测试用例将原始列分成一个表格。有人知道如何实现吗?

表格之前:

A
XXID0081
45011
654000
2
654001
3
654002
4
XXID0082
45012
785902
2
3
XXID0083
45013
888981
2
888982
3

表格之后:

A B C D
XXID0081 45011 654000 2
XXID0081 45011 654001 3
XXID0081 45011 654002 4
XXID0082 45012 785902 5
XXID0083 45013 888981 2
XXID0083 45013 888982 3

我尝试使用Power Query,但想要使用Excel函数来完成。尝试使用WRAPROWS函数

=WRAPROWS(A2:A300,4)

但它不起作用。还有一个问题,当A、B、C列的数量是两倍时,它们将被相加,例如在屏幕截图中所示。

如果您有任何问题,请随时提问。如果需要,我将发布Power Query代码。TIA。

英文:

I have some barcode scanner which lists out the codes on a column in Excel.

The goal is to divide the original column into a table as per the test cases below. Does anyone have an idea in how to achieve it?

Table Before:

A
XXID0081
45011
654000
2
654001
3
654002
4
XXID0082
45012
785902
2
3
XXID0083
45013
888981
2
888982
3

Table After:

A B C D
XXID0081 45011 654000 2
XXID0081 45011 654001 3
XXID0081 45011 654002 4
XXID0082 45012 785902 5
XXID0083 45013 888981 2
XXID0083 45013 888982 3

I have tried using the Power query but wanted to do it with excel functions. Tried using the WRAPROWS

=WRAPROWS(A2:A300,4)

not working. There is one more problem when the qty is twice for A,B,C column it will be added up. for example as in the screenprints.

Please ask away if you have any questions. I will post the power query code if needed. TIA.

let
    Source = Excel.CurrentWorkbook(){[Name="Table6"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"A", type text}}),
    #"Added Conditional Column" = Table.AddColumn(#"Changed Type", "Custom", each if Text.StartsWith([A], "XXID") then [A] else null),
    #"Filled Down" = Table.FillDown(#"Added Conditional Column",{"Custom"}),
    #"Filtered Rows" = Table.SelectRows(#"Filled Down", each not Text.StartsWith([A], "UID")),
    #"Added Custom" = Table.AddColumn(#"Filtered Rows", "Custom.1", each if Text.Length([A]) = 5 then [A] else null),
    #"Filled Down1" = Table.FillDown(#"Added Custom",{"Custom.1"}),
    #"Added Custom1" = Table.AddColumn(#"Filled Down1", "Custom.2", each if Text.Length([A]) = 6 then [A] else null),
    #"Filled Down2" = Table.FillDown(#"Added Custom1",{"Custom.2"}),
    #"Filled Up" = Table.FillUp(#"Filled Down2",{"Custom.2"}),
    #"Added Custom2" = Table.AddColumn(#"Filled Up", "Custom.3", each if Text.Length([A]) < 4 then [A] else null),
    #"Filtered Rows1" = Table.SelectRows(#"Added Custom2", each [Custom.3] <> null and [Custom.3] <> ""),
    #"Removed Columns" = Table.RemoveColumns(#"Filtered Rows1",{"Custom.3"}),
    #"Reordered Columns" = Table.ReorderColumns(#"Removed Columns",{"Custom", "Custom.1", "Custom.2", "A"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Reordered Columns",{{"Custom", type text}, {"Custom.1", Int64.Type}, {"Custom.2", Int64.Type}, {"A", type number}}),
    #"Grouped Rows" = Table.Group(#"Changed Type1", {"Custom", "Custom.1", "Custom.2"}, {{"A", each List.Sum([A]), type nullable text}}),
    #"Changed Type2" = Table.TransformColumnTypes(#"Grouped Rows",{{"Custom", type text}, {"Custom.1", Int64.Type}, {"Custom.2", Int64.Type}, {"A", type number}})
in
    #"Changed Type2"

将一列按多个条件分割成一个包含多个条件的表格。

将一列按多个条件分割成一个包含多个条件的表格。

答案1

得分: 4

=LET(arr,VSTACK(TOCOL(A:A,1),"Finish"),n,ROWS(arr),seq,SEQUENCE(n),seqA,SEQUENCE(n-1),
WRAPROWS(DROP(REDUCE("",seqA,LAMBDA(all,curr,
LET(length,LEN(INDEX(arr,curr)),lenNext,LEN(INDEX(arr,curr+1)),IF(AND(length<=4,lenNext>4),VSTACK(all,
XLOOKUP(1,(LEN(arr)=8)(seq<curr),arr,,,-1),
XLOOKUP(1,(LEN(arr)=5)
(seq<curr),arr,,,-1),
XLOOKUP(1,(LEN(arr)=6)(seq<curr),arr,,,-1),
SUM(FILTER(arr,(seq<=curr)
(seq>XMATCH(1,(LEN(arr)>4)*(seq<curr),,-1))))
),all)))),1),4))

英文:

Try:

=LET(arr,VSTACK(TOCOL(A:A,1),&quot;Finish&quot;),n,ROWS(arr),seq,SEQUENCE(n),seqA,SEQUENCE(n-1),
WRAPROWS(DROP(REDUCE(&quot;&quot;,seqA,LAMBDA(all,curr,
LET(length,LEN(INDEX(arr,curr)),lenNext,LEN(INDEX(arr,curr+1)),IF(AND(length&lt;=4,lenNext&gt;4),VSTACK(all,
      XLOOKUP(1,(LEN(arr)=8)*(seq&lt;curr),arr,,,-1),
      XLOOKUP(1,(LEN(arr)=5)*(seq&lt;curr),arr,,,-1),
      XLOOKUP(1,(LEN(arr)=6)*(seq&lt;curr),arr,,,-1),
      SUM(FILTER(arr,(seq&lt;=curr)*(seq&gt;XMATCH(1,(LEN(arr)&gt;4)*(seq&lt;curr),,-1))))
),all)))),1),4))

将一列按多个条件分割成一个包含多个条件的表格。

答案2

得分: 1

(I would use List.Accumulate.)

let
  // Table6's A column as a list
  Source = Excel.CurrentWorkbook(){[Name="Table6"]}[Content][A],
  #"Accumulate Values" = List.Accumulate(
    Source,
    // NextRow is the row we're building
    // Rows is a list of rows we've built
    [
      NextRow = {},
      Rows = {}
    ],
    (_, v) => let
      vnum = try Number.From(v) otherwise null,
      NextRowCount = List.Count([NextRow]),
      ThisColNum = if (vnum is null) then
        // not a number so must be column A
        0
      else if vnum < 10000 then
        // Assume Qty (column D) if less than 5-digit number
        3
      else if vnum < 100000 then
        // Column B if 5-digit number
        1
      else
        // Column C
        2,
      ret = if ThisColNum = NextRowCount then
        // Append v to row we're building
        _ & [NextRow = [NextRow] & {vnum ?? v}]
      else if NextRowCount <> 4 then
        // if v isn't the next column to append to the row we're building then we should have a complete row!
        error Error.Record("Bad Values", "NextRow incomplete", [state=_, value=v])
      else if ThisColNum = 3 then
        // another quantity. Add to column D
        _ & [
          NextRow = List.FirstN([NextRow], 3) & {[NextRow]{3} + vnum}
        ]
      else
        // Commit row we've built, start building a new row
        [
          NextRow = List.FirstN([NextRow], ThisColNum) & {vnum ?? v},
          Rows = [Rows] & {[NextRow]}
        ]
      in
        ret
  ),
  // Get all the rows we've built
  Rows = if List.Count(#"Accumulate Values"[NextRow]) = 4 then
    #"Accumulate Values"[Rows] & {#"Accumulate Values"[NextRow]}
  else
    error Error.Record("Bad Values", "Last NextRow incomplete. Last value not quantity?", #"Accumulate Values"),
  Table = #table(
    type table [A=text, B=Int64.Type, C=Int64.Type, D=Int64.Type],
    Rows
  )
in
  Table
英文:

(Holy moly Tom Sharpe's answer is great! And already accepted. But since I had written this already I thought I'd contribute it.)

I would use List.Accumulate.

let
&#160; // Table6&#39;s A column as a list
&#160;&#160;Source = Excel.CurrentWorkbook(){[Name=&quot;Table6&quot;]}[Content][A],
&#160;&#160;#&quot;Accumulate Values&quot; = List.Accumulate(
&#160;&#160;&#160; Source,
&#160;&#160;&#160; // NextRow is the row we&#39;re building
&#160;&#160;&#160; // Rows is a list of rows we&#39;ve built
&#160;&#160;&#160;&#160;[
&#160;&#160;&#160;&#160;&#160; NextRow = {},
&#160;&#160;&#160;&#160;&#160;&#160;Rows = {}
&#160;&#160;&#160;&#160;],
&#160;&#160;&#160;&#160;(_, v) =&gt; let
&#160;&#160;&#160;&#160;&#160; vnum = try Number.From(v)&#160;otherwise null,
&#160;&#160;&#160;&#160;&#160;&#160;NextRowCount = List.Count([NextRow]),
&#160;&#160;&#160;&#160;&#160;&#160;ThisColNum = if (vnum is null) then
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // not a number so must be column A
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;0
&#160;&#160;&#160;&#160;&#160;&#160;else if vnum &lt; 10000 then
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Assume Qty (column D) if less than 5-digit number
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;3
&#160;&#160;&#160;&#160;&#160;&#160;else if vnum &lt; 100000 then
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Column B if 5-digit number
&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1
&#160;&#160;&#160;&#160;&#160;&#160;else
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Column C
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;2,
&#160;&#160;&#160;&#160;&#160;&#160;ret = if ThisColNum = NextRowCount then
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Append v to row we&#39;re building
&#160;&#160;&#160;&#160;&#160;&#160;&#160; _ &amp; [NextRow = [NextRow] &amp; {vnum ?? v}]
&#160;&#160;&#160;&#160;&#160;&#160;else if NextRowCount &lt;&gt; 4 then
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // if v isn&#39;t the next column to append to the row we&#39;re building then we should have a complete row!
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;error Error.Record(&quot;Bad Values&quot;, &quot;NextRow incomplete&quot;, [state=_, value=v])
&#160;&#160;&#160;&#160;&#160;&#160;else if ThisColNum = 3 then
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // another quantity. Add to column D
&#160;&#160;&#160;&#160;&#160;&#160;&#160; _ &amp; [
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NextRow = List.FirstN([NextRow], 3) &amp; {[NextRow]{3} + vnum}
&#160;&#160;&#160;&#160;&#160;&#160;&#160; ]
&#160;&#160;&#160;&#160;&#160;&#160;else
&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Commit row we&#39;ve built, start building new row
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;[
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NextRow = List.FirstN([NextRow], ThisColNum) &amp; {vnum ?? v},
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Rows = [Rows] &amp; {[NextRow]}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;]
      in
        ret
&#160;&#160;),
&#160; // Get all the rows we&#39;ve built
&#160;&#160;Rows = if List.Count(#&quot;Accumulate Values&quot;[NextRow]) = 4 then
&#160;&#160;&#160; #&quot;Accumulate Values&quot;[Rows] &amp; {#&quot;Accumulate Values&quot;[NextRow]}
&#160;&#160;else
&#160;&#160;&#160;&#160;error Error.Record(&quot;Bad Values&quot;, &quot;Last NextRow incomplete. Last value not quantity?&quot;, #&quot;Accumulate Values&quot;),
&#160;&#160;Table = #table(
&#160;&#160;&#160;&#160;type table [A=text, B=Int64.Type, C=Int64.Type, D=Int64.Type],
&#160;&#160;&#160;&#160;Rows
&#160;&#160;)
in
&#160;&#160;Table

huangapple
  • 本文由 发表于 2023年5月22日 05:05:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301916.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定