VB熟達者というよりは、VBマニアな方々に質問です。
Sub Hoge(A)
A = 6
End Sub
Sub Main()
Dim N As Long
Hoge N
Debug.Print N
End Sub
このコードを実行して "6" が出力されるのは明白です。
Hogeはバリアントの参照を取るにも関わらず、LongのNを渡してそのNに6を入れてくれました。
これは、VBが引数を渡す時点で変数A用のメモリ領域をかってに確保し、Nという変数の参照型を作ったということの証拠になります。
実際、DLLでAPIを用意して、バリアント構造体のVarTypeを調べたところ、未知の16387という数値が現れました。
これは、MSDNライブラリを見たところ、VT_LONG Or VT_BYREFのようです。
このように、VBでも参照型は存在していますが、隠蔽されています。
そこで、参照型をもっと自由に使いたいと思い、参照型を作るAPIを作ってみました。
しかし、=演算子で代入しようとしたところ、参照が解除されて通常のバリアント型に戻ってしまいます。
ただし、もともとある変数の参照であるバリアント変数を別の変数の参照に変えたもののときは、参照先に代入してくれました。
どうやらVBはケチなようで、VBが内部で引数として作った参照変数以外は、参照している先に代入はしてくれないようです。
この障害を乗り越える方法を思いついた方、ぜひ教えてください。
No.2ベストアンサー
- 回答日時:
通常、VBでメソッドを呼び出すときは内部では
DISPPARAMS構造体に引数をセットします。
この構造体の中では引数はVARIANTARGにセットされ、
VARIANTARGの内部で引数のポインタが保持されます。
つまり、VBでメソッドを呼び出すときは
内部的には常にVariant型で呼ばれていると考える事ができます。
Privateの関数を呼ぶときはそんな面倒くさい事をしないで
Cと同じように呼んでいるかと考えていたのですが
もし、ご質問されているような結果が出るのでしたら
DISPPARAMSを使用しているのかもしれませんね。
ということは、その構造体内で宣言された変数しか、=は参照型として扱ってくれないということなのでしょうね。
実際、Variantの参照を取る関数に、Variantの変数を渡したとき、渡した側で調べたときと、関数内で調べたときと、変数のアドレスが違っていました。
DISPPARAMS構造体というのは、初めて聞いたのですが、これなら納得がいきます。
GetWindowsDirectoryAなどのAPIにBSTRを渡しているのに、ちゃんと文字列が得られるというのも、同時に納得がいきました。
No.3
- 回答日時:
APIを作るということの解決案にはなりませんが、補足から勝手になぜそのようにしたいかを推測しました。
>Dim A As Variant, B As Long
>MakeRef A, B
とし、Aを変更すればBも勝手に変わる、またはその逆をしたいのでしょうか?
もしそうであるなら、やはりクラスを作成しするのがいいように思います。
Dim obj1 as Object
Dim obj2 as Object
Set obj1 = New ClassA
Set obj2 = obj1
とすれば、大丈夫なような気がします。
勝手な予想で、でしゃばって申し訳ありません。
それは一応私も考えてみました。
しかし、やっぱり、LongやDoubleの参照を作りたいわけです。
LongやDoubleのポインタを取得して、参照/代入を行うクラスも作ってみました。
最後にはやっぱりVariant型を懲らしめてやりたい(?)のです。
No.1
- 回答日時:
あまり自信がないのですが・・・
>これは、VBが引数を渡す時点で変数A用のメモリ領域をかってに確保し、Nという変数の参照型を作ったということの証拠になります。
何をさして証拠といわれているのかちょっとわかりませんが、プロシージャの引数は、参照渡しがデフォルトであることはマニュアルに記載があります。(当然、値渡しもあります。)
>参照型をもっと自由に使いたいと思い、参照型を作るAPIを作ってみました。
どのような処理をすることをしたいのかはっきりしませんが、VBの仕様でプロシージャの引数以外に参照値を渡す(代入する)ことはできないような気がします。
当然、=演算子で代入することは仕様上できないと思います。
ところで、「参照型を作るAPI」というのは、言語は何で作られたのでしょうか?
VBで作るのであれば、クラスを作成し、クラス内で参照値を返すように見えるメソッドは作れるような気がしますが、VBは演算子のオーバーライドができないので、=演算子を使って操作できるようにはできないような気がします。
CやC++言語を使い、同じように作ることもできるような気はしますが、VB側で演算子のオーバーライドがやはりできないので、=演算子を使用することはできないと思います。
この回答への補足
関数はバリアント型の参照をほしがっているのに、Longの変数が渡せること自体が、C++から考えるとおかしなことだということです。
要は、VBでは、Cのように関数を呼び出すときに、スタックのpush、pop、callだけを行っているのではなく、mallocを使ったり、Variant構造体の内部をいじったりしているといいたいのです。
参照型をもっと自由に使いたいというのは、
Dim A As Variant, B As Long
MakeRef A, B
とすれば、AがBの参照になるような関数を作りたいと言うことです。
C++では次のようにすれば簡単ですが。
long B;
long& A = B;
ちなみに、APIを作る環境は、C++のWin32 DLLです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 列の最終行に新たに入力されたらその値を自動参照 1 2023/01/21 09:59
- Visual Basic(VBA) マクロVBA 1シートをまとめる 閉じ方 初心者 SOS! 1 2022/06/17 14:54
- Visual Basic(VBA) VBAでのMATCH関数 3 2022/10/17 19:06
- Excel(エクセル) エクセルの複数のセルを一括で絶対参照にする方法 3 2023/06/14 15:57
- Visual Basic(VBA) マクロについて教えてください。 1 2023/06/06 00:57
- Visual Basic(VBA) Sheet1のA列にコードB列にメアド、Sheet2のB列にコード一覧とD列にメアド一覧があり、Sh 3 2022/10/19 11:57
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
- Excel(エクセル) エクセル開いたらウィンドウがでました 2 2023/03/28 16:24
- その他(プログラミング・Web制作) python質問 1 2023/08/14 11:54
- Visual Basic(VBA) Sheet「状況」から、分類の年齢別カウント数をSheet「D表」へ転記する下記マクロを作っています 7 2022/12/14 17:57
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
構造体のデータを丸ごとコピー...
-
VBAにてcolorindexを変数に格納...
-
プログラミング言語の変数と数...
-
値が変わるのはどうしてでしょ...
-
値が代入されてない時
-
VB6.0の変数、関数の定義位置か...
-
VBAの変数のデータ型を変更する...
-
long型のデータをバイト型の配...
-
C言語 構造体の中に共用体を定...
-
整数から16進数への変換 現在c...
-
ヘッダファイルと構造体
-
構造体の代入と比較
-
winsockのsendtoで送れるデータ型
-
C++ 構造体の一括初期化 {0}
-
構造体のポインタにNULLが入らない
-
セグメントエラー
-
関数から配列を返すには?
-
ExcelVBAで質問です。離れた二...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
C++ 構造体の一括初期化 {0}
-
long型のデータをバイト型の配...
-
「#undef」と「#define」の使い...
-
構造体のデータを丸ごとコピー...
-
VBAにてcolorindexを変数に格納...
-
C言語 構造体の中に共用体を定...
-
値が代入されてない時
-
異なる構造体のデータのコピー
-
typedefをプログラム中で解除す...
-
構造体のポインタにNULLが入らない
-
charとucharの違い
-
整数から16進数への変換 現在c...
-
VBAの変数のデータ型を変更する...
-
VB.NETのStructureというのはど...
-
構造体を型の異なる構造体に代入
-
日付チェック関数について
-
ユーザー定義型変数の一括初期化
-
構造体の初期化方法について
おすすめ情報