• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:アクセス2010VBA側から他のプログラムを操作)

アクセス2010VBAで他のプログラムを操作する方法

このQ&Aのポイント
  • アクセス2010VBAで他のプログラムを操作したい場合、FindWindow関数やFindWindowEx関数を使用することで他のプログラムのウィンドウハンドルを取得することができます。しかし、正しくウィンドウハンドルを取得できない場合があります。
  • 具体的には、FindWindowEx関数が正しく機能しないことがあります。これは、引数に渡すウィンドウクラス名やウィンドウタイトルの指定に問題がある可能性があります。
  • 将来的にはSendMessage関数を使用して他のプログラムを制御することも可能ですが、アクセス2010での実現可能性については疑問が残ります。

質問者が選んだベストアンサー

  • ベストアンサー
  • kumatti1
  • ベストアンサー率60% (73/121)
回答No.5

回答でなくてただの余談なのですが、電卓(に限りませんが)はWindowsのバージョンによってつくりがマチマチで、 (トップレベルのウィンドウクラスも違う) 例えばWin8だとボタンには、ウィンドウタイトルも無かったりします。 なのでコントロールIDで特定する事になりますが、ウィンドウツリーもそう単純でないとすると、AutomationIdで検索可能なUI Automationの方がいいのではと思ったりもします。 (VBAだと UIAutomationCore.dll に参照設定) ※ リンク先はJScript.NETです。

参考URL:
http://180.cocolog-nifty.com/blog/2011/10/ui-automationjs.html
situmonnsya
質問者

お礼

>Windowsのバージョンによってつくりがマチマチで そうなんですか。 できたとしても、バージョンちがいにも対応したいので、私には少し道のりが遠いみたいです。 他のプログラムを操作といっても、そちらも自作ソフトなので、他の方法を考えます。 ありがとうございました。

その他の回答 (4)

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.4

No3です。 AccessではNo3の一番目のWEBページの モジュールで、ボタンクリック時のイベントを 以下のようにしています。 Private Sub コマンド0_Click()   Dim lngWindWnd As Long   Dim ret As Long   Dim hCalc As Long    'ウィンドウハンドルを得ます   lngWindWnd = FindWindow(vbNullString, "電卓")    '電卓「1」ボタンのハンドル   hCalc = FindWindowEx(lngWindWnd, 0, "Button", "1")   If hCalc <> 0 Then     MsgBox "電卓は起動されています"   Else     MsgBox "電卓は起動されていません"   End If   '電卓を前面に表示   ret = SetForegroundWindow(lngWindWnd)    'ボタンクリックの設定   'ret = PostMessage(hCalc, WM_LBUTTONDOWN, MK_LBUTTON, ByVal 0)   'ret = PostMessage(hCalc, WM_LBUTTONUP, MK_LBUTTON, ByVal 0)   ret = SendMessage(hCalc, WM_LBUTTONDOWN, MK_LBUTTON, ByVal 0)   ret = SendMessage(hCalc, WM_LBUTTONUP, MK_LBUTTON, ByVal 0) End Sub

situmonnsya
質問者

お礼

皆様、ありがとうございました。

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.3

WEBを少し念入りに探せば例はいくらでもあります。 たとえば、 http://homepage1.nifty.com/MADIA/vb/vb_bbs2/200601/200601_06010010.html http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/vb_t02.htm などはほとんどズバリの内容だと思いますが。 一応、上記はVB6なので確認のためにVB6で走らせてみました。 一番目の場合は、Formにモジュールも設定して、Formの ロード時にコードを走らせていますが、ボタンクリック でも同じです。Accessで確認したところ、同様にモジュールを ボタンクリックで機能しました。 Spy++で確認すると、 電卓本体 キャプション(電卓) クラス名(SciCalc) 5のボタン キャプション(5)  クラス名(Button) などとなっています。 FindWindowExの定義は、  Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _     (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _     ByVal lpClassName As String, ByVal lpWindowName As String) As Long のようになっているので、 tt = FindWindowEx(tw, 0, "Button", "5") のように記述するのではと思いますが。 あとは、ボタンダウン、ボタンアップの定数を PostMessage関数に設定すればいいのでは。 なお、PostMessageをSendMessageに置き換えても 機能します。 なお、こちらではOSはXPなので、電卓のボタンには キャプションが設定してあります。

  • kumatti1
  • ベストアンサー率60% (73/121)
回答No.2

> tt = FindWindowEx(tw, 0&, "5", "") ウィンドウタイトルは第四引数です。 (ウィンドウクラスも指定した方が無難) ちなみに""とvbNullStringは等価ではありません。 (FindWindow系では普通、「""」は使わない)

参考URL:
http://d.hatena.ne.jp/maeyan/20091227/1261848549
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.1

子猫な自分なので、Win32APIの深いところは分かりませんが、気付いたところだけ... 下記は5のボタンのハンドルを取得しようとしているのでしょうか? tt = FindWindowEx(tw, 0&, "5", "") 電卓を起動した状態で、下記コードをExcelで実行してみて下さい。 ウィンドウ(含む子ウィンドウ)を列挙するコードです。 http://d.hatena.ne.jp/cartooh/20090618 実際のボタン以上にボタンがあって、どれがどれだか特定できませんが、(普通の電卓用と、関数電卓用に別のボタンを切り替えて表示しているのかも)、すべてclassnameはButtonであり、ボタンの文字はウィンドウのタイトルではなさそうです。 また、ボタンは電卓の「子」ではなく、曾孫位にあたりそうです。 >将来的に、SendMessage(tw, ~~~)として他プログラムを制御したいのですが、 >アクセス2010で可能でしょうか? エクセルのUserFormのコントロールがハンドルを取得できない様に、限界がありますのでご留意下さい。

situmonnsya
質問者

お礼

>ボタンは電卓の「子」ではなく、曾孫位 >限界がありますのでご留意 そうですか。 Delphiでも実験しているのですが、うまくいくとボタンといかないものがありました。 他の方法を考えた方がいいみたいですね。 ありがとうございました。