とっておきの「夜食」教えて下さい

http://oshiete.goo.ne.jp/qa/1341789.html

ここに同じような質問があるのですが

ワークシート関数をVBAで使いたい場合

Application.WorksheetFunction.xxxxx
WorksheetFunction.xxxxx
Application.xxxxx

の三つの方法があります、
これらはどのような違いがあるか教えてください。

上記のページによれば

97以上の書法
Application.WorksheetFunction.xxxxx
WorksheetFunction.xxxxx

古いVersionの書法
Application.xxxxx

らしいですが、
実際に計算速度を自作プログラムを使って比較したところ

Application.WorksheetFunction.Round
WorksheetFunction.Round
の速度がが同じで

Application.Round
がこれらと比べて3倍強遅い
という結果が得られました。

なぜApplication.xxxxxの方が遅いのでしょうか?

Application.xxxxx
を使うメリットはないでしょうか?

それでも他人が書かれたVBAコードを見ると
たまにApplication.xxxxxを見かけることがありますがなぜでしょうか?

A 回答 (4件)

#2の回答者です。


単に古い書き方だけではありませんね。

この実際その違いを知って使っているわけですから、それを闇雲に、古いという理由だけで、
没にしてしまうという理屈は成り立ちません。実際のエラーの違いを認識すべきでしょうね。
#2の Sub TestMacro()が、なぜ、正しい結果を出さないか分かるなら、この問題は解決しているはずです。

エラーが出ないものならともかく、ワークシート関数の多くは、いろんな理由でエラーを返します。
それを単なるOn Error Resume Nextだけでは、失敗します。
WorksheetFunction で完全移行しているなら、誰もApplication.XXXX(関数) などはしません。実際のVBAをやっていない人には、分からない話だと思います。
    • good
    • 7

Application.WorksheetFunction.xxxxx


WorksheetFunction.xxxxx
のどちらも完全に同じ内容。
コーディングの手間を考えれば
WorksheetFunction.xxxxx
でよいと思う。

本来のオブジェクト ツリーでいえば xxxxx の位置は Application の下の WorksheetFunction の下にあるため、Application.WorksheetFunction.xxxxx の書き方となる。
しかし Application の部分はデフォルトで VBA によって読み込まれているため省略が可能である。
Dim mySheet As Excel.Worksheet
Set mySheet = Application.ThisWorkbook.Worksheets(1)
と書かず
Dim mySheet As Worksheet
Set mySheet = ThisWorkbook.Worksheets(1)
と書くのと同じ。

質問者自ら調査もし、
Application.xxxxx
という書き方が 「古い」 との情報を得ているはず。
しかも 「Excel 97 よりも前の書き方」 という事も十分に推測できているはず。
さらに実効速度も 3倍遅いという情報まで仕入れてある。
上記のことから、そもそも候補に入れるものではないことは考えられませんかね。

> それでも他人が書かれたVBAコードを見ると
> たまにApplication.xxxxxを見かけることがありますがなぜでしょうか?
未だに、そしてこれからも Application.xxxxx と書かれたコードが生産され続けているのであれば、その作者が勉強した当時の古い情報のまま進化していないってだけ。
過去に作って掲載したコードであれば、掲載し続けているコードが時代とともに自動的に最新の状態になるはずない。単なる 「当時書かれたコード」 ってだけ。
    • good
    • 2

こんにちは。



リンク先にか書かれていた通りだと思いますが、あまり、細かい仕様末節についての疑問は、自分のプログラミングの方向性を変えてしまいかねませんから、ほどほどにしておいたほうが良いかもしれませんね。

 ret = Application.xxxxx
とした時に、エラー値として返るので、IsError で、それを捉えることができるのが、最大のメリットです。
実行時エラーにはなりません。

buf1 = Application.Match(buf, ar(), 0)
If IsError(bufar1) Then '←エラー処理として、これだけで済みます。
 ar(n) = buf1
 n = n + 1
End If

掲示板以外の実際の現場では、WorksheetFunction を省略しないほうがよいと言われますが、エラー処理を含めたコードは、必然的に長くなります。以前は、古い書き方をすると、いつ、変更になるか分からないから、と言われましたが、あれから15年近くなりますがの一向に変わりませんね。

On Error トラップを設けるというのは、それ自体は当然ですが、エラー処理として、goto ErrorHandler などとすれば、コードが上下しますので、読みにくさもあります。基本的に、エラートラップは、絞り込めたほうがよいと思うのです。

VBAユーザーでOn Error トラップを本当に理解して使っている人がどのぐらいいるのか、疑問に思えることがあります。安易に、On Error Resume Next を使ってしまうのです。

セルのA1:A10 まで、このような、文字と数字の混在のデータがあるとします。
a
1
b
2
c
3
d
4
e
5

'//
Sub TestMacro()
Dim mTotal As Long
Dim i As Long, j As Long
i = 1
On Error Resume Next
Do
 j = WorksheetFunction.Match(i, Range("A1:A10"), 0)
 If j > 0 Then
  mTotal = mTotal + Cells(j, 1).Value
 End If
 i = i + 1
Loop While i <= 10
On Error GoTo 0
Debug.Print mTotal
End Sub
'//

このマクロの答えは、いくつでしょうか?
「40」
このぐらいのミスは、ひと目で見つけてほしいものですが、掲示板で書いている人の中には、さっぱり分っていない人もいるのです。

>Application.WorksheetFunction.xxxxx
>WorksheetFunction.xxxxx
これは、基本的に同じだと思います。
Excelを使っていれば、WorksheetFunction の親オブジェクトにApplicationがあります。

>なぜApplication.xxxxxの方が遅いのでしょうか?

ともかく、こちらでも論より証拠で測ってみました。
Declare Function timeGetTime Lib "winmm.dll" () As Long
を使い、計算内容は、B列全体、ランダムな3桁または4桁の数字で、合計のSUM関数を用いました。

32948674- 32948643 = 31 ...WorksheetFunction.Sum(Range("B:B"))
32988516- 32988469 = 47 ... Application.Sum(Range("B:B"))

同じ数値を、.Round(Cells(i, 2).Value / 10, 0)
でやってみると、
32280198 - 32266907 = 13291 ...Application.Round( x / 10,0)
32327201 - 32317747 = 9454 ...WorksheetFunction.Round( x / 10,0)

想像の範囲ですが、Excel側からインターフェースを通して利用しているせいだと考えます。
ただ、エラートラップという一つのオブジェクトを通すことになれば、それは、また別の時間が掛かる原因になると思います。
    • good
    • 5

速度が同じで

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報

このQ&Aを見た人がよく見るQ&A