转置多次出现

时间:2017-01-10 11:40:33

标签: excel-formula transpose

编辑:我已恢复源数据源以消除我上次屏幕截图的模糊性

我正在尝试转置电子表格数据,其中有许多行可能会复制客户名称,但每行包含不同的产品。

例如 revised original data source

revised proposed data format

如果可能的话,我想用公式做,因为我在与VB斗争

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

我意识到这是一个巨大的答案,道歉,但我想清楚。如果您需要我的任何内容,请给我发表评论,我会帮忙。

这是我公式的输出: enter image description here

已编辑的答案 - 用于便于理解的命名范围:

enter image description here enter image description here enter image description here

这些只是我使用的一些命名范围的示例,您可以直接引用范围或自己命名(最简单的方法是突出显示数据,然后将名称放在公式栏旁边的下拉列表中) [左上角])

要小心,因为我们将使用AccNum和AccType的数组公式,您不希望选择整个列,而是选择确切的数据长度或超过100左右。大数组公式倾向于减慢计算速度,并且无论是否为空,都会单独计算每个单元格。

第一个公式

=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Account Number ",LEFT((COLUMN(A:A)+1)/2,1)),"")

此公式与原始答案中的公式相同,除了调整后的标题标题。

=IF(Condition,True,False) - IF逻辑有很多用途,在我看来,这是Excel中最好的公式。我已经习惯使用COUNTIF来检查是否有超过0个单元格超过BLANK(或"")。这只是使用ISBLANK()或其他空白标识符的一个技巧,当存在公式时会混淆。

如果结果为TRUE,我使用CONCATENATE(Text1,Text2,etc.)为列标题构建文本字符串。 ROW(1:1)COLUMN(A:A)通常用于根据是否需要水平或垂直计数来启动公式的自动增加整数。我将这个增加的整数加1并将其除以2,以便每列的增加为0.5(1> 1.5> 2> 2.5)然后我使用LEFT公式将第一个数字加到这个十进制答案的左边是这样,每2列只增加一次。

如果结果为FALSE,则将单元格留空,"")。标准的东西在这里,不需要解释。

第二个公式

=CONCATENATE(INDEX(Forename,MATCH(Sheet4!$A2,Reference,0))) =CONCATENATE(INDEX(Surname,MATCH(Sheet4!$A2,Reference,0)))

CONCATENATE仅用于强制空白单元格在INDEX拉动时保持空白。 INDEX会将空白单元格作为值读取,因此0会将CONCATENATE读取为"",因此INDEX(Range,Row,Column)会将其作为文本读取,因此会VLOOKUP

HLOOKUP:这是一个比ForenameSurname更先进的查找公式,并且不受其限制。

我使用的范围是预期的输出范围 - MATCH(Criteria,Range,Match Type)Reference

然后使用=IFERROR(INDEX(AccNum,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0))),"")计算行。匹配将查看范围并将位置返回到发生匹配的整数。为此,我将条件设置为该行的A列中的唯一引用号,指定范围=IFERROR(INDEX(AccType,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0))),"")的范围和匹配类型0(1小于0,精确匹配,-1大于)

我没有为INDEX定义一个列号,因为它默认为第一列,我只是给它一列数据来输出。

第三个​​公式

请记住,这些需要作为数组输入(在公式栏中点击 Ctrl + Shift + Enter

AccNum

AccType

如您所见,其中一个用于IFERROR(Value),另一个用于,"")

SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0)):使用它的原因是我们不希望公式总是返回一些东西。当公式无法返回某些内容或SMALL已用完匹配时,将发生错误(通常为#VALUE或#NUM!),因此我使用=Sheet4!$A2来强制显示空白结果(同样是标准内容)。

我已经解释了上面的INDEX公式,所以让我们深入研究如何计算出符合我们要求的行:

Reference

这里的IF语句是相当自我解释的,但是由于我们将它用作数组公式,它将执行{FALSE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE},它是指定范围IF中每个单元格的唯一引用。在模拟数据中,这将返回第一个条目的结果:FALSE(我在范围中包含标题,因此初始值为FALSE)。 SMALL(array,k)将为每个true执行行计算*,但保留SMALL s。

这会留下ROUNDDOWN(Number,digits)将使用的{FALSE; 2; FALSE; FALSE; FALSE; FALSE; FALSE; FALSE; FALSE; FALSE}}的结果。 LEFT()仅适用于数值,并会显示第k个结果。再次使用了列技巧但是为了覆盖更多的基础,我使用了另一种方法:1, 1, 2, 2, 3, 3而不是使用SMALL这里的数字意味着小数位,所以我使用0来向下舍入到整数的整数同样的结果。因为这样复制了这样的列:ROW(Reference)=IF(COUNTIF(C2:C11,">""")>0,CONCATENATE("Product ",LEFT((COLUMN(A:A)+1)/2,1)),"")将替代(当公式交替时)抓取第一个最小的AccNum然后获取第一个最小的AccType,然后再抓住第二个AccNum和Acctype,等等。 / p>

*(匹配的行号减去范围的第一行编号再加上1,再次相当常见,因为无论数据从何处开始,总是得到正确的行;实际上当您的数据从第1行开始时我们可以做=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Prod code ",LEFT((COLUMN(B:B)+1)/2,1)),"")但我离开了,因为你有不同格式的数据)

原始答案 - 与上述逻辑相同

以下是3部分的解决方案

第1部分 是自动完成标题的技巧,以便在不使用时隐藏它们(如果您只是为自己的全部付款并粘贴价值加快再次使用)。

enter image description here C中的"Product "

D

中的

"Prod code "

突出显示两个单元格并拖动以错开输出DATA > REMOVE DUPLICATES > Continue with current selection=INDEX(Sheet2!$B$1:$B$7,MATCH(Sheet4!$A2,Sheet2!$A$1:$A$7,0))

第2部分 会在新工作表中输入唯一ID,我建议您将整个A列复制到新工作表并使用=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0)),1),"")修剪掉多次出现的唯一身份证。

在B列中,使用=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0)),2),"")来获取名称。

第3部分,INDEX enter image description here enter image description here

再一次,我们在这里进行交错输入,然后在页面上复制公式以覆盖整个数据。

C中的

{{1}}

D

中的

{{1}}

第3部分的公式需要作为数组输入(在公式栏中点击 Ctrl + Shift + Enter ) 。这需要在复制公式之前完成。

现在可以在所有方向上拖动/复制这些公式,并将从A列中的唯一ID中提取。

我的答案已经很长了,所以我还没有打破公式。如果您在理解其工作原理时遇到任何问题,请告诉我,我将很乐意为您编写一份快速指南,将其分解为大块。