Excel-DNA で簡単に XLL を作成できることはわかりました。XLL アドインはワークシート上でユーザー定義関数として直接利用できて便利ですね。これが VBA からも利用できると便利です。XLL アドインに定義された関数をVBAから利用する方法は、ここに説明されています。→ (MSDN) Accessing XLL Code in Excel
これによると、Application.Run メソッドで行えることがわかります。さっそく、コードを書いて試してみます。こんなコードを書いてみました(笑)
(こんな感じ↓)
<DnaLibrary RuntimeVersion="v4.0" Name="Prime" Language="CS"> <![CDATA[ using System.Threading.Tasks; public class Prime { public static bool IsPrime(int x) { for (int i = 2; i <= x / 2; i++) { if (x % i == 0) { return false; } } return true; } } ]]> </DnaLibrary>
与えられた整数 x が素数であるか?判定する関数です。あの・・・、アルゴリズムに突っ込んではいけません。与えられた整数 x より小さな整数でひたすら割り切れるかどうかチェックします(笑)
上記のコードを、.dna ファイルに記述し、実行してみましょう。シート上に =IsPrime(A1) のように記述すると、ちゃんと動作してますね。
では、VBA から呼んでみます。ただ呼んでも面白くないので、同じ処理を行う VBA コードを書いて、処理速度を比較してみたいと思います。上記のコードを VBA で記述するとこうなりますね?
Function IsPrimeVBA(target As Long) As Boolean Dim i As Long IsPrimeVBA = True For i = 2 To target / 2 If target Mod i = 0 Then IsPrimeVBA = False Exit For End If Next End Function
これを、Excel-VBE で標準モジュールを作成して記述します。これで、ワークシートからユーザー定義関数として、=IsPrimeVBA(A1) のように呼べますね。これで、準備が出来ました。VBA からそれぞれの関数を呼んで、処理時間を計測してみましょう。こんなコードを書いてみました。
Sub VBACalculateTime() Dim start, finish Dim is_prime As Boolean With ActiveSheet start = Timer is_prime = Application.Run("IsPrime", .Range("A1").Value) finish = Timer Debug.Print (is_prime & ":XLL time= " & finish - start) start = Timer is_prime = IsPrimeVBA(.Range("A1").Value) finish = Timer Debug.Print (is_prime & ":VBA time= " & finish - start) End With End Sub
このコードでは、ワークシートのA1セルに入っている数値を素数判定する時間を計測します。小さな数値では差がわかりにくいかもしれませんので、Long の最大値(2147483647)を入れてみることにしましょう。2147483647 は都合のいいことに素数なので、これの判定を行うにはかなりの繰り返し演算が必要になります。
いかがでしたか?私の環境では、かなり差が出ました。そして、会社のExcel2007(x86) と自宅のExcel2010(x64)で比較したところ・・・ふしぎな事に、XLL の関数の処理時間はほぼ同じなのに対して、VBA で作成した関数はExcel2010(x64) のほうが約2倍の処理時間となりました。どうしてなんでしょうね~?
どなたかご存知の方がおられたら、教えてください。
しかし、XLL だと、COMアドインのようにオブジェクトの生成が出来ないのがたまにきずですね♪
次回は、ちょっとExcel-DNA から離れて、以前に作成した BigIntXLL.dll を、COMアドイン および、COMオートメーションアドイン として登録してみたいと思います。で・・・、 VBA vs COM vs XLL の処理時間を比較してみたいとおもいます♪
では、また(笑)
VBAの方だけやってみました。
Vista+2007でも2010で両方共約30秒で差がでません。
>VBAの方だけやってみました。
ありがとうございます m(_ _)m
>Vista+2007でも2010で両方共約30秒で差がでません。
XP+Excel2007(x86)+Core2 Quad だと23秒
Win7(x64) + Excel2010(x64) + i5 だと・・・46秒なんです。
ちょうど2倍違います。
XLL のほうは、どちらも約 5秒 なんですが・・・(謎)
>XLL のほうは、どちらも約 5秒 なんですが・・・(謎)
うーーん速いですね。
明日でもまたやって見ます。
Vista+2007,2010でDNAもやってみました。
2007:DNA 7.5秒、VBA 29.2秒
2010:DNA 6.8秒、VBA 29.7秒
で2007、2010で特に差があるとは思えません。
しかし、DNAの方もインタープリティブにやってるはずですが、早いですね。
>で2007、2010で特に差があるとは思えません。
ん・・・
PCの違いですかね~?
なんか、CPU の違いが疑わしいところです。
でも、XLL のほうはあまり変わらないので・・・
やはり、謎です^^
ついでに2003でもやってみました。
やはり、DNA:6.9~8.4、VBA:29.4 でほぼ2007以降と変わりませんね。