比较 2 张不同 headers
Compare 2 sheets with different headers
我有 2 个不同的文件,它们具有不同的 header,例如:
OldfileHeaders | NewFileheaders
ID | Test ID
Date | New date
等等。我正在尝试比较两个 sheet 中的数据,看看它们是否匹配。数据行的顺序可能不同,header 的顺序也可能不同。
所以我想做的是:
1) 定义 2 个文件中哪些 headers 匹配哪些 headers
2)从旧文件中找到ID,看它是否在新文件中,如果是,则查看每个header下的数据是否匹配。如果没有,则将该行数据导出到新的 sheet 添加一列并将其标记为 "Missing".
到目前为止的代码:
Set testIdData = testIdData.Resize(testIdData.CurrentRegion.Rows.Count)
Do Until sourceId.Value = ""
datacopy = False
' Look for ID in test data
Set cellFound = testIdData.Find(What:=sourceId.Value, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
If cellFound Is Nothing Then
' This entry not found, so copy to output
datacopy = True
outputRange.Resize(ColumnSize:=NUMCOLUMNS).Interior.Color = vbRed
Else
' This assumes that columns are in same order
For columnNum = 2 To NUM_COLUMNS_DATA
' No need to test the ID column
If sourceId.Cells(ColumnIndex:=columnNum).Value <> cellFound.Cells(ColumnIndex:=columnNum).Value Then
outputRange.Cells(ColumnIndex:=columnNum).Interior.Color = vbYellow
datacopy = True
End If
Next columnNum
End If
If datacopy Then
sourceId.Resize(ColumnSize:=NUMCOLUMNS).Copy
outputRange.PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
Set outputRange = outputRange.Offset(RowOffset:=1)
difference = difference + 1
End If
Set sourceId = sourceId.Offset(RowOffset:=1)
Loop
此代码的工作取决于我以正确的顺序格式化 sheet 并更改 header 名称。
我需要帮助定义哪些字段名称与 2 sheet 中的哪些字段名称匹配,然后为每个 ID 搜索新的 sheet 并查看相应单元格中的数据是否匹配.如果 ID 不在 sheet 中,则输出该行也不同 sheet。如果 id 存在并且单元格中存在差异,则将它们丢掉 sheet。我想统计每一列的差异。
匹配数据集之间的数据需要你给程序一些帮助。在这种情况下,需要的帮助是哪些列相互关联。您已经确定了 table 如何关联 header 的一小部分。有了这个,您可以进行从数据源 1 到数据源 2 的各种翻译。它需要大量使用 Application.Match
和 Application.VLookup
。
我将提供一个基本示例,它是您尝试做的事情的核心。在一个 sheet 上看到所有内容要容易得多,这就是我所做的。
数据图片显示三个table:rng_headers、rng_source和rng_dest。第一个是 header 的查找,第二个是 "source" 数据,第三个是要比较的数据源,我将调用 destination = "dest".
代码包括以下步骤:遍历源数据中的所有 ID,检查它们是否存在于目标数据中,如果存在,检查所有单独的值平等。此代码检查每一步的 headers(这很慢)但允许数据乱序。
Sub ConfirmHeadersAndMatch()
Dim rng_headers As Range
Set rng_headers = Range("B3").CurrentRegion
Dim rng_dest As Range
Set rng_dest = Range("I2").CurrentRegion
Dim rng_source As Range
Set rng_source = Range("E2").CurrentRegion
Dim rng_id As Range 'first column, below header row
For Each rng_id In Intersect(rng_source.Columns(1).Offset(1), rng_source)
Dim str_header As Variant
str_header = Application.VLookup( _
Intersect(rng_id.EntireColumn, rng_source.Rows(1)), _
rng_headers, 2, False)
'get col number
Dim int_col_id As Integer
int_col_id = Application.Match(str_header, rng_dest.Rows(1), 0)
'find ID in the new column
Dim int_row_id As Variant
int_row_id = Application.Match(rng_id, rng_dest.Columns(int_col_id), 0)
If IsError(int_row_id) Then
'ID missing... do something
rng_id.Interior.Color = 255
Else
Dim rng_check As Range 'all values, same row
For Each rng_check In Intersect(rng_source, rng_id.EntireRow)
'get col number
str_header = Application.VLookup( _
Intersect(rng_check.EntireColumn, rng_source.Rows(1)), _
rng_headers, 2, False)
int_col_id = Application.Match(str_header, rng_dest.Rows(1), 0)
'check value
If rng_check.Value <> rng_dest.Cells(int_row_id, int_col_id).Value Then
'values did not match... do something
rng_dest.Cells(int_row_id, int_col_id).Interior.Color = 255
End If
Next rng_check
End If
Next
End Sub
代码注释
- 范围建立在
CurrentRegion
的基础上,它挑选出数据块。您可以将它们换成不同 sheets 上的不同范围。
- 第 header 列翻译完成
Application.VLookup
以检查源 header 和 return 目标 header。然后使用 Application.Match
在目标 header 行中找到此 String
。您可以将此代码抽象为 Function
以避免重复两次。
- 找到该列后,将使用
Application.Match
在目标 table 中搜索 ID。如果找不到 ID,这将 return 出错。
- 如果找到 ID,它会检查同一行中的所有其他值,将它们与目标 table 中的正确列进行比较。 Non-matching 结果为红色。
- 如果所有列都没有成对,您可以在
VLookup
或 Match
列上添加额外的检查来检查这一点。
- 此代码的绝大部分只是处理使用
Intersect
、Rows
和 Columns
. 获取数据中的正确位置
结果 为未找到的 ID 和不匹配的值显示一些红色值。
我有 2 个不同的文件,它们具有不同的 header,例如:
OldfileHeaders | NewFileheaders
ID | Test ID
Date | New date
等等。我正在尝试比较两个 sheet 中的数据,看看它们是否匹配。数据行的顺序可能不同,header 的顺序也可能不同。
所以我想做的是: 1) 定义 2 个文件中哪些 headers 匹配哪些 headers 2)从旧文件中找到ID,看它是否在新文件中,如果是,则查看每个header下的数据是否匹配。如果没有,则将该行数据导出到新的 sheet 添加一列并将其标记为 "Missing".
到目前为止的代码:
Set testIdData = testIdData.Resize(testIdData.CurrentRegion.Rows.Count)
Do Until sourceId.Value = ""
datacopy = False
' Look for ID in test data
Set cellFound = testIdData.Find(What:=sourceId.Value, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
If cellFound Is Nothing Then
' This entry not found, so copy to output
datacopy = True
outputRange.Resize(ColumnSize:=NUMCOLUMNS).Interior.Color = vbRed
Else
' This assumes that columns are in same order
For columnNum = 2 To NUM_COLUMNS_DATA
' No need to test the ID column
If sourceId.Cells(ColumnIndex:=columnNum).Value <> cellFound.Cells(ColumnIndex:=columnNum).Value Then
outputRange.Cells(ColumnIndex:=columnNum).Interior.Color = vbYellow
datacopy = True
End If
Next columnNum
End If
If datacopy Then
sourceId.Resize(ColumnSize:=NUMCOLUMNS).Copy
outputRange.PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
Set outputRange = outputRange.Offset(RowOffset:=1)
difference = difference + 1
End If
Set sourceId = sourceId.Offset(RowOffset:=1)
Loop
此代码的工作取决于我以正确的顺序格式化 sheet 并更改 header 名称。
我需要帮助定义哪些字段名称与 2 sheet 中的哪些字段名称匹配,然后为每个 ID 搜索新的 sheet 并查看相应单元格中的数据是否匹配.如果 ID 不在 sheet 中,则输出该行也不同 sheet。如果 id 存在并且单元格中存在差异,则将它们丢掉 sheet。我想统计每一列的差异。
匹配数据集之间的数据需要你给程序一些帮助。在这种情况下,需要的帮助是哪些列相互关联。您已经确定了 table 如何关联 header 的一小部分。有了这个,您可以进行从数据源 1 到数据源 2 的各种翻译。它需要大量使用 Application.Match
和 Application.VLookup
。
我将提供一个基本示例,它是您尝试做的事情的核心。在一个 sheet 上看到所有内容要容易得多,这就是我所做的。
数据图片显示三个table:rng_headers、rng_source和rng_dest。第一个是 header 的查找,第二个是 "source" 数据,第三个是要比较的数据源,我将调用 destination = "dest".
代码包括以下步骤:遍历源数据中的所有 ID,检查它们是否存在于目标数据中,如果存在,检查所有单独的值平等。此代码检查每一步的 headers(这很慢)但允许数据乱序。
Sub ConfirmHeadersAndMatch()
Dim rng_headers As Range
Set rng_headers = Range("B3").CurrentRegion
Dim rng_dest As Range
Set rng_dest = Range("I2").CurrentRegion
Dim rng_source As Range
Set rng_source = Range("E2").CurrentRegion
Dim rng_id As Range 'first column, below header row
For Each rng_id In Intersect(rng_source.Columns(1).Offset(1), rng_source)
Dim str_header As Variant
str_header = Application.VLookup( _
Intersect(rng_id.EntireColumn, rng_source.Rows(1)), _
rng_headers, 2, False)
'get col number
Dim int_col_id As Integer
int_col_id = Application.Match(str_header, rng_dest.Rows(1), 0)
'find ID in the new column
Dim int_row_id As Variant
int_row_id = Application.Match(rng_id, rng_dest.Columns(int_col_id), 0)
If IsError(int_row_id) Then
'ID missing... do something
rng_id.Interior.Color = 255
Else
Dim rng_check As Range 'all values, same row
For Each rng_check In Intersect(rng_source, rng_id.EntireRow)
'get col number
str_header = Application.VLookup( _
Intersect(rng_check.EntireColumn, rng_source.Rows(1)), _
rng_headers, 2, False)
int_col_id = Application.Match(str_header, rng_dest.Rows(1), 0)
'check value
If rng_check.Value <> rng_dest.Cells(int_row_id, int_col_id).Value Then
'values did not match... do something
rng_dest.Cells(int_row_id, int_col_id).Interior.Color = 255
End If
Next rng_check
End If
Next
End Sub
代码注释
- 范围建立在
CurrentRegion
的基础上,它挑选出数据块。您可以将它们换成不同 sheets 上的不同范围。 - 第 header 列翻译完成
Application.VLookup
以检查源 header 和 return 目标 header。然后使用Application.Match
在目标 header 行中找到此String
。您可以将此代码抽象为Function
以避免重复两次。 - 找到该列后,将使用
Application.Match
在目标 table 中搜索 ID。如果找不到 ID,这将 return 出错。 - 如果找到 ID,它会检查同一行中的所有其他值,将它们与目标 table 中的正确列进行比较。 Non-matching 结果为红色。
- 如果所有列都没有成对,您可以在
VLookup
或Match
列上添加额外的检查来检查这一点。 - 此代码的绝大部分只是处理使用
Intersect
、Rows
和Columns
. 获取数据中的正确位置
结果 为未找到的 ID 和不匹配的值显示一些红色值。