编辑:我已恢复源数据源以消除我上次屏幕截图的模糊性
我正在尝试转置电子表格数据,其中有许多行可能会复制客户名称,但每行包含不同的产品。
例如 revised original data source
到
如果可能的话,我想用公式做,因为我在与VB斗争
感谢您的帮助
答案 0 :(得分:0)
我意识到这是一个巨大的答案,道歉,但我想清楚。如果您需要我的任何内容,请给我发表评论,我会帮忙。
已编辑的答案 - 用于便于理解的命名范围:
这些只是我使用的一些命名范围的示例,您可以直接引用范围或自己命名(最简单的方法是突出显示数据,然后将名称放在公式栏旁边的下拉列表中) [左上角])
要小心,因为我们将使用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
:这是一个比Forename
或Surname
更先进的查找公式,并且不受其限制。
我使用的范围是预期的输出范围 - 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部分 是自动完成标题的技巧,以便在不使用时隐藏它们(如果您只是为自己的全部付款并粘贴价值加快再次使用)。
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),"")
来获取名称。
再一次,我们在这里进行交错输入,然后在页面上复制公式以覆盖整个数据。
C中的{{1}}
D 中的{{1}}
第3部分的公式需要作为数组输入(在公式栏中点击 Ctrl + Shift + Enter ) 。这需要在复制公式之前完成。
现在可以在所有方向上拖动/复制这些公式,并将从A列中的唯一ID中提取。
我的答案已经很长了,所以我还没有打破公式。如果您在理解其工作原理时遇到任何问题,请告诉我,我将很乐意为您编写一份快速指南,将其分解为大块。