Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确调用vba函数_Vba_Excel - Fatal编程技术网

如何正确调用vba函数

如何正确调用vba函数,vba,excel,Vba,Excel,我是vba新手,但我正在尝试创建一个函数,动态查找整个工作表的范围,以便在其他宏中用于数据清理 以下是函数: Public Function FindRange(Rw As Long, CL As Long) Dim Rw As Long Dim CL As Long CL = ActiveSheet.Cells.Find(What:="*", _ After:=Range("A1"), _ LookAt:=xlPart, _

我是vba新手,但我正在尝试创建一个函数,动态查找整个工作表的范围,以便在其他宏中用于数据清理

以下是函数:

Public Function FindRange(Rw As Long, CL As Long)
Dim Rw As Long
Dim CL As Long

CL = ActiveSheet.Cells.Find(What:="*", _
                After:=Range("A1"), _
                LookAt:=xlPart, _
                LookIn:=xlFormulas, _
                SearchOrder:=xlByColumns, _
                SearchDirection:=xlPrevious, _
                MatchCase:=False).Column

Rw = ActiveSheet.Cells.Find(What:="*", _
                After:=Range("A1"), _
                LookAt:=xlPart, _
                LookIn:=xlFormulas, _
                SearchOrder:=xlByRows, _
                SearchDirection:=xlPrevious, _
                MatchCase:=False).Row
End Function
以下是我试图称之为:

Sub Range_Find_Method()


Call FindRange(Rw, CL)
ActiveSheet.Range("A1", Cells(Rw, CL)).Select



End Sub

我一直发现ByRef参数类型不匹配。

您不应该调用函数,应该将其返回值赋给调用子/函数中的变量。您还应该为函数指定一个返回类型,例如

Public Function GetUsedRange() As Range
    Set GetUsedRange = ActiveSheet.UsedRange
End Function
另外,正如上面的代码所示,您不能使用

ActiveSheet.UsedRange
找到使用的单元格范围

我编写的函数本质上是冗余的,因为您可以使用

 Dim MyUsedRange As Range
 Set MyUsedRange = ActiveSheet.UsedRange

在这种情况下,您甚至不需要将结果分配给变量,除非所使用的范围在代码运行过程中发生变化。

您不应该调用函数,应该将其返回值分配给调用子/函数中的变量。您还应该为函数指定一个返回类型,例如

Public Function GetUsedRange() As Range
    Set GetUsedRange = ActiveSheet.UsedRange
End Function
另外,正如上面的代码所示,您不能使用

ActiveSheet.UsedRange
找到使用的单元格范围

我编写的函数本质上是冗余的,因为您可以使用

 Dim MyUsedRange As Range
 Set MyUsedRange = ActiveSheet.UsedRange
在这种情况下,您甚至不需要将结果分配给变量,除非所使用的范围在代码运行过程中发生变化。

请考虑:

Public Function FindRange()
    Dim Rw As Long
    Dim CL As Long

    CL = ActiveSheet.Cells.Find(What:="*", _
                    After:=Range("A1"), _
                    LookAt:=xlPart, _
                    LookIn:=xlFormulas, _
                    SearchOrder:=xlByColumns, _
                    SearchDirection:=xlPrevious, _
                    MatchCase:=False).Column

    Rw = ActiveSheet.Cells.Find(What:="*", _
                    After:=Range("A1"), _
                    LookAt:=xlPart, _
                    LookIn:=xlFormulas, _
                    SearchOrder:=xlByRows, _
                    SearchDirection:=xlPrevious, _
                    MatchCase:=False).Row
    Dim arr(1 To 2) As Long
    arr(1) = CL
    arr(2) = Rw
    FindRange = arr
End Function

Sub MAIN()
    Dim coor() As Long
    coor = FindRange()
    ActiveSheet.Range("A1", Cells(coor(2), coor(1))).Select
End Sub
考虑一下:

Public Function FindRange()
    Dim Rw As Long
    Dim CL As Long

    CL = ActiveSheet.Cells.Find(What:="*", _
                    After:=Range("A1"), _
                    LookAt:=xlPart, _
                    LookIn:=xlFormulas, _
                    SearchOrder:=xlByColumns, _
                    SearchDirection:=xlPrevious, _
                    MatchCase:=False).Column

    Rw = ActiveSheet.Cells.Find(What:="*", _
                    After:=Range("A1"), _
                    LookAt:=xlPart, _
                    LookIn:=xlFormulas, _
                    SearchOrder:=xlByRows, _
                    SearchDirection:=xlPrevious, _
                    MatchCase:=False).Row
    Dim arr(1 To 2) As Long
    arr(1) = CL
    arr(2) = Rw
    FindRange = arr
End Function

Sub MAIN()
    Dim coor() As Long
    coor = FindRange()
    ActiveSheet.Range("A1", Cells(coor(2), coor(1))).Select
End Sub

甚至不应该编译,
Rw
CL
局部变量在这里是重复的声明:

将这两个参数都删除,您的代码应按预期工作,即分配
ByRef
参数
Rw
CL
。。。它可以使用更具描述性的名称和显式的
ByRef
修饰符(如果未指定,则为隐式)

另外,正如其他人所暗示的,函数应该返回一个值。您可以通过在函数的签名中指定返回类型来实现这一点

Public Function FindRange(ByVal inRow As Long, ByVal inColumn As Long) As Range
…然后在函数体中指定函数的标识符:

    Set FindRange = result ' where result is a Range object reference
使用
ByRef
参数作为返回值是可行的,但当过程是
函数时,会产生相当混乱的API。将其作为
子过程将消除关于返回值可能是什么的模糊性,再次命名有助于使意图更清楚:

Public Sub FindRange(ByRef outRow As Long, ByRef outColumn As Long)
您正在进行的
Range.Find
方法调用假定将找到一个单元格,并且如果针对空工作表调用,则会因运行时错误91而崩溃从不假定
范围。查找
将返回有效的对象引用-将其结果存储在
范围
对象引用中,并验证它是否为

Dim result As Range
Set result = ActiveSheet.Cells.Find(What:="*", _
                                    After:=Range("A1"), _
                                    LookAt:=xlPart, _
                                    LookIn:=xlFormulas, _
                                    SearchOrder:=xlByColumns, _
                                    SearchDirection:=xlPrevious, _
                                    MatchCase:=False)
If Not result Is Nothing Then
    outRow = result.Row
    outColumn = result.Column
End If
作为奖励,您可以避免两次打同一个电话。但是,再考虑一下,只返回<代码>结果范围代替:

Set FindRange = result
最后,寻找一种实际可靠的方法来检索工作表上的最后一行/列
UsedRange
会说谎;这个答案还列出了各种方法,以及为什么不使用它们

甚至不应该编译,
Rw
CL
局部变量在这里是重复的声明:

将这两个参数都删除,您的代码应按预期工作,即分配
ByRef
参数
Rw
CL
。。。它可以使用更具描述性的名称和显式的
ByRef
修饰符(如果未指定,则为隐式)

另外,正如其他人所暗示的,函数应该返回一个值。您可以通过在函数的签名中指定返回类型来实现这一点

Public Function FindRange(ByVal inRow As Long, ByVal inColumn As Long) As Range
…然后在函数体中指定函数的标识符:

    Set FindRange = result ' where result is a Range object reference
使用
ByRef
参数作为返回值是可行的,但当过程是
函数时,会产生相当混乱的API。将其作为
子过程将消除关于返回值可能是什么的模糊性,再次命名有助于使意图更清楚:

Public Sub FindRange(ByRef outRow As Long, ByRef outColumn As Long)
您正在进行的
Range.Find
方法调用假定将找到一个单元格,并且如果针对空工作表调用,则会因运行时错误91而崩溃从不假定
范围。查找
将返回有效的对象引用-将其结果存储在
范围
对象引用中,并验证它是否为

Dim result As Range
Set result = ActiveSheet.Cells.Find(What:="*", _
                                    After:=Range("A1"), _
                                    LookAt:=xlPart, _
                                    LookIn:=xlFormulas, _
                                    SearchOrder:=xlByColumns, _
                                    SearchDirection:=xlPrevious, _
                                    MatchCase:=False)
If Not result Is Nothing Then
    outRow = result.Row
    outColumn = result.Column
End If
作为奖励,您可以避免两次打同一个电话。但是,再考虑一下,只返回<代码>结果范围代替:

Set FindRange = result
最后,寻找一种实际可靠的方法来检索工作表上的最后一行/列
UsedRange
会说谎;这个答案还列出了各种方法,以及为什么不使用它们

  • 设置找到的对象的范围
  • 将父工作表作为参数传入。Activesheet不应该在通用函数中使用,在任何情况下,您都将很快停止使用它
  • 不要重复你的论点
  • 由于只将新值byRef赋给参数,而不从函数返回值,因此这也可能是一个子过程
  • 把你的主灯调暗。使用选项显式
  • 这是根据上面的笔记改写的

    Public sub FindRange(ws as worksheet, byref Rw As Long, byref CL As Long)
        with ws
            CL = .Cells.Find(What:="*", _
                             After:=.cells(1), _
                             LookAt:=xlPart, _
                             LookIn:=xlFormulas, _
                             SearchOrder:=xlByColumns, _
                             SearchDirection:=xlPrevious, _
                             MatchCase:=False).Column
    
            Rw = .Cells.Find(What:="*", _
                             After:=.cells(1), _
                             LookAt:=xlPart, _
                             LookIn:=xlFormulas, _
                             SearchOrder:=xlByRows, _
                             SearchDirection:=xlPrevious, _
                             MatchCase:=False).Row
        end with
    End sub
    
    Sub Range_Find_Method()
    
        Dim Rw As Long
        Dim CL As Long
    
        FindRange ActiveSheet, Rw, CL
        ActiveSheet.Range("A1", ActiveSheet.Cells(Rw, CL)).Select
    
    End Sub
    

  • 设置找到的对象的范围
  • 将父工作表作为参数传入。Activesheet不应该在通用函数中使用,在任何情况下,您都将很快停止使用它
  • 不要重复你的论点
  • 由于只将新值byRef赋给参数,而不从函数返回值,因此这也可能是一个子过程
  • 把你的主灯调暗。使用选项显式
  • 这是根据上面的笔记改写的

    Public sub FindRange(ws as worksheet, byref Rw As Long, byref CL As Long)
        with ws
            CL = .Cells.Find(What:="*", _
                             After:=.cells(1), _
                             LookAt:=xlPart, _
                             LookIn:=xlFormulas, _
                             SearchOrder:=xlByColumns, _
                             SearchDirection:=xlPrevious, _
                             MatchCase:=False).Column
    
            Rw = .Cells.Find(What:="*", _
                             After:=.cells(1), _
                             LookAt:=xlPart, _
                             LookIn:=xlFormulas, _
                             SearchOrder:=xlByRows, _
                             SearchDirection:=xlPrevious, _
                             MatchCase:=False).Row
        end with
    End sub
    
    Sub Range_Find_Method()
    
        Dim Rw As Long
        Dim CL As Long
    
        FindRange ActiveSheet, Rw, CL
        ActiveSheet.Range("A1", ActiveSheet.Cells(Rw, CL)).Select
    
    End Sub
    

    最好解释一下你想做什么,因为你的错误代码并不清楚。函数不做任何操作,作为参数传递的变量通过
    find
    设置,然后在函数