VBA比较变体

时间:2015-08-09 04:51:44

标签: excel vba excel-vba

我要做的是遍历变体以查看内部的所有内容是否匹配。

...但是有更快更有效的方法来比较变种吗? (我真的不需要知道里面是什么。)

如果我在字符串之间进行比较"如果string1 = string2那么......"就够了(在这种情况下会像#34;如果Var1 = Var2那么......")。

Var1 = Sheets(1).Range("A1:B10")
Var2 = Sheets(1).Range("C1:D10")


    A      B      C     D
   ABC    DEF    ABC   DEF  
   SBC    SEF    SBC   SEF  
   FBC    FEF    FBC   FEF  
   RBC    REF    RBC   REF  

数据主要是文本,大多数时候Col A和B应该等于Col C和D(在范围内指定的行数)。我需要知道的是,列A和B(在指定的行中)是否与D和C具有相同的内容。

5 个答案:

答案 0 :(得分:1)

如果您正在尝试比较评论中提及的两个范围,我建议使用rng1循环迭代第一个范围for each并使用{ {1}}查看MATCH中的每个项目是否都在rng1中,这比明确比较每对项目要快。

答案 1 :(得分:1)

您正在查看两个@ 2维数组。

这个简短的例程将尺寸(LBound functionUBound function)和值输出到VBE的立即窗口(Ctrl + G)。

Sub str_test()
    Dim v As Long, w As Long, vABs As Variant, vCDs As Variant

    With ActiveSheet
        vABs = .Range("A1:B10").Value2
        vCDs = .Range("C1:D10").Value2
        Debug.Print LBound(vABs, 1) & ":" & UBound(vABs, 1)
        Debug.Print LBound(vABs, 2) & ":" & UBound(vABs, 2)
        Debug.Print LBound(vCDs, 1) & ":" & UBound(vCDs, 1)
        Debug.Print LBound(vCDs, 2) & ":" & UBound(vCDs, 2)

        For v = LBound(vABs, 1) To UBound(vABs, 1)
            For w = LBound(vABs, 2) To UBound(vABs, 2)
                Debug.Print vABs(v, w) & " - " & vCDs(v, w)
            Next w
        Next v
    End With
End Sub

结果:

str_test
1:10
1:2
1:10
1:2
LOGG - JWSA
EGXL - SBQI
WKSL - ZITO
VUKB - MCWY
(etc, etc, blah, blah...)

你应该可以从那里进行字符串比较。

答案 2 :(得分:1)

如果您要比较两个相同形状的范围并且它们的值是数字,则可以使用(在VBA中)工作表函数SumX2MY2(A, B)。此函数计算相应条目之间差异的平方。当且仅当结果为0时,数字是相同的。这可能不是最有效的方法 - 但对于大型数组,可能胜出(由于使用Excel的计算引擎而不是解释VBA代码)。你可以使用这样的东西:

Sub test()
    Dim A As Variant, B As Variant
    A = Range("A1:B2").Value
    B = Range("C1:D2").Value
    If Application.WorksheetFunction.SumX2MY2(A, B) = 0 Then
        Debug.Print "Values the same"
    Else
        Debug.Print "Values different"
    End If   
End Sub

运行两次,当两个范围包含相同的值时运行一次,而当某些值不同时运行一次。

On Edit:如果要比较两个包含相等文本的范围,并且不想使用嵌套循环,则可以使用数组公式。选择一个单元格,说出你不打算使用的X1(隐藏它是安全的)并创建一个这样的函数:

Function SameVals(R1 As Range, R2 As Range) As Boolean
    Range("X1").FormulaArray = "= Sum(If(" & _
                               R1.Address(ReferenceStyle:=xlR1C1) & _
                               "=" & R2.Address(ReferenceStyle:=xlR1C1) & _
                               ",0,1))"
    SameVals = Range("X1").Value = 0
    Range("X1").ClearContents
End Function

如此测试:

Sub test()
    MsgBox SameVals(Range("A1:B4"), Range("C1:D4"))
End Sub

在测试用例中的数组公式

{= SUM(IF($A$1:$B$4=$C$1:$D$4,0,1)}

在X1中组装。它首先创建一个0和1的数组,表示范围不同的位置,然后对该结果求和。

与明显的嵌套for循环方法检查相等的范围相比,这有一些缺点,但如果你测试大范围的相等性和直接迭代方法的性能似乎是一个问题,你可以尝试这种方法。

答案 3 :(得分:1)

这是公式方法(没有VBA):

Using Match formula

快速突出公式差异的另一种方法:

 A       B       C       D       E           F
ABC     DEF     ABC      x      TRUE        FALSE
SBC     SEF     SBC     SEF     TRUE        TRUE
FBC     FEF     FBC     FEF     TRUE        TRUE
RBC     REF     RBC     REF     TRUE        TRUE

ABC     DEF     ABC     DEF     =A7=C7      =B7=D7
SBC     SEF     SBC     SEF     =A8=C8      =B8=D8
FBC     FEF     FBC     FEF     =A9=C9      =B9=D9
RBC     REF     RBC     REF     =A10=C10    =B10=D10

这是VBA中的匹配功能:

Option Explicit

Public Sub compareValues()
    Dim rng1 As Range, rng2 As Variant, rng3 As Variant
    Dim ws As Worksheet, result As Variant, cel As Range

    Set ws = Sheet1
    Set rng1 = ws.Range("A1:B10")
    rng2 = Application.Transpose(ws.Range("C1:C10"))
    rng3 = Application.Transpose(ws.Range("D1:D10"))

    For Each cel In rng1
        cel = Trim(cel)
        If Len(cel) > 0 Then
            result = Application.Match(cel, rng2, 0)
            If IsError(result) Then
                result = Application.Match(cel, rng3, 0)
                If IsError(result) Then cel.Interior.Color = vbYellow
            End If
        End If
    Next
End Sub

答案 4 :(得分:0)

直截了当的解决方案(我首先想到的)。运行时间约为0.12毫秒:

oRange1 = Range("A1:B10")
oRange2 = Range("C1:D10")

For i = 1 To 10
    For j = 1 To 2
        If oRange1(i, j) <> oRange2(i, j) Then MsgBox "Not equal.": Exit For
    Next j
Next i