這個(gè)題目是受一個(gè)網(wǎng)友問題的啟發(fā),寫在這里算是給自己留個(gè)記號(hào). 第一, Worksheetfunciton.(excel自帶的Function)與Application.Worksheetfunction.(excel自帶的Function)在EXCEL環(huán)境下效果是一樣的,也就是說Application可以省略,因?yàn)槟J(rèn)是EXCEL. 如果是在其他的OFFICE程序中調(diào)用EXCEL函數(shù)時(shí)需要加上Application,比如在Word中用VBA調(diào)用EXCEL函數(shù),微軟有這樣的示例: Dim xlApp As Excel.Application Dim x, y As Integer Set xlApp = New Excel.Application x = ActiveDocument.ContentControls(1).Range.Text y = ActiveDocument.ContentControls(2).Range.Text ActiveDocument.ContentControls(3).Range.Text = _ xlApp.WorksheetFunction.Sum(x, y) (以下部分的討論均只考慮EXCEL環(huán)境,不涉及其他任何程序,所以在用Worksheetfunction時(shí),前面這個(gè)Application.是可以省略掉的) 第二,我們來看一下Application.(excel自帶Function)與Worksheetfunction.(excel自帶Function)有什么不同,其實(shí)在絕大多數(shù)情況下它們?cè)谑褂蒙鲜且粯拥?網(wǎng)上通常認(rèn)為主要區(qū)別在于對(duì)彈出錯(cuò)誤的處理上.比如在用VLookup時(shí): 程序1:
如果在A1:A100沒有對(duì)應(yīng)"hello"值,以上運(yùn)行時(shí)會(huì)出現(xiàn)Run Time Error,所以容錯(cuò)處理上通常用On Error Resume Next, If Err.Number <> 0這樣的結(jié)構(gòu). 程序2:
如果在A2:A10沒有對(duì)應(yīng)"hello"值,以上不會(huì)出現(xiàn)Run Time Error,會(huì)看到y(tǒng)值是: Error 2042. 在預(yù)想程序找不到到相應(yīng)結(jié)果的"容錯(cuò)"處理上通常只要用: If IsError(y) = False 這樣的語句就可以了. 另外的一個(gè)案例,是關(guān)于RoundDown函數(shù)結(jié)合聲明Currency類型出現(xiàn)的:
SheetCredit not Rounded -0.775 WorksheetFunction.RoundDown: -0.77 Application.RoundDown: -0.78 理論上Rounddown的結(jié)果都應(yīng)該是-0.77,但實(shí)際上Application.RoundDown結(jié)果為-0.78 奇妙的是,如果在聲明變量時(shí)類型定義SheetCredit為Double類型,Application和Worksheetfunction的結(jié)果就是一樣的了,都是0.77 SheetCredit not Rounded -0.774999999999999 WorksheetFunction.RoundDown: -0.77 Application.RoundDown: -0.77 除了數(shù)值范圍外,Currency和Double最主要的區(qū)別是,前者不用浮點(diǎn)計(jì)算器,后者用,所以精度是不一樣的(從0.775與0.7749999999999的區(qū)別上也可看出),但為什么Application和Worksheetfunction在處理對(duì)待-0.775上有不同的結(jié)果?更奇怪的是為什么Application.RoundDown是-0.78?事實(shí)上,我試了Application.Round, Application.RoundUp,結(jié)果都是-0.78! 也許是微軟的另一個(gè)bug? 第三,前面的案例表明,Application與Worksheetfunction(或Application.Worksheetfunction)在VBA中的運(yùn)用還是有區(qū)別的,雖然在絕大多數(shù)情形下我們似乎不需要在意,所以如果你看到某本VBA的書上說,以下三種寫法可以互通,也不算什么錯(cuò): Application.(excel自帶Function) Application.Worksheetfunction.(excel自帶Function) Worksheetfucntion.(excel自帶Function) 我曾經(jīng)看過一位微軟MVP的觀點(diǎn),他講了兩點(diǎn): 一是微軟認(rèn)為比較成熟的語法用法,會(huì)將它歸檔(中文可能翻譯得不到位,英文是稱為Documented),如果沒有歸檔,是因?yàn)槲④浌こ處焸兛赡軙?huì)在將來的版本中繼續(xù)改進(jìn)或增強(qiáng)或完善或拋棄它的用法.一般歸檔的用法微軟在后期很少會(huì)改動(dòng),所以這位MVP建議大家在用EXCEL函數(shù)或VBA時(shí),如果有可能,盡量用歸檔過的東西(微軟的這個(gè)歸檔的列表在哪里,他沒有說,我也不清楚),因?yàn)檫@些是微軟自認(rèn)為比較成熟的用法. 二是,微軟在新推出Worksheetfunction的時(shí)候(我不知道是哪一年了),曾經(jīng)表明將來會(huì)以這個(gè)為主,將來會(huì)淘汰對(duì)Application.(excel自帶Function)這種用法的支持,要強(qiáng)制用戶使用Application.Worksheetfunction.(excel自帶Function),或者Worksheetfucntion.(excel自帶Function),最關(guān)鍵的,是它把Worksheetfunction用法歸檔了,而Application直接帶EXCEL Function的用法一直沒有歸檔.所以為了避免將來因?yàn)榘姹旧?jí)造成代碼多處改動(dòng)的麻煩,這位MVP建議大家現(xiàn)在就養(yǎng)成用Worksheetfunction的習(xí)慣! 不過,事實(shí)上,直到2010版本為止,Application和Worksheetfunction的使用還在并存著,絕大多數(shù)用戶也將它們混為一談,微軟什么時(shí)候會(huì)終止Application的直接調(diào)用,或者什么時(shí)候改變了想法,將Application的直接調(diào)用也歸檔,只有它自己知道了(?) 這個(gè)論壇很多人喜歡用數(shù)組,這就構(gòu)成了第三個(gè)案例: 1) arr = Application.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000")) '運(yùn)行正常 2) arr = WorksheetFunction.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000")) '運(yùn)行時(shí)出現(xiàn)Run Time Error 13, 類型不匹配 初步結(jié)論是: a) 在SumIf這個(gè)函數(shù)上,Worksheetfunction是不支持?jǐn)?shù)組條件的,如果將條件Array("B", "C", "G", "R")改為"B",是可以得到結(jié)果的 b) 在SumIf這個(gè)函數(shù)上,用Application直接調(diào)用,是支持?jǐn)?shù)組條件的 c) 我猜Worksheetfunction不支持SumIf數(shù)組條件的可能原因是,因?yàn)閃orksheetfunction相當(dāng)于在Excel表格中直接輸入,所以當(dāng)在Excel中直接輸入數(shù)組公式時(shí),因?yàn)樾枰狢trl + Shift + Enter三鍵并按才能得到結(jié)果,然后到VBA中用Worksheetfunction這個(gè)Object調(diào)用的時(shí)候,無法模擬CSE三鍵齊按,所以出現(xiàn)Run Time Error,而用Application直接調(diào)用,可能在程序后臺(tái)有另外的內(nèi)嵌計(jì)算方法直接支持?jǐn)?shù)組模式,所以就避免了出錯(cuò),這一點(diǎn)仍然與前面的Vlookup一例有相通之處. 結(jié)論是,Application.{excel function}與Worksheetfunction.{excel function}區(qū)別不大,但如果在你的代碼里出現(xiàn)區(qū)別時(shí),請(qǐng)不要太驚訝! 個(gè)人建議:如果你有個(gè)人喜好,那就保持代碼習(xí)慣前后一致,如果用Application就一直用,如果用Worksheetfunction也就一直用,盡量不要在一段代碼中混用這兩種方法;如果你沒有個(gè)人喜好,那么在兩種方式都可正確運(yùn)行時(shí),盡可能只用Worksheetfunction,畢竟這是微軟歸檔過的用法. |
|