[英]Call a function from sub in vba
我編寫了此函數,該函數應該從選定的范圍內獲取用戶定義的單元格,並將其值與用戶定義的數字相加或相乘。 輸出應為具有一個已更改單元格的數組。
我能夠編譯它; 但是,我不能這樣稱呼。
Function Macro1(cellref As Range, row_number As Long, column_number As Long, x As Double, method As Integer) As Variant
'Number, which will be added or multiplied by chosen cell value in an array
'One for multiplication, two for addition
If method = 1 Then
Cells(row_number, column_number) = Cells(row_number, column_number) * x
ElseIf method = 2 Then
Cells(row_number, column_number) = Cells(row_number, column_number) + x
End If
Result = Macro1
End Function
Sub try()
Macro1(Range("A1:AX3").Select, 2, 2, 0.5, 1) = Result
End Sub
運行此代碼時,出現錯誤消息“運行時錯誤424,所需對象”。 行Macro1(Range("A1:AX3").Select, 2, 2, 0.5, 1) = Result
突出顯示為紅色
然后我嘗試
Function Macro1(cellref As Range, row_number As Long, column_number As Long, x As Double, method As Integer) As Variant
'Number, which will be added or multiplied by chosen cell value in an array
'One for multiplication, two for addition
If method = 1 Then
Cells(row_number, column_number) = Cells(row_number, column_number) * x
ElseIf method = 2 Then
Cells(row_number, column_number) = Cells(row_number, column_number) + x
End If
Result = Macro1
End Function
Sub try()
Macro1(Worksheets("Macro1").Range("A1:AX3"), 2, 2, 0.5, 1)
End Sub
但是我收到“類型不匹配錯誤13”消息。 Sub try()
行以黃色突出顯示,其下面的行為紅色
我看到幾個問題:
一 ,行
Result = Macro1
在Macro1
是對Macro1
的遞歸調用。 即Macro1
正在嘗試自我調用。
因為Macro1
需要參數(第一個參數是Object
( Range
是Object
)),並且沒有提供對象參數,所以會出現錯誤。 實際上,您沒有在此調用中提供任何必需的參數。
二 ,代碼:
<functionName> = value
是倒退。 該行嘗試將Macro1
(賦值運算符=
左側的<functionName>
)設置為Result
的值。 這是不可能的(至少在VBA中沒有)。 我相信您想要的是:
result = Macro1(Worksheets("Macro1").Range("A1:AX3"), 2, 2, 0.5, 1)
將執行Macro1
使用指定的參數,然后將返回的值( Variant
如你定義它)的Variant
變量(因為你沒有Dim
配有它) result
。
第三 ,您已經將Macro1
聲明為Function
,但是沒有必要-它不返回值,而是將其設置為已傳遞的Range
的單元格。 最好將其更改為Sub
,因為這是它正在做的工作。 我認為您可能已經打算讓它在Result = Macro1
行中返回一個值,但是如上所述,它不會這樣做。 VBA通過將要返回的值分配給Function
名稱來工作,而不是像某些其他語言那樣使用return
函數。 如果確實有想要返回的某種結果,則可以使用以下代碼為其分配:
Macro1 = <the value to be returned>
但是,我不確定您從Function
實際返回的內容是什么,因為它可以在一個Range
而不是單個Cell
第四 ,我不確定您為什么要接受整個Range
作為Macro1
的參數,然后在其中指定單個Cell
。 傳遞...Range("A1:AX3")
然后指定我想column 2
和Row 2
的那個范圍是太多的認知努力挑選出你是什么細胞后。 為什么不僅僅傳遞...Range("B2")
並完成它呢? 好處是
1) Macro1
直接與所需的單元格一起使用,並且僅與所需的單元格一起使用
2)呼叫者僅指定所需的單元格和所需的單元格
3)從參數列表中消除其他不必要的參數。
第五,您的Macro1
收到一個Range
參數以供處理,但從未引用它。 您接受cellref As Range
,但是在代碼體中,您正在使用Cells()
並且從未引用過cellref
。 有兩個問題:
1)您有一個未指定的Cells()
,它將自動引用ActiveSheet
,無論您的意圖與否。
2)您根本不使用調用Macro1
時傳遞的內容(它可以在Worksheet
Workbook
任何 Worksheet
上)。
通過指定Worksheets("Macro1").Range("A1:AX3")
以便VBA 確切知道要在哪個單元格上,您在對 Macro1
的調用中非常具體。 但是,如果您恰巧在調用時正在查看Sheet2
,則Macro1
將與Worksheets("Sheet2").Range("B2")
因為此時Activesheet
= Worksheets("Sheet2")
而不是Worksheets("Macro1")
。
第六,您不對輸入值做任何檢查。 如果傳遞的單元格中的值恰好是red
而不是17.256
會發生什么。 red * 2
的值是多少? 為什么,這是Runtime error #13. Type mismatch
Runtime error #13. Type mismatch
。 您需要某種形式的健全性檢查或錯誤處理,以確保您使用的是數字數據。
最后,我將通過執行前的健全性檢查來建議這樣的事情:
Function Macro1(cellref As Range, x As Double, method As Long) As Variant
'Number, which will be added or multiplied by chosen cell value in an array
'One for multiplication, two for addition
Dim Result As Double
If Not IsNumeric(cellref.Value) Then
MsgBox ("The cell does not contain a numeric value")
Exit Function
End If
If method = 1 Then
Result = cellref.Value * x
ElseIf method = 2 Then
Result = cellref.Value + x
End If
Macro1 = Result
End Function
Sub try()
With Worksheets("Sheet1")
.Range("B2") = Macro1(.Range("B2"), 0.5, 1)
End With
End Sub
或者,您可以進行錯誤處理並按以下方式進行操作:
Option Explicit
Function Macro1(cellref As Range, x As Double, method As Long) As Variant
'Number, which will be added or multiplied by chosen cell value in an array
'One for multiplication, two for addition
On Error GoTo ErrorHandler
Dim Result As Double
If method = 1 Then
Result = cellref.Value * x
ElseIf method = 2 Then
Result = cellref.Value + x
End If
CleanExit:
Macro1 = Result
ErrorHandler:
MsgBox ("The cell does not contain a numeric value")
Result = vbNull
Resume CleanExit
End Function
Sub try()
With Worksheets("Sheet1")
.Range("B2") = Macro1(.Range("B2"), 0.5, 1)
End With
End Sub
請注意, Option Explicit
的包含要求您在使用它們之前聲明所有變量( Dim
)。 這將有助於消除其他可能的錯誤,因為您會錯誤地將Variable1
拼寫為Varaible1
而VBA“有幫助”地為您創建了一個全新的變量,從而創建了一個很難發現的錯誤。
根據其他一些評論,我認為您正在嘗試為范圍內的許多單元格調用此方法。 在這種情況下,您可以向Try()
過程添加一些簡單的循環,以遍歷所有需要應用的單元格。 如果不是,並且您正試圖基於該范圍內的其他值將其應用於“ Range
的一個單元格,則需要修改它的某些部分以執行后續操作。 我希望這篇文章中有足夠的信息供您了解如何做到這一點。 如果沒有,那么一旦您完全理解了更改此單元格的過程后,可能會提出一個很大的后續問題。
附帶說明一下,有一個很棒的OSS VBE附加軟件,名為Rubberduck ,可幫助您發現和修復許多此類錯誤。 我是該工具的忠實擁護者,每天都會使用它,我也為該項目做出了貢獻。
首先,不需要不需要的cellref參數。
就像@nacorid和@Jnevill所說的那樣,結果= Macro1不執行任何操作,代碼只是跳過了它。 如果要返回函數,則為Macro1 = result。 但是,您不分配任何結果,因此它仍然不會做任何事情。 您還需要在sub try()
創建一個分配以捕獲返回值。
我不確定您期望的輸出是一個具有一個已更改單元格的數組,您正在更改一個單元格,但它不是一個數組,您只是在此行直接更改其值: Cells(row_number, column_number) = Cells(row_number, column_number) * x
編輯:這是您加載陣列,修改並將其粘貼到其他位置的方式。
您將需要添加一些錯誤處理,以免類型不匹配。
您可能還希望使用pasterange的偏移量使其更具動態性。
sub macro1()
Dim rngarr() As Variant
Dim divisor As Double
Dim targetcol As Long
Dim targetrow As Long
Dim pasterange As Range
rngarr = Range("A1:AX3").Value
'Remember that your array starts at index 1
'A range that starts at row 2 will still have an index 1
targetcol = 2
targetrow = 2
divisor = 0.5
rngarr(targetrow, targetcol) = rngarr(targetrow, targetcol) * divisor
Set pasterange = Range("A5:AX7")
pasterange = rngarr
end sub
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.