有条件地转置excel数据
我有一个excel文件,其中有一些特定于国家的信息。我需要以某种方式转换它,这样对于每个国家,我都可以得到按行填充的数据。例如: 来源数据:有条件地转置excel数据,excel,vba,excel-formula,Excel,Vba,Excel Formula,我有一个excel文件,其中有一些特定于国家的信息。我需要以某种方式转换它,这样对于每个国家,我都可以得到按行填充的数据。例如: 来源数据: Column A Column B Column C -----------------+---------------+------------------+ United Kingdom Data 1 Instruction 1 United Kingdom Data
Column A Column B Column C
-----------------+---------------+------------------+
United Kingdom Data 1 Instruction 1
United Kingdom Data 2 Instruction 2
United Kingdom Data 3 Instruction 3
USA Data 4 Instruction 4
USA Data 5 Instruction 5
India Data 6 Instruction 6
UAE Data 7 Instruction 7
UAE Data 8 Instruction 8
预期产量Column A Column B Column C Column D
----------------+-------------------+------------------+-------------------+
United Kingdom Data 1 Data 2 Data 3
United Kingdom Instruction 1 Instruction 2 Instruction 3
USA Data 4 Data 5
USA Instruction 4 Instruction 5
India Data 6
India Instruction 6
UAE Data 7 Data 8
UAE Instruction 7 Instruction 8
请注意,我的源表中有242个国家的数据,它们的数据元素从1到20不等
有人可以建议一个公式或宏脚本来帮助我做到这一点。我不是excel方面的专家,我在excel方面有vlookup学位,但不超过:)
希望我没有把它弄得太混乱。:) 您可以通过一系列步骤来完成,我必须使用helper列。此解决方案还要求将国家分组,如您的示例所示。要实现最后一点,只需先按国家名称对数据进行排序,这将确保数据是正确的 您看到的公式假设您的数据位于A2:A9中,第1行为空或标题行。重要的是,无论标题行中有什么信息,它都与唯一列表中的任何名称都不匹配 步骤1-国家名称的唯一列表 您可以使用“数据工具”部分中“数据”选项卡下名为“删除重复项”的内置函数,并在空列中生成列表。这是您的帮助器列 或者,您可以使用以下公式。这是一个数组公式,因此当您输入它时,您需要按CONTROL+SHIFT+enter键,而不是只按enter键。当{}出现在公式栏中的公式周围时,您就知道您做得对了。注意:不能为公式手动添加这些参数。此外,您还需要在计划开始列表的位置上方有一个空白单元格
=IFERROR(INDEX($A$2:$A$9, MATCH(0,COUNTIF($G$1:G1, $A$2:$A$9), 0)),"")
将该单元格向下复制,直到看到空单元格为止
步骤2-为输出设置国家名称
由于每个国家/地区都需要列出两次,因此从刚刚创建的唯一列表生成一个列表,但只需每隔一行向下推进列表。假设您的唯一列表是在G2:G9中生成的,您可以通过以下方式实现:
=INDEX(G:G,INT((ROW(A1)-1)/2)+ROW($G$2))
将上面的公式放在希望表格开始的位置,然后向下复制,直到看到空单元格为止
第3步-填写数据
现在您有了两行国家/地区名称列表,在最顶端条目右侧的单元格中,输入以下公式并向下和向右复制。尽可能向右边复制任何国家/地区的最大条目,因此在您的情况下,请向右复制20列。抄写到你桌子的底部
=IF(COUNTIF($A$2:$A$9,$G2)>=COLUMNS($H$2:H2),INDEX($B$2:$C$9,MATCH($G2,$A$2:$A$9,0)+COLUMNS($H$2:H2)-1,COUNTIF($G$2:G2,$G2)),"")
举个例子,如果源数据由三列组成,您可以使用Excel 2010中提供的Power Query来执行此操作+ 在Excel 2016+中,光标位于源表中:(不确定是否在早期版本中开始此操作)
数据-->从表/范围获取和转换-->数据
- 电源查询界面打开时,进入主/高级编辑器
- 用下面的M代码替换您看到的代码
- 更改第二行代码中的表名,以反映为源数据生成的表名
- 关闭并加载到新页面,或加载到同一页面上的其他位置
- 如果依次选择每个应用的步骤,则可以看到逐步进行的修改,并了解如何进行修改
let
//Replace Table Name in line below with your REAL table name
Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column A", type text}, {"Column B", type text}, {"Column C", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Column A"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
#"Added Index" = Table.AddIndexColumn(#"Removed Columns", "Index", 0, 1, Int64.Type),
#"Inserted Modulo" = Table.AddColumn(#"Added Index", "Modulo", each Number.Mod([Index], 2), type number),
#"Removed Columns1" = Table.RemoveColumns(#"Inserted Modulo",{"Index"}),
#"Grouped Rows" = Table.Group(#"Removed Columns1", {"Column A", "Modulo"}, {{"Grouped", each _, type table [Column A=nullable text, Value=text, Modulo=number]}}),
#"Removed Columns2" = Table.RemoveColumns(#"Grouped Rows",{"Modulo"}),
#"Added Custom" = Table.AddColumn(#"Removed Columns2", "D/I", each Table.Column([Grouped],"Value")),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "colCt", each List.Count([#"D/I"])),
maxCols = List.Max(#"Added Custom1"[colCt]),
#"Extracted Values" = Table.TransformColumns(#"Added Custom1",
{"D/I", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
#"Removed Columns3" = Table.RemoveColumns(#"Extracted Values",{"Grouped", "colCt"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns3", "D/I",
Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), maxCols)
in
#"Split Column by Delimiter"
这将需要VBA代码,您需要在这之前显示一些努力。无论如何,检查一下其他可能指导您编写代码的问题,例如:不使用VBA也可以完成,但在公式方面有点难看。@FoxfireAndBurnsAndBurns为什么需要VBA代码?我同意在VBA中可以做得更干净,一步到位。可以手动完成,就像Excel中的所有操作一样,但使用VBA可以更快地完成