必须声明标量变量_Excel VBA解读(136): 在用户定义函数中的变体、引用、数组、计算表达式、标量...
學(xué)習(xí)Excel技術(shù),關(guān)注微信公眾號(hào):
excelperfect
在前面的幾篇文章中,我們自定義的函數(shù)使用定義為Range的參數(shù)來(lái)從Excel工作表中獲取數(shù)據(jù),例如:
Function VINTERPOLATEB(Lookup_Value As Variant, _
???Table_Array As Range, _
???Col_Num As Long)
如果在公式中使用單元格區(qū)域作為參數(shù)來(lái)調(diào)用該函數(shù),運(yùn)轉(zhuǎn)得非常好:
=VINTERPOLATEB($H1,$A$1:$C$10000,2)
但是,如果使用計(jì)算表達(dá)式或者一組常量作為參數(shù),則返回的結(jié)果為#Value:
{=VINTERPOLATEB($H1,($A$1:$C$10000*1),2)}
這個(gè)公式是數(shù)組公式,因此輸入完后按Ctrl+Shift+Enter組合鍵,Excel自動(dòng)在公式兩邊添加花括號(hào)。
=VINTERPOLATEB(4.5,{1,3,3.5;4,4,4.5;5,4.5,5},2)
這個(gè)公式使用了3行3列的數(shù)組常量。
Excel在調(diào)用函數(shù)之前會(huì)檢測(cè)到這些參數(shù)不是單元格區(qū)域。
通過將參數(shù)定義為Variant型而不是Range可以解決此問題:Variant型參數(shù)幾乎可以包含任何內(nèi)容!但用戶自定義函數(shù)現(xiàn)在必須處理Variant可能包含的所有不同類型的數(shù)據(jù)。
一種簡(jiǎn)單的方法是將參數(shù)聲明為Variant型變量:這會(huì)將所有內(nèi)容強(qiáng)制轉(zhuǎn)換為值:
Function TestFunc(theParameter AsVariant)
???Dim vArr As Variant
???vArr = theParameter
???TestFunc = vArr
End Function
在VBE中,在賦值給函數(shù)的返回值的語(yǔ)句行設(shè)置斷點(diǎn),如下圖1所示
圖1
輸入數(shù)組公式:
=TestFunc($A$1:$A$5*1)
本地窗口顯示如下圖2所示。
圖2
在本地窗口可以看到,vArr變量包含2維Variant型數(shù)組,子類型為Double。
輸入公式:
=TestFunc({1,2,3;5,6,7})
在本地窗口中可以看到其結(jié)果也是2維數(shù)組:
圖3
輸入公式:
=TestFunc({1,2,3})
在本地窗口可以看到結(jié)果為1維數(shù)組:
圖4
輸入公式:
=TestFunc({1;2;3})
在本地窗口可以看到結(jié)果為2維數(shù)組:
圖5
輸入公式:
=TestFunc(15)
可以看到結(jié)果為一個(gè)標(biāo)量,而非數(shù)組:
圖6
如果提供單元格區(qū)域作為函數(shù)參數(shù):
=TestFunc($A$1:$A$5)
則得到:
圖7
注意,theParameter變量包含對(duì)象子類型Range,意味著必須將它視為Range變量,而vArr包含從該Range變量中提取的值。
因此,在通用目的的用戶自定義函數(shù)中,希望使用Variant型參數(shù),并且經(jīng)常需要確定變體的類型以及上限和下限。
為了獲得最大效率,不能只使用vArr=theVariant,因?yàn)?#xff1a;
不能使用.Value2,因?yàn)樗赡懿皇菃卧駞^(qū)域。
在許多情況下,希望在強(qiáng)制轉(zhuǎn)換所有值之前操控Range對(duì)象或者操控Range對(duì)象而不是強(qiáng)制轉(zhuǎn)換所有值。
因此,這里有一個(gè)函數(shù)用來(lái)確定傳遞的內(nèi)容以及它的大小:
Function Variant_Type(theVariantAs Variant)
???Dim jRowL As Long
???Dim jRowU As Long
???Dim jColL As Long
???Dim jColU As Long
???Dim jType As Long
???Dim varr As Variant
??? '
??? ' theVariant可以包含標(biāo)量, 數(shù)組, 或單元格區(qū)域
??? ' 找到上限和下限以及類型
??? 'type=1:單元格區(qū)域, 2:2維variant數(shù)組,
??? ' 3:1-維variant數(shù)組(列的單行), 4:標(biāo)量
??? '
???On Error GoTo FuncFail
???jType = 0
???jRowL = 0
???jColL = 0
???jRowU = -1
???jColU = -1
???If TypeName(theVariant) = "Range" Then
??????? jRowL = 1
??????? jColL = 1
??????? jRowU = theVariant.Rows.Count
??????? jColU = theVariant.Columns.Count
??????? jType = 1
???ElseIf IsArray(theVariant) Then
??????? jRowL = LBound(theVariant, 1)
??????? jRowU = UBound(theVariant, 1)
??????? On Error Resume Next
??????? jColL = LBound(theVariant, 2)
??????? jColU = UBound(theVariant, 2)
??????? On Error GoTo FuncFail
??????? If jColU < 0 Then
??????????? jType = 3
??????????? jColL = jRowL
??????????? jColU = jRowU
??????????? jRowL = 0
??????????? jRowU = -1
??????? Else
???????? ???jType = 2
??????? End If
???Else
??????? jRowL = 1
??????? jRowU = 1
??????? jColL = 1
??????? jColU = 1
??????? jType = 4
???End If
???Variant_Type = jType
???Exit Function
FuncFail:
???Variant_Type = CVErr(xlErrValue)
???jType = 0
???jRowU = -1
???jColU = -1
End Function
注意,首先測(cè)試變量是否包含Range,這是為了避免無(wú)意中將Range強(qiáng)制轉(zhuǎn)換為其值。在確定變體的子類型時(shí),VBA還有幾種方法:
If TypeOf theVariant Is Range Then
If TypeName(theVariant) = “Range”Then
嘗試使用VarType(theVariant)時(shí)要特別小心,這會(huì)對(duì)Range的覆蓋范圍進(jìn)行強(qiáng)制轉(zhuǎn)換,然后拋出結(jié)果值!
代碼的圖片版:
小結(jié):在通用目的的用戶自定義函數(shù)中,必須使用Variant類型的參數(shù)而不是Range類型。可以通過在處理變量之前確定變體包含的內(nèi)容來(lái)有效地處理出現(xiàn)的問題。
總結(jié)
以上是生活随笔為你收集整理的必须声明标量变量_Excel VBA解读(136): 在用户定义函数中的变体、引用、数组、计算表达式、标量...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iic总线从机仲裁_I2C总线的仲裁问题
- 下一篇: hbase hdfs外部表_硬核干货长文