我在MS Excel 2007工作簿的2张单独的工作表上有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
---------------------------
两者都有相同的列,但它们可以有不同的数据。
我希望将两个表的数据垂直组合,即单个表与第三个单独表中的所有数据。 如果可能的话,我想添加另一列,其中包含行所在的工作表名称。
===================================
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
-----------------------------------
可以在不使用宏的情况下完成吗?
答案 0 :(得分:3)
您可以激活 Office剪贴板(功能区主页选项卡上剪贴板部分右下角的箭头)。复制两个范围,然后使用全部粘贴命令,如下所示。
您仍然需要首先在额外的列中填写工作表名称,但可以通过双击填充手柄来完成。
<强>更新强>
要使用公式获得相同的结果,请尝试将其填写为工作表名称:
=IF(ROW()<=COUNTA(Sheet1!A:A),"Sheet1",IF(ROW()<COUNTA(Sheet1:Sheet2!A:A),"Sheet2",""))
然后在表格中填写并填写此公式中的值:
=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),""))
答案 1 :(得分:1)
lori_m通过使用Microsoft Excel Tables和结构化引用为我做出了非常好的贡献。
首先在输出表中创建一个名为RowID的列,其中包含表中的行号,然后使用它来填充数据值。
=IF( INDIRECT("Table3[RowId]")<=ROWS(Table1)
,INDEX(Table1[column1],INDIRECT("Table3[RowId]"))
,INDEX(Table2[Column1],INDIRECT("Table3[RowId]")-ROWS(Table1)))
有一个detailed explanation of how this works on my blog因为它包含在这里太久了。
答案 2 :(得分:0)
略微修改了Jeeped的代码。
如果您碰巧使用类似的方法,但有几个表(例如超过10个),那么尝试手动添加每个表的每个名称将会相当麻烦。如果更改表的名称,这也是一个问题,因为名称在VBA中是硬连线的。为避免额外工作,请考虑以下事项:
所以,假设如下:
然后上面示例中的 Workbook_SheetChange Sub可能如下所示:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim tbl As ListObject
For Each tbl In ActiveSheet.ListObjects
If Not Intersect(Target, tbl.Range.Offset(1, 0)) Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
Call update_Table
End If
Next tbl
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
编辑。然后第二个例程如下:
Private Sub update_Table()
Dim iTBL3rws As Long, rng As Range, rngOLDBDY As Range
Dim tbl As ListObject
Dim sht As Worksheet
iTBL3rws = 0
' consider all tables, excluding master table
For Each sht In ThisWorkbook.Worksheets
For Each tbl In sht.ListObjects
If tbl.Name <> "Table3" Then
iTBL3rws = iTBL3rws + tbl.DataBodyRange.Rows.Count
End If
Next tbl
Next sht
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
此例程与先前的例程不同,它取消了预编程的案例。如果在活动工作表上注册了更改,则此工作表中即将更改的任何表将触发 update_Table 过程。
答案 3 :(得分:0)
我正在使用此代码/公式。适合我的需要只有我想知道的是我如何制作更好的细胞配方,所以我可以使用3+表作为参考。目前我只是在iferror
中嵌套了一堆iferror语句
=IFERROR(INDEX(Table1, ROW([@Date])-ROW(Table3[#Headers]),COLUMN(A:A)),IFERROR( INDEX(Table2, ROW([@Date])-ROW(Table3[#Headers])-ROWS(Table1),COLUMN(A:A)), IFERROR(INDEX(Table4, ROW([@Date])-ROW(Table3[#Headers])-ROWS(Table2)-ROWS(Table1),COLUMN(A:A)),INDEX(Table5, ROW([@Date])-ROW(Table3[#Headers])-ROWS(Table2)-ROWS(Table1)-ROWS(Table4),COLUMN(A:A)))))
&#13;
我也在使用