VBA比较变体
我要做的是遍历变量,看看里面的所有内容是否匹配 …但是有没有一种更快更有效的方法来比较变体?我真的不需要知道里面是什么 如果我在比较字符串,如果string1=string2,那么。。。就够了。在这种情况下,如果Var1=Var2,那么VBA比较变体,vba,excel,Vba,Excel,我要做的是遍历变量,看看里面的所有内容是否匹配 …但是有没有一种更快更有效的方法来比较变体?我真的不需要知道里面是什么 如果我在比较字符串,如果string1=string2,那么。。。就够了。在这种情况下,如果Var1=Var2,那么 Var1 = Sheets(1).Range("A1:B10") Var2 = Sheets(1).Range("C1:D10") A B C D ABC DEF ABC DEF SBC
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
数据将主要是文本,并且在范围内的指定行数中,大多数情况下,列A和B应等于列C和D。我需要知道的是,指定行中的A列和B列的内容是否与D列和C列的内容相同。如果您试图比较您在评论中提到的两个范围,我建议使用A for each循环迭代第一个范围rng1,并使用MATCH查看rng1中的每个项目是否在rng2中,这将比显式比较每对更快。如果您试图比较您在评论中提到的两个范围,我建议使用for-each循环在第一个范围rng1上迭代,并使用MATCH查看rng1中的每个项目是否都在rng2中,这将比显式比较每一对更快。您看到的是两个@2维数组 这个简短的例程向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维数组 这个简短的例程向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...)
您应该能够从那里进行字符串比较。如果您试图比较两个形状相同的范围,并且它们的值是数字,您可以在VBA中使用工作表函数SumX2MY2A,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
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
运行两次,当两个范围包含相同的值时运行一次,当某些值不同时运行一次
编辑时:如果要比较包含相等文本的两个范围,并且不希望使用嵌套循环,则可以使用数组公式。选择一个单元格,例如X1,为了安全起见,您不打算使用它来隐藏它,并创建如下函数:
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
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循环方法相比,这有缺点,但是,如果您正在测试大范围的相等性和直接迭代方法的性能,那么您可以尝试使用此方法。如果您试图比较两个形状相同的范围,并且它们的值是数字,则可以在VBA中使用工作表函数SumX2MY2A,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
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
运行两次,当两个范围包含相同的值时运行一次,当某些值不同时运行一次
编辑时:如果要比较包含相等文本的两个范围,并且不希望使用嵌套循环,则可以使用数组公式。选择一个单元格,例如X1,为了安全起见,您不打算使用它来隐藏它,并创建如下函数:
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
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循环方法相比,这有缺点,但如果您正在测试大范围是否相等,那么直接迭代方法的性能似乎是一个问题,您可以尝试使用此方法。以下是不带VBA的公式方法: 快速突出显示公式差异的另一种方法:
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
以下是不带VBA的公式方法: 快速突出显示公式差异的另一种方法:
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
我首先想到的直截了当的解决办法。运行时间约为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
我首先想到的直截了当的解决办法。运行时间约为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
你能提供你的代码吗?我还没有编码。现在我只有两个变量的值为f
rom 2范围[Var1=Sheets1.RangeA1:B10:Var2=Sheets1.RangeC1:D10]您应该指定正在进行的比较类型,以及这些范围中可能存在的输入类型。你在寻找他们之间的身份吗?i、 e.var1与var2具有相同的值,并且它们的顺序相同,是否查找两者具有相同的值,但顺序不同?它可以改变你推断答案的速度,因此你似乎需要有完全相同的值,即A1需要等于C1等。这样你就无法避免显式比较,你必须按照Jeeped的建议迭代整个过程,否则你可能会得到假阳性,虽然我会在比较中出现错误的情况下添加一个中断,但是这样一来,一旦你知道它不好,你就不需要继续检查了。是的,我所需要的只是知道A1:B10范围内的文本是否与C1:D10范围内的文本相同。你能提供你的代码吗?我还没有编码它。现在,我有两个变量,它们的值来自两个范围[Var1=Sheets1.RangeA1:B10:Var2=Sheets1.RangeC1:D10],您应该指定正在进行的比较类型,以及这些范围中可能存在的输入类型。你在寻找他们之间的身份吗?i、 e.var1与var2具有相同的值,并且它们的顺序相同,是否查找两者具有相同的值,但顺序不同?它可以改变你推断答案的速度,因此你似乎需要有完全相同的值,即A1需要等于C1等。这样你就无法避免显式比较,你必须按照Jeeped的建议迭代整个过程,否则你可能会得到假阳性,虽然我会在比较中出现错误的情况下添加一个中断,但是这样一来,一旦你知道它不好,你就不需要继续检查了。是的,我所需要的只是知道A1:B10范围内的文本是否与C1:D10范围内的文本相同。有趣的是。这比我希望的要复杂得多,甚至比迭代更复杂,但它看起来确实很整洁!我将尝试更好地理解它实际上在做什么,或者更确切地说,它是如何做的。非常感谢。有趣的这比我希望的要复杂得多,甚至比迭代更复杂,但它看起来确实很整洁!我将尝试更好地理解它实际上在做什么,或者更确切地说,它是如何做的。非常感谢。事实上,这会更快。我没有考虑过使用公式,但它们可能是最好的。match也适用于VBA,而不仅仅适用于excel中的forumlas,因此如果它是更大宏的一部分,这不是问题x=worksheetfunction.Matcharg1、arg2、Arg3确实会更快。我没有想过使用公式,但它们可能是最好的。match也适用于VBA,而不仅仅适用于excel中的forumlas,因此如果它是更大宏的一部分,这不是问题x=worksheetfunction.Matcharg1、arg2、Arg3该范围将主要包含文本。。。但我认为变体上的某些匹配函数可能会起到作用。@jony我添加了第二种方法,该方法适用于文本,尽管我怀疑它是否真的比直接的迭代方法好。范围将主要包含文本。。。但我认为变量上的某些匹配函数可能会起到作用。@jony我添加了第二种方法,该方法适用于文本,尽管我怀疑它是否真的比直接的迭代方法好。我对公式的经验比VBA的经验要少,但是如果Range1包含与Range2相同的精确文本,是否有一个公式可以返回单个真/假值?这将迅速而容易地解决它。就像一个匹配中的一个匹配?我对公式比VBA更缺乏经验,但是如果Range1包含与Range2相同的精确文本,是否有一个公式可以返回单个真/假值?这将迅速而容易地解决它。像火柴里面的火柴?