2015-05-22 64 views
1

我不明白范围的语法。VBA EXCEL范围语法

为什么这个工作:

For i = 1 To 10 
    Range("A" & i & ":D" & i).Copy 
Next 

但是,这并不工作:

For i = 2 To lastRow 
    num = WorksheetFunction.Match(Cells(i, 1), Range("A" & lastRow), 0) 
Next  

为什么我需要使用

For i = 2 To lastRow 
    'num = WorksheetFunction.Match(Cells(i, 1), Range("A1:A" & lastRow), 0) 
Next 

什么A1:的平均?为什么我不能使用

+0

你指定的起点和“A1:A”不是你正在使用的,而是“A1:A3”来表示一个范围 - 单个单元格范围可以只是“A1:A1”等。 –

+0

OK,对于第二行是有意义的,但首先的语法看起来很奇怪。 – equalizer

+0

我继续并发布了一个试图更详细地解释这个问题的答案。希望这将有助于:) –

回答

2

没有什么不对您的语法你的代码应该工作得很好。
使用工作表函数如Match,Vlookup和其他查找函数的问题是,如果找不到值被搜索,它会引发错误。

就你而言,你试图在一个单元中搜索多个值。
因此,让我们说你的lastrow是9.你的代码将从Cell(2,1)循环到Cell(9,1)检查它是否在Range("A" & lastrow)Range("A9")

如果值从Cell(2,1)通过Cell(9,1)相同的价值Range("A9"),你不会得到一个错误。

现在,如果您使用Range("A1:A" & lastrow),它肯定会奏效,因为您试图将该范围的每个元素都与自己匹配,并且肯定会找到匹配项。

WorksheetFunction.Match(Cells(2,1), Range("A1:A9")) 'will return 2 
WorksheetFunction.Match(Cells(3,1), Range("A1:A9")) 'will return 3 
' 
' 
'And so on if all elements are unique 

如果使用Range("A9")Range("A1:A9")没关系。
重要的是,如果您没有找到匹配,您将处理错误。
一种方法是使用On Error Resume NextOn Error Goto 0这样的:

Sub ject() 
    Dim num As Variant 
    Dim i As Long, lastrow As Long: lastrow = 9 

    For i = 2 To lastrow 
     On Error Resume Next 
     num = WorksheetFunction.Match(Cells(i, 1), Range("A" & lastrow), 0) 
     If Err.Number <> 0 Then num = "Not Found" 
     On Error GoTo 0 
     Debug.Print num 
    Next 
End Sub 

另一种方法是使用Application.MatchWorksheetFunction.Match这样的:

Sub ject() 
    Dim num As Variant 
    Dim i As Long, lastrow As Long: lastrow = 9 

    For i = 2 To lastrow 
     num = Application.Match(Cells(i, 1), Range("A" & lastrow), 0) 
     Debug.Print num 
     'If Not IsError(num) Then Debug.Print num Else Debug.Print "Not Found" 
    Next 
End Sub 

Application.Match工作方式相同,但它并不会报错了当它返回#N/A。因此,您可以将其值分配给Variant变量,并稍后在代码中使用,而不会有任何问题。更好的是,使用IsError测试来检查在注释行中是否找不到如上所示的值。

在上述两种情况下,我使用了Variant类型num变量。
主要原因是如果没有找到匹配的情况下,它可以处理任何其他值。

至于范围语法,不要混淆,它很简单。
请参考下面的例子。

  1. 单细胞 - 都指A1

    Cells(1,1) ' Using Cell property where you indicate row and column 
    Cells(1) ' Using cell property but using just the cell index 
    Range("A1") ' Omits the optional [Cell2] argument 
    

    不要使用细胞指数相混淆。这就像你从左到右,从上到下编号所有单元格一样。 enter image description here

    Cells(16385) ' refer to A2 
    
  2. 连续单元的范围 - 所有参考A1:A10

    Range("A1:A10") ' Classic 
    Range("A1", "A10") ' or below 
    Range(Cells(1, 1), Cells(10, 1)) 
    

    以上使用相同的语法Range(Cell1,[Cell2])其中所述第一个,省略了optional参数[Cell2]。正因为如此,以下也适用:

    Range("A1:A5","A6:A10") 
    Range("A1", "A8:A10") 
    Range("A1:A2", "A10") 
    
  3. 非连续的单元格 - 都指A1,A3,A5,A7,A9

    Range("A1,A3,A5,A7,A9") ' Classic 
    
+0

我明显站得更正。我没有意识到我的Excel VBA很生疏。删除了恶意答案。 –

+1

谢谢!范围(“A1”,“A”和lastRow),0)用lastrow = 9查找范围(A1到A9)。比范围(“A1:A”和lastRow)更容易阅读,0) – equalizer

+0

L42,非常全面的答案,比我期待的要多得多。希望这会帮助其他人。 – equalizer

1

没有关于错误的任何具体细节,我假设Match不会返回您期望的值,而是#N/A错误。匹配的语法是

=匹配(Lookup_Array中,lookup_range,MATCH_TYPE)

的lookup_range通常由几个范围单元中的,或者是具有若干行或列与多个列的行。

在您的公式中,lookup_range中只有一个单元格。比方说,LASTROW是10环的前三个运行生成式

=Match(A2,A10,0) 
=Match(A3,A10,0) 
=Match(A4,A10,0) 

这是一个有效的公式,但在大多数情况下,结果将不会是一个比赛,但一个错误。尽管你可能想要的是

=Match(A2,A1:A10,0) 

你的代码再来看,缝合在一起,并找出为什么你需要A1:A作为一个字符串公式中恒:

For i = 2 To lastRow 
    num = WorksheetFunction.Match(Cells(i, 1), Range("A1:A" & lastRow), 0) 
Next 
+0

num = WorksheetFunction.Match(Cells(i,1),Range(“A”&lastRow),0) 给出运行时错误1004.无法获取Worksheet函数类的匹配属性。你是对的,我正在寻找A1:A10,只是不明白语法 – equalizer