VBA EXCEL范围语法

时间:2015-05-22 20:17:50

标签: excel vba excel-vba

我不理解范围的语法。

为什么这样做:

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:A是什么意思?为什么我不能使用

Range("A" & lastRow), 0

2 个答案:

答案 0 :(得分:2)

您的语法没有任何问题,您的代码应该可以正常工作 使用MatchVlookup和其他查找函数等工作表函数的问题在于,如果找不到要搜索的值,则会引发错误。

在您的情况下,您尝试在一个单元格中搜索多个值 因此,我们假设您的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.Match而非WorksheetFunction.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
    

答案 1 :(得分:1)

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

= match(lookup_value,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