如何正确调用vba函数
我是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, _
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
设置,然后在函数