在Excel中使用VBA,如何根据表1单行中的名称列中的值将表2中某些列的数据复制到表3中?
表2(原始数据,位于工作表2)
| 日期1|日期2|日期3|姓名|文本|
| - -----|- -----|- -----|- -----|- -----|
| 日期|日期|日期|默认|正文|
| 日期|日期|日期|默认|正文|
| 日期|日期|日期|默认|正文|
| 日期|日期|日期|乔恩·多伊|正文|
| 日期|日期|日期|乔恩·多伊|正文|
| 日期|日期|日期|乔恩·多伊|正文|
| 日期|日期|日期|乔恩·多伊|正文|
| 日期|日期|日期|无名氏|正文|
| 日期|日期|日期|无名氏|正文|
| 日期|日期|日期|无名氏|正文|
| 日期|日期|日期|无名氏|正文|
| 日期|日期|日期|无名氏|正文|
| 日期|日期|日期|无名氏|正文|
示例1:
表1(表1只有1行数据,位于Worksheet 1中)
| 不相关数据1|不相关数据2|不相关数据3|不相关数据4|姓名|
| - -----|- -----|- -----|- -----|- -----|
| 随机数据|其他数据|更多数据|一些数据|无名氏|
表3(所需输出,位于工作表1中,行仅为表2中的John Doe行)
| 已选定|日期1|日期2|日期3|文本|
| - -----|- -----|- -----|- -----|- -----|
| | 日期|日期|日期|正文|
| | 日期|日期|日期|正文|
| | 日期|日期|日期|正文|
| | 日期|日期|日期|正文|
示例二:
表1(表1只有1行数据,位于Worksheet 1,名称为空)
| 不相关数据1|不相关数据2|不相关数据3|不相关数据4|姓名|
| - -----|- -----|- -----|- -----|- -----|
| 随机数据|其他数据|更多数据|一些数据||
表3(所需输出,位于工作表1中,行仅为表2中的默认行)
| 已选定|日期1|日期2|日期3|文本|
| - -----|- -----|- -----|- -----|- -----|
| | 日期|日期|日期|正文|
| | 日期|日期|日期|正文|
| | 日期|日期|日期|正文|
下面的解决方案(来自VBA Copying data from one table to another and rearranging columns)几乎可以满足我的需要,除了我需要能够根据Table 1中的名称过滤Table 2中的数据,如果名称为空,则使用Table 2中的Default数据。谢谢你的帮助!
Option Explicit
Sub raw2processed()
Dim lc As Long, mc As Variant, x As Variant
Dim raw_data As Worksheet, processed_data As Worksheet
Dim raw_tbl As ListObject, processed_tbl As ListObject
Set raw_data = Worksheets("raw")
Set processed_data = Worksheets("processed")
Set raw_tbl = raw_data.ListObjects("tbl_raw")
Set processed_tbl = processed_data.ListObjects("tbl_processed")
With processed_tbl
'clear target table
On Error Resume Next
.DataBodyRange.Clear
.Resize .Range.Resize(raw_tbl.ListRows.Count + 1, .ListColumns.Count)
On Error GoTo 0
'loop through target header and collect columns from raw_tbl
For lc = 1 To .ListColumns.Count
Debug.Print .HeaderRowRange(lc)
mc = Application.Match(.HeaderRowRange(lc), raw_tbl.HeaderRowRange, 0)
If Not IsError(mc) Then
x = raw_tbl.ListColumns(mc).DataBodyRange.Value
.ListColumns(lc).DataBodyRange = x
End If
Next lc
End With
End Sub
1条答案
按热度按时间6pp0gazn1#
如果要在传输数据之前使用过滤器,则需要事先将其应用于源原点。
你可以用
Autofilter
这样做:过滤器所做的基本上是隐藏不匹配条件的行(零高度),因此当您传输数据时,您需要确保仅使用可见的行(例如
.SpecialCells(xlCellTypeVisible)
)。将所有这些放在一起将给予:
之前
之后
请注意,这将使您的源表处于过滤模式。如果有问题,你可以在最后加上
SourceTable.AutoFilter.ShowAllData
。编辑1:如果你想保留格式,你可以使用
Copy
方法,而不是只传输值,但请注意,这样会更慢。EDIT2:要处理引用名称与源表中的任何名称都不匹配的情况,可以在过滤器后添加一个检查,如果过滤后的表中不存在数据,则使用“Default”过滤器重新运行过滤器。