将列转换为新列并相应地维护/复制行

时间:2015-06-30 03:17:11

标签: excel excel-vba transpose vba

为尴尬的头衔道歉。我已经在论坛中搜索过但尚未找到合适的解决方案。我想我之后需要使用宏。

我有一个电子表格,按行概述交易,即每笔交易一行。每笔交易都包含预计的财务数据因此,每一行都涉及一项多年来有财务影响的交易。

例如,标题看起来像

Transaction | field1 | field 2 | etc. | 2010-11 | 2011-12 | 2012-13 | etc. |

这些年份之下是美元金额。

所有字段都包含我需要跨行复制的数据,除了我希望将转换为单个列,其中包含财务数据。

所以,如果我有记录:

exampleid | data | data | 45000 | 56000 | 223145 | data

我希望它也成为:

exampleid | data | data | 2010/11 | 45000  | data
exampleid | data | data | 2011/12 | 56000  | data
exampleid | data | data | 2012/13 | 223145 | data

大约有30列。

3 个答案:

答案 0 :(得分:1)

您不需要VBA。您可以使用/调整公布的here公式。 这篇文章的目的正是作为像这样的案例的参考。

对于每个输入行,您需要两组行 - 列,一个用于标题,一个用于数据。

在公式中使用适当的相对/绝对索引,以便能够复制/粘贴。

答案 1 :(得分:0)

这是我用来做这件事的。您可以更改子开头的变量,以指定数据的列数,透视数据的宽度,用于导入和导出的工作表名称等。

导出的数据将始终从原始数据开始的同一列开始。

数据需要让标题正常工作,并假设第一列数据中没有空白单元格。

Sub pivot_data()

data_sheet = "Sheet1" 'name of sheet containing original data
export_sheet = "Sheet2" 'name of sheet to export to

start_d_row = 2     'first row of data (headings are grabbed from row above)
start_d_col = 1     'first column of data
end_d_col = 7       'last column of data
start_t_col = 4     'first column to pivot
end_t_col = 6       'last column to pivot
xrow = 2            'first row to export DATA to (headings will be row above)
trailing_col = end_d_col - end_t_col 'calculated number of trailing columns
pivot_size = end_t_col - start_t_col + 1 'calculated size of pivot

'headings

For xcol = start_d_col To start_t_col - 1
  Worksheets(export_sheet).Cells(xrow - 1, xcol).Formula = Worksheets(data_sheet).Cells(start_d_row - 1, xcol).Value
Next xcol
  Worksheets(export_sheet).Cells(xrow - 1, xcol).Formula = "Narrative"
  Worksheets(export_sheet).Cells(xrow - 1, xcol + 1).Formula = "Value"
For xcol = start_t_col + 2 To start_t_col + 2 + trailing_col - 1
  Worksheets(export_sheet).Cells(xrow - 1, xcol).Formula = Worksheets(data_sheet).Cells(start_d_row - 1, xcol - 2 + pivot_size).Value
Next xcol


'data

For irow = 2 To Worksheets(data_sheet).Cells(start_d_row - 1, start_d_col).End(xlDown).Row

  For icol = start_t_col To end_t_col

    For xcol = start_d_col To start_t_col - 1
      Worksheets(export_sheet).Cells(xrow, xcol).Formula = Worksheets(data_sheet).Cells(irow, xcol).Value
    Next xcol

      Worksheets(export_sheet).Cells(xrow, start_t_col).Formula = Worksheets(data_sheet).Cells(1, icol).Value
      Worksheets(export_sheet).Cells(xrow, start_t_col + 1).Formula = Worksheets(data_sheet).Cells(irow, icol).Value
    If end_d_col = end_t_col Then
    Else
      For xcol = start_t_col + 2 To start_t_col + 2 + trailing_col - 1
        Worksheets(export_sheet).Cells(xrow, xcol).Formula = Worksheets(data_sheet).Cells(irow, xcol - 2 + pivot_size).Value
      Next xcol
   End If
   xrow = xrow + 1
  Next icol

Next irow


End Sub

希望有所帮助

答案 2 :(得分:0)

VBA肯定可以用来解决这个问题,但是对于常规结构化数据,例如也可以使用本机Excel。

基本问题是您希望将“输入”列表中的每条记录拆分为“输出”列表中的 n 记录。因此,如果输入列表中有 i 条记录,则输出中将包含 i * n 条记录。

我以前在英国国家统计局人口数据上做了很多这样的事情,数据以整齐格式的表格发布,显示按年龄组和地点划分的人口水平,而我希望以列表格式记录仅显示单个位置和年龄组组合中的人口。然后,列表格式通常用于Excel的数据过滤和/或数据透视表以进行分析,并偶尔导入Access。

转换数据的方法如下:

  1. 假设您的输入表中有25年的数据并且说200条输入记录,则需要生成200 * 25 = 5000条输出记录,因此首先生成一个包含5000行的2列列表。从第1行的1,1开始; {2}中1,2;第3行1,3; ......; 1,25在第25行;第26排2,1;第27排2,2; ......;第50行2,25;第51排3,1;依此类推,直到你到达第5000行的200,25。这样的列表很容易生成:假设单元格A2B2 表示第一个1,1(只需在两个单元格中键入这些值),然后B3有一个公式,如 IF(B2=25,1,1+B2)可以在其余行中复制 列B. A3还包含基于IF函数的公式,但这一次 第一个参数基于相邻单元格中的值(即B3)。准确的公式留作练习,并且应该再次向下复制A列的剩余行。
  2. 5000行对应于您的输出记录,每对值告诉您哪条输入记录(第一个值)以及该记录中的哪一年(第二个值)提供输出记录的数据。您现在可以选择使用此信息创建包含输出记录的单元格的函数。可能性包括INDEX()OFFSET()INDIRECT()函数,但后者需要与ADDRESS()函数一起使用。
  3. INDEX()可能最容易理解和应用,但其他人值得探索和理解。如果您的200个输入记录(不包括标题行)保留在Sheet1!A2:AB201中(其中cols A-C用于非年度数据,而25年的年度数据用于列{{1}输出表将显示在D-AB上(第1行是标题行,列A和B按上面步骤1中所述使用),然后Sheet2的公式将是Sheet2!C2并且可以为所有输出行和下两个(非年)输出列复制此公式(请注意使用实现此目的的混合绝对和相对寻址)。输出列表(列F)的第4列的年份值是通过从=INDEX(Sheet1!A$2:A$201,$A2)中的标题行中选择正确的值来生成的。要使用的公式是单元格Sheet1中的=INDEX(Sheet1!$D$1:$AB$1,B2)。将此公式复制到列F的剩余行中。单元格Sheet2!F2的公式使用Sheet2!G2函数的二维版本 - 但我会将其作为练习。一旦你得到了正确的公式,就应该将其复制到G列的剩余行中。
  4. 如果您已成功导航上述内容,则输出数据应位于=INDEX(),您可以在第1行输入列标题。

    对您的术语做出最后评论。您没有转置数据,而是改变了它的呈现方式。转置数据通常意味着将表的所有行转换为列,反之亦然:因此,将带有 I 行和 J 列的表转换为带有 J 行和 I 列。在您的情况下,美元值从 I 行和 J 列转换为 I * J 行和1列。