|
本帖最后由 adders 于 2012-4-29 16:03 编辑
vbamaster 发表于 2012-4-29 09:40
感谢各位老师的回答,今天有些晚了,先标记下,等有时间再细研究。
好了,我接着15楼说.
前面做了这么多的铺垫,只是想说明一下,Application.与Worksheetfunction.(或Application.Worksheetfunction.)在VBA中的用法还是有区别的,虽然在绝大多数情形下我们似乎不需要在意,所以如果你看到某本VBA的书上说,以下三种写法可以互通,也不算什么错:
Application.(excel自带Function)
Application.Worksheetfunction.(excel自带Function)
Worksheetfucntion.(excel自带Function)
当然,这个主题的要求是为了探讨下两种用法的区别,那么我们就继续看还有哪些不同点.
我曾经看过一位微软MVP的观点,他讲了两点:
一是微软认为比较成熟的语法用法,会将它档案化(中文可能翻译得不到位,英文是称为Documentation),如果没有档案化,是因为微软工程师们可能会在将来的版本中继续改进或增强或完善或抛弃它的用法.一般档案化的用法微软在后期很少会改动,所以这位MVP建议大家在用EXCEL函数或VBA时,如果有可能,尽量用档案化过的东西(微软的这个档案化的列表在哪里,他没有说,我也不清楚),因为这些是微软自认为比较成熟的用法.
二是,微软在新推出Worksheetfunction的时候(我不知道是哪一年了),曾经表明将来会以这个为主,将来会淘汰对Application.(excel自带Function)这种用法的支持,要强制用户使用Application.Worksheetfunction.(excel自带Function),或者Worksheetfucntion.(excel自带Function),最关键的,是它把Worksheetfunction用法档案化了,而Application直接带EXCEL Function的用法一直没有档案化.所以为了避免将来因为版本升级造成代码多处改动的麻烦,这位MVP建议大家现在就养成用Worksheetfunction的习惯!
不过,事实上,直到2010版本为止,Application和Worksheetfunction的使用还在并存着,绝大多数用户也将它们混为一谈,微软什么时候会终止Application的直接调用,或者什么时候改变了想法,将Application的直接调用也档案化,只有它自己知道了(?).
好了,啰嗦了半天,言归正传,现在来看一看楼主的问题.
我自己做了试验,我的配置是WIN7 + EXCEL2003 (英文版),在楼主的3种写法中(实际就两种,因为写法2和写法3是一样的):
1) arr = Application.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000"))
我试验的结果是不出现Run Time Error但是也没有得到结果
2) arr = WorksheetFunction.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000"))
我试验的结果是Run Time Error 13, 类型不匹配
这个试验在预料之中.类似于我在15楼中的Vlookup例子.
接下来,我稍稍改动代码如下:
3) arr = Application.Sum(Application.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000")))
这一次我得到了正确的结果
我再改动一下:
4) arr = WorksheetFunction.Sum(Application.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000")))
我得到了跟3)一样的正确结果
我再改动一下:
5) arr = WorksheetFunction.Sum(WorksheetFunction.SumIf(Range("a2:a10000"), Array("B", "C", "G", "R"), Range("B2:B10000")))
结果,Run Time Error 13, 类型不匹配
3,4,5这三个代码说明了什么,我的粗浅结论是:
a) 在SumIf这个函数上,Worksheetfunction是不支持数组条件的,就象前面有网友指出的,如果将条件Array("B", "C", "G", "R")改为"B",是可以得到结果的
b) 在SumIf这个函数上,用Application直接调用,是支持数组条件的
c) 在Sum这个函数上,Application与Worksheetfunction的调用没有区别,原因是Sum函数不涉及数组条件
d) 我猜Worksheetfunction不支持SumIf数组条件的可能原因是,因为Worksheetfunction相当于在Excel表格中直接输入,所以当在Excel表格中直接输入数组公式时,因为需要Ctrl + Shift + Enter三键并按才能得到结果,然后到VBA中用Worksheetfunction这个Object调用的时候,无法模拟CSE三键齐按,所以出现Run Time Error,而用Application直接调用,可能在程序后台有另外的内嵌计算方法直接支持数组模式,所以就避免了出错,这一点仍然与前面的Vlookup一例有相通之处.
结论是,Application.{excel function}与Worksheetfunction.{excel function}区别不大,但如果在你的代码里出现区别时,请不要太惊讶!
我个人的建议是保持代码习惯前后一致,如果用Application就一直用,如果用Worksheetfunction也就一直用,不要在一段代码中混用这两种方法. |
|