XLPack 5 リバースコミュニケーション版
外部関数を必要とするルーチンについては, 従来のコールバック版に加え, XLPack 5より新たにリバースコミュニケーション版がサポートされます.
1. 従来型ルーチン(コールバック版)
例として, 次の定積分を求める問題を考えてみます.
∫ 1/(1 + x^2) dx [0, 4]
Qk15を使った一般的なプログラムは次のようになります.
Function F(X As Double) As Double
F = 1 / (1 + X ^ 2)
End Function
Sub Ex_Qk15()
Dim A As Double, B As Double, Result As Double
A = 0: B = 4
Call Qk15(AddressOf F, A, B, Result)
Debug.Print "S =", Result
End Sub
積分ルーチンQk15は, 被積分関数値が必要になると外部ユーザールーチンFを呼び出して(コールバックして)必要な点における関数値を計算してもらいます. そして, 最終的な積分値が求まったときに呼び出し元に戻ります.
2. リバースコミュニケーション版
従来型ルーチンに対して, リバースコミュニケーション版では被積分関数値が必要になるとxの値を返していったん呼び出し元に戻り, 必要な関数値とともに再度呼び出してもらう手順を最終的な積分値が求まるまで繰り返します.
上の例のリバースコミュニケーション版によるプログラムは次のようになります.
Sub Ex_Qk15_r()
Dim A As Double, B As Double, Result As Double
Dim XX As Double, YY As Double, IRev As Long
A = 0: B = 4
IRev = 0
Do
Call Qk15_r(A, B, Result, XX, YY, IRev)
If IRev = 1 Then YY = 1 / (1 + XX ^ 2)
Loop While IRev <> 0
Debug.Print "S =", Result
End Sub
リバースコミュニケーション版のルーチン名は, (Qk15に対してQk15_rというように)コールバック版のルーチン名に “_r” を付けたものになります.
IRevはリバースコミュニケーションの制御変数で, 必ず初めに0に設定してから呼び出す必要があります. 最終結果が求められたときにはIRev=0で戻ってきます. 途中で追加情報が必要な場合にはIRev<>0で戻ってきます. その場合のIRevの値と必要な処理はルーチンごとに定義されています.
Qk15_rの場合には, XXとYYはリバースコミュニケーション用の追加引数で, IRev=1であればXXにおける関数値をYYに入れて再度呼び出すことを要求しています.
3. リバースコミュニケーション版のメリットとデメリット
リバースコミュニケーション版は次のようなメリットがあります.
- AddressOf演算子を使わなくてよいので安全です. すなわち, AddressOfでは外部ルーチンのインターフェースの正しさはチェックされませんので, 誤りがあるとExcelがクラッシュしてしまうことがあります
- プログラミングの自由度が高くなります. コールバック版では外部ユーザールーチンの引数が決まっているため, 追加情報を渡すのに不自由なことがあります.
一方で次のようなデメリットもあります.
- 呼び出し手順がコールバック版に比べて面倒で, プログラムが複雑になることがあります.
コールバック版とリバースコミュニケーション版における計算結果は同じになります. 状況に応じて適切な方を使用してください.