将2个Excel表组合成一个附加数据的表吗?

anu*_*nuj 10 excel append

我在2个单独的MS Excel 2007工作簿表上有2个表,如下所示:

===========================
no.   f_name     l_name  
===========================
13   Little     Timmy
1   John       Doe
17   Baby       Jessica
---------------------------


===========================
no.   f_name     l_name  
===========================
1   john       Tim
16   kyle       joe
14   Baby       katy
22   qbcd       wsde
---------------------------
Run Code Online (Sandbox Code Playgroud)

两者都具有相同的列,但它们可以具有不同的数据.

我想垂直地组合两个表的数据,即单个表与第三个单独的表中的所有数据.如果可能的话,我想添加另一列,其中包含行所在的工作表名称.

===================================
SheetName   no.   f_name     l_name  
===================================
Sheet1      13   Little     Timmy
Sheet1      1   John       Doe
Sheet1      17   Baby       Jessica
Sheet2      1   john       Tim
Sheet2      16   kyle       joe
Sheet2      14   Baby       katy
Sheet2      22   qbcd       wsde
-----------------------------------
Run Code Online (Sandbox Code Playgroud)

可以不使用宏来完成吗?

小智 9

此答案处理由Excel解释的结构化表格.虽然这些方法可以很容易地转换为原始数据矩阵而没有分配表结构,但是该解决方案的公式和VBA编码将针对真正的结构化表.

前言

第三个表可以使用一些本机工作表公式来维护两个表的组合数据,但是当向依赖表添加或删除行时,保持第三个表的大小正确将需要手动调整大小操作或一些跟踪这些更改并符合的VBA第三个表适合.我已经包含了在这个答案的最后添加源表的工作表名称以及一些表维护VBA代码的选项.

如果您只想要一个没有所有解释的操作示例工作簿,请跳到本答案的末尾,以获取用于创建此过程的工作簿的链接.

样本数据表

    表集合示例数据

我已经使用OP的示例数据来构造两个表(默认情况下)Table1和Table2分别在工作表Sheet1和Sheet2上.我故意从每个工作表的A1单元格中不同程度地抵消它们,以证明结构化表格能够将公式中的自身或另一个结构化表格作为单独的实体进行处理,而不管它在父工作表上的位置如何.第三个表格将以类似的方式构建.这些补偿仅用于演示目的; 他们不是必需的.

第1步:构建第三个表

构建第三个表的标题,然后选择未来的标题行以及它下面的至少一行,以基于"插入"►"表"►"表格"命令.

        结合表新表

Sheet3工作表上新的空第三个表应类似于以下内容.

    收集表数据构建新表

第2步:填充第三个表

首先填充第三个表的DataBodyRange中的第一个单元格.在这个例子中,那将是Sheet3!C6.在C6中键入或粘贴以下公式,请记住它基于默认表名.如果您更改了表名,请相应地进行调整.

=IFERROR(INDEX(Table1, ROW([@[no.]])-ROW(Table3[#Headers]),COLUMN(A:A)), INDEX(Table2, ROW([@[no.]])-ROW(Table3[#Headers])-ROWS(Table1),COLUMN(A:A)))
Run Code Online (Sandbox Code Playgroud)

INDEX函数首先检索每个可用行表1.实际的行号是通过引用结构化表的定义部分的ROW函数和一些小数学得出的.当表1用完的行,检索被传递到第二INDEX函数参照表2IFERROR函数和其顺序的行与所述行和检索ROWS功能使用更多的数学.该COLUMN函数用作COLUMN(A:A)这是会检索参考表的第一列,无论它是在工作表上.当公式填充正确时,这将进入第二,第三等列.

说到填充权,请将公式填入E6.你应该有一些近似以下的东西.

    聚合表数据,第三个表

步骤2.5:[可选]添加源表的父工作表名称

在右下角抓取Table3的大小调整手柄(由下面示例图像中的橙色箭头指示),然后将其向右拖动一列以向表中添加新列.将标头标签重命名为比默认标签更合适的标签.我使用Sheet作为列标签.

        整理表数据 - 源工作表名称

虽然您无法直接检索源表的工作表名称,但CELL函数可以检索已保存工作簿中任何单元格的完全限定路径,文件名和工作表作为其可选info_types之一.

将以下公式放入您刚刚创建的新列的第一行中的Table3的空单元格中.

=TRIM(RIGHT(SUBSTITUTE(CELL("filename", IF((ROW([@[no.]])-ROW(Table3[#Headers]))>ROWS(Table1), Table2, Table1)), CHAR(93), REPT(CHAR(32), 999)), 255))
Run Code Online (Sandbox Code Playgroud)

编译填充表3

如果您不打算使用某个VBA完成这个小项目,以便在从两个源表中的任何一个添加或删除行时维护Table3的维度,那么只需抓住Table3的调整大小句柄并向下拖动,直到您累积了来自两个表的所有数据.有关预期结果的示例图像,请参阅本答案的底部.

如果您计划添加一些VBA,请跳过Table3的完整填充,然后继续下一步.

步骤3:添加一些VBA以维护第三个表

通过更改工作表数据触发的流程的完全自动化最好由工作表的Worksheet_Change事件宏处理.由于涉及三个表,每个表都在自己的工作表上,因此Workbook_SheetChange事件宏是处理来自多个工作表的更改事件的更好方法.

Alt+ 打开VBE F11.打开后,查找左上角的Project Explorer.如果看不到,请点按Ctrl+ R打开它.找到ThisWorkbook并右键单击,然后选择"查看代码"(或只需双击"ThisWorkbook").

        从多个表中收集数据

将以下内容粘贴到标题为Book1 - ThisWorkbook(Code)之类的新窗格中.

Option Explicit

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    Select Case Sh.Name
        Case Sheet1.Name
            If Not Intersect(Target, Sheet1.ListObjects("Table1").Range.Offset(1, 0)) Is Nothing Then
                On Error GoTo bm_Safe_Exit
                Application.EnableEvents = False
                Call update_Table3
            End If
        Case Sheet2.Name
            If Not Intersect(Target, Sheet2.ListObjects("Table2").Range.Offset(1, 0)) Is Nothing Then
                On Error GoTo bm_Safe_Exit
                Application.EnableEvents = False
                Call update_Table3
            End If
    End Select

bm_Safe_Exit:
    Application.EnableEvents = True
End Sub

Private Sub update_Table3()
    Dim iTBL3rws As Long, rng As Range, rngOLDBDY As Range
    iTBL3rws = Sheet1.ListObjects("Table1").DataBodyRange.Rows.Count
    iTBL3rws = iTBL3rws + Sheet2.ListObjects("Table2").DataBodyRange.Rows.Count
    iTBL3rws = iTBL3rws + Sheet3.ListObjects("Table3").DataBodyRange.Cells(1, 1).Row - _
                          Sheet3.ListObjects("Table3").Range.Cells(1, 1).Row
    With Sheet3.ListObjects("Table3")
        Set rngOLDBDY = .DataBodyRange
        .Resize .Range.Cells(1, 1).Resize(iTBL3rws, .DataBodyRange.Columns.Count)
        If rngOLDBDY.Rows.Count > .DataBodyRange.Rows.Count Then
            For Each rng In rngOLDBDY
                If Intersect(rng, .DataBodyRange) Is Nothing Then
                    rng.Clear
                End If
            Next rng
        End If
    End With
End Sub
Run Code Online (Sandbox Code Playgroud)

这两个例程广泛使用Worksheet .CodeName属性.工作表的CodeNameSheet1,Sheet2,Sheet3等,并且在重命名工作表时不会更改.实际上,即使是更高级的用户也很少改变它们.它们已被使用,因此您无需修改​​代码即可重命名工作表.但是,他们现在应该指向正确的工作表.如果表和工作表与给定的不同,请修改代码.您可以在上面图像中显示VBE的Project Explorer 的工作表.Name属性旁边的括号中看到单个工作表的代号.

点按Alt+ Q返回工作表.剩下的就是通过选择Table1Table2中的任何单元格并假装通过点击然后修改它来完成填充Table3.您的结果应类似于以下内容.F2Enter↵

    自动将两个表合并为一个表

如果您一直跟着到这里,那么您应该有一个非常全面的收集表,它积极地组合来自两个源'子'表的数据.如果您同时添加了VBA,则几乎不存在第三个收集表的维护.

重命名表格

如果您选择重命名三个表中的任何一个或全部,则工作表公式将立即自动反映更改.如果您选择包含Workbook_SheetChange和随附的帮助程序子程序,则必须返回ThisWorkbook代码表并使用"查找和替换"进行适当的更改.

示例工作簿

我已经从我的公共DropBox中提供了完全可操作的示例工作簿.

Table_Collection_w_Sheetname.xlsb


¹ 细胞功能只能检索保存工作簿的工作表名称.如果尚未保存工作簿,则它没有文件名,并且CELL函数在询问文件名时将返回空字符串.


lor*_*i_m 4

您可以激活Office 剪贴板(功能区主页选项卡上剪贴板部分右下角的箭头)。复制这两个范围,然后使用“全部粘贴”命令,如下所示。

您仍然需要先在额外的列中填写工作表名称,但这可以通过双击填充柄来完成。

在此输入图像描述

更新

要使用公式获得相同的结果,请尝试填写工作表名称:

=IF(ROW()<=COUNTA(Sheet1!A:A),"Sheet1",IF(ROW()<COUNTA(Sheet1:Sheet2!A:A),"Sheet2",""))
Run Code Online (Sandbox Code Playgroud)

然后向下填写此公式以获取表中的值:

=IF(ROW()<=COUNTA(Sheet1!A:A),Sheet1!A2,IF(ROW()<COUNTA(Sheet1:Sheet2!A:A),INDEX(Sheet2!A:A,ROW()-COUNTA(Sheet1!A:A)+1),""))
Run Code Online (Sandbox Code Playgroud)