比较工作表之间的单元格,范围不在A1上开始

时间:2017-02-28 18:38:42

标签: vba excel-vba excel

利用帖子here,我能够构建一个VBA宏来比较工作表之间的单元格以满足我的目的。但是,到目前为止,我还没有在A1范围内开始测试它。

当给出像B1:X50这样的范围时,我遇到一个问题,即纸张阵列的列尺寸的LBound是1而给定范围的开始处的列是2(B)。以下是我正在使用的代码的一部分:

'Define the range to be checked
strRangeToCheck = Summary_ws.Range("I2").Value

'Store the range to be checked on each sheet in an array
varSheetA = New_Data_ws.Range(strRangeToCheck)
varSheetB = Old_Data_ws.Range(strRangeToCheck)

'Clear current highlighted cells on data tabs
New_Data_ws.Cells.Interior.Color = xlNone
Old_Data_ws.Cells.Interior.Color = xlNone

'Initialize counter
Counter = 0
Counter_rng.Value = Counter

For iRow = LBound(varSheetA, 1) To UBound(varSheetA, 1)
    For iCol = LBound(varSheetA, 2) To UBound(varSheetA, 2)
        On Error GoTo Err_Handler
        If IsError(New_Data_ws.Cells(iRow, iCol).Value) Or IsError(Old_Data_ws.Cells(iRow, iCol).Value) Then
            Counter = Counter + 1
            Error_Flag = True
            Call Flag_Changes
        ElseIf varSheetA(iRow, iCol) = varSheetB(iRow, iCol) And _
                Len(varSheetA(iRow, iCol)) = Len(varSheetB(iRow, iCol)) Then
                'Cells are identical and lengths match
                'Do Nothing
        Else 'Cells are different
            Counter = Counter + 1 'increment counter
            Error_Flag = False
            Call Flag_Changes
        End If
    Next iCol
Next iRow

我能够评估strRangeToCheck以确定它是否从A列开始。根据该确定,是否可以手动设置工作表的LBound以匹配strRangeToCheck中的起始列?

2 个答案:

答案 0 :(得分:1)

回答问题"然后可以手动设置工作表的LBound以匹配起始列",答案是否定的。 Range.Value将始终返回一个下限为1的数组 - Excel负责创建返回的数组,并且您无法通过VBA更改该行为(即使您不愿意也不想这样做可以出于各种其他原因)。

解决方案是在将Range引入数组之前,从传递的地址中创建.Value作为中间步骤:

'Store the range to be checked on each sheet in an array
Dim newRange As Range
Dim oldRange As Range
Set newRange = New_Data_ws.Range(strRangeToCheck)
Set oldRange = Old_Data_ws.Range(strRangeToCheck)
varSheetA = newRange.Value
varSheetB = oldRange.Value

然后使用Worksheet.Cells而不是在循环中使用Range.Cells。如果您需要将其转换为工作表地址,则可以从A1中的第一个Row找到Range的偏移量。使用B1:X50的示例:

Dim example As Range
Set example = Sheet1.Range("B1:X50")
Debug.Print example.Columns(1).Column   '<-- column 2
Debug.Print example.Rows(1).Row         '<-- row 1

请注意,在上面的代码中,您只能在一行上使用工作表索引(虽然我不知道您在Call Flag_Changes中正在做什么):

If IsError(New_Data_ws.Cells(iRow, iCol).Value) Or IsError(Old_Data_ws.Cells(iRow, iCol).Value) Then

根本不需要这样做。 New_Data_ws.Cells(iRow, iCol).ValuevarSheetA(iRow, iCol)完全相同。那就是你把它拉进阵列的原因吧?只需用以下内容替换该行:

If IsError(varSheetA(iRow, iCol)) Or IsError(varSheetB(iRow, iCol)) Then

最后,您没有包含iRowiCol的声明,但是根据匈牙利符号来判断它们是否被声明为Integer您需要更改它们到Long以避免溢出错误。如果他们 声明为Long,那又是反对不使用匈牙利符号开始的另一个论点...

答案 1 :(得分:0)

我不确定这是否是实现建议的最优雅方式,但是这是工作代码,感谢共产国际:

'Store the range to be checked on each sheet in an array
Set newRange = New_Data_ws.Range(strRangeToCheck)
Set oldRange = Old_Data_ws.Range(strRangeToCheck)
varSheetA = newRange.Value
varSheetB = oldRange.Value

'Variables used to track difference between array start and given range start
row_diff = newRange.Rows(1).Row - 1
col_diff = newRange.Columns(1).Column - 1

'Loop through given range
For rngRow = newRange.Rows(1).Row To newRange.Rows.Count + row_diff
    arrRow = rngRow - row_diff 'increment row of array being evaluated
    For rngCol = newRange.Columns(1).Column To newRange.Columns.Count + col_diff
        arrCol = rngCol - col_diff 'increment column of array being evaluated
        On Error GoTo Err_Handler
        If IsError(varSheetA(arrRow, arrCol)) Or IsError(varSheetB(arrRow, arrCol)) Then
            Counter = Counter + 1
            Error_Flag = True
            Call Flag_Changes
        ElseIf varSheetA(arrRow, arrCol) = varSheetB(arrRow, arrCol) And _
                Len(varSheetA(arrRow, arrCol)) = Len(varSheetB(arrRow, arrCol)) Then
                'Cells are identical and lengths match
                'Do Nothing
        Else 'Cells are different
            Counter = Counter + 1 'increment counter
            Error_Flag = False
            Call Flag_Changes
        End If
    Next rngCol
Next rngRow

在我的Flag_Changes子目录中,我只是在突出显示两个工作表上的不同单元格,打印该单元格的地址,打印每个单元格的值以及差异(如果单元格是数字)。