[[20230306173942]] 『マクロの関数の引数の意味』(morimori) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『マクロの関数の引数の意味』(morimori)

お世話になります。

VBAでマクロを組んでいて、いろいろ調べているうちに、このサイトを見つけました。
https://stackoverflow.com/questions/35583949/how-to-get-text-and-select-text-from-a-list-box-in-another-application-using-vba

この中のコードで、
Call SendMessage(vendor_listbox, LB_GETTEXT, i, buffer$)
Call SendMessage(vendor_listbox, LB_SETSEL, ByVal 0&, ByVal -1&)
ここの ByValの意味と、数値& 、変数$ の意味を教えてほしいです。

ByValに関しては、関数の宣言のときにすでに指定してあるのに???
と疑問に思っています。

実際 ByValを付けないと動かなかったので不思議に思いました。

よろしくお願いいたします。

< 使用 Excel:Microsoft365、使用 OS:Windows10 >


"VBA 参照渡し 値渡し"
で検索してみてください。

また、&や$は型宣言文字 というもので、
& は Long, $は Stringを意味します。
変数につけるほか、数値につけることもままあります。

(abc) 2023/03/06(月) 17:53:56


回答がついてますが、そのままアップします。

他の回答者の回答が付くまでの繋ぎです。

https://search.yahoo.co.jp/amp/s/pulogu.net/blog/020-computer/excel-vba/excel-vba-variable-declaration-after-variable-and-symbol-dollar-sign-meaning/%3Famp%26usqp%3Dmq331AQIKAGwASCAAgM%253D
(MK) 2023/03/06(月) 17:55:52


回答ありがとうございます。

&と$がこのような使い方ができるのを知りませんでした。
こういう文字は検索してもヒットしてくれないので助かりました!

ByValに関して、モジュールの先頭で

    Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
                     (ByVal hWnd As Long, _
                     ByVal Msg As Long, _
                     ByVal wParam As Long, _
                     ByVal lParam As Long) As Long

のように宣言をしていますが、
なぜ、関数を呼び出した際に、明示的にByValを付けないといけないのか
が理解できていなくて、そこを教えていただきたいです。
(実際ByValを抜くとSendMessageがエラーを返します)

よろしくお願いいたします。
(morimori) 2023/03/06(月) 19:08:26


それは普通のファンクションプロシージャではなく、WindowsAPIという特別な関数群との
情報のやり取りを設定しているものです。
その時には、その引数の型や変数の渡し方が厳密に決められているから、それを守らないといけない、
ということです。
理屈ではなく、そのように決まっている、ということです。

(abc) 2023/03/06(月) 19:16:43


こちらが参考になります。
https://qiita.com/nukie_53/items/6a88ce82565e238a3c71

ここにリファレンスへのリンクがありますから、それを取得することで
どのように決まっているかを知ることができると思います。

まあ、すぐに、それらが全て必要になるとも思えないので、
必要になったときに、あらためて学習されたらいかがでしょうか。

(abc) 2023/03/06(月) 19:54:18


 ↓こんな記事見つけました。

VB6.0でポインタを扱う | 画像処理ソリューション
https://imagingsolution.blog.fc2.com/blog-entry-69.html?sp

 ちょい引用すると...
 > APIの宣言の型は As Any として
 > 呼び出す側はポインタ(先頭アドレス)にByValを付けて渡す

      ...という使い方をする時なんかに Call内でByVal付けたりするみたいですねー。

 ほいで、
 SendMessageをDeclareする時って、多分↓こうが一般的だと思います。

 Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (_
         ByVal hwnd As LongPtr, _
         ByVal wMsg As Long, _
         ByVal wParam As LongPtr, _
         lParam As Any) As LongPtr
 '       ~~~~~~~~~~~~~

 こういった場合に
 Call側でByValを「必ず付けなければならない」のかどうかまでは私も存じあげませんが、
 SendMessage自体は(Declare側でAnyで定義してなかったとしても)Any型があるものとして動作してるでしょうし(たぶん...)
 エラーについてはその辺の不整合が影響してるんでないでしょうかね?
                                                      ...しらんけど。と、ぼんやりした意見でスマセン ^^;

(白茶) 2023/03/06(月) 23:01:56


https://www.tokovalue.jp/function/SendMessage.htm
https://t19488sns.com/sendmessagepostmessage/397/
 よく知らないけど、もともとのApi自体がlParamの型を持っていないみたい?
 他の言語だと、ポインタで渡したり、参照渡し?の構造体で渡したりしてるから
 送る相手によって型を決めてあげなくちゃいけない?

 VBAだと省略した場合参照型になるけど、C#では省略すると値渡しになるのかしら

 1回しか使ったことなくて、ByValもつけた記憶ないんだけどテストしたコード教えて貰えませんか?

(稲葉) 2023/03/07(火) 05:37:53


https://liclog.net/sendmessage-function-vba-api/
の最後にあるコード例では Any型をそのまま使っていますが、
問題なく動作するようです。

ちなみに、2023/03/06(月) 19:54:18で書いたリファレンスの件です。
ダウンロードしたものは自己解凍形式になっており、
ダブルクリックして解凍すると、
C:\Office 2010 Developer Resources というフォルダに解凍されました。
(SendMessageについては、白茶さんの書かれた形式になっておりました。)

(abc) 2023/03/07(火) 06:33:07


みなさま、ご回答ありがとうございます。

とりあえずはうまく動いてくれてるので、
みなさまから頂いたURLを見て勉強したいと思います。

ありがとうございました!!

(morimori) 2023/03/07(火) 11:51:54


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.