• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:エクセル2003VBAで時間稼ぎ(待機)をさせたいのですが、)

エクセル2003VBAで使える時間稼ぎ方法とは?

このQ&Aのポイント
  • エクセル2003VBAで時間稼ぎ(待機)をさせる方法について紹介します。
  • Sleep関数を使用すると、PCが固まることがあるため、他の時間稼ぎ方法を探しています。
  • 開くボタンのハンドルを取得するためには、時間のかかる処理を実行する必要があります。

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

spy++のしょぼいの -->[MiniSpy] というソフト名ですね。 VB Professional やC++などを持っていれば、本物のSpy+ があります。 このぐらいは正しい名前を表示しても良いと思いますし、省略ばかりでは、公開性の掲示板で質問している意味がないと思います。 前のところから読みなおしてみて、どうやら、CommonDialog から、ファイルメニューで、 hDlg = FindWindowA("#32770", "Open") '←CommonDialog 'ファイル名入力欄のハンドルを取得 hInput = FindWindowExA(hDlg, 0, "Edit", vbNullString) '子ウィンドウのハンドルが取る 'いきなりEditBox で、ハンドルが取れるのか分かりませんが、 OpenButton = FindWindowExA(hwindow, 0, "ToolbarWindow32", vbNullString) 一体、どこから、hWinodw が取れるのか、hDlg と結びつぎが得られません。 ここは、もしかしたら、メニューの中のファイルオープンのIDを取るのではないかと思います。 ループさせるというのは、賛成できません。何か、違つているような気がするだけです。IDが取れれば、はっきりしますが。 一応、「UWSC」については興味をもたれていないようですが、この記録マクロには、自動的に相手のソフトのIDを取ります。 GETID("Microsoft Excel","XLMAIN")こんな感じです。 GETID("ファイルを開く","bosa_sdm_XL9") このようにID等は、取れます。ただし、個々のコマンドのIDは取れませんので、リソースエディタなどを使い、メニューから、IDを取ります。 Waiting というのは、そのテクニック名で、いろんな方法があります。APIのSleep は、メモリ負担が少ないということです。 >Loop While hOpenButton = 0 この場合は、ループではなくて、If OpenButton<>0 Then というようなスタイルだけだと思います。いくら、Sleep を入れても、取れないと思うのです。 私としても、これ以上は、断片的な質問では、この問題は難しいのではないかと思います。

ddtqp
質問者

お礼

いつも解決するまで何度も的確なアドバイスありがとうございます!助かります。 おっしゃるとおりloop文をなくしてみたら、うまいこと動きました。 以前の回答で言われたとおり、sendmessageでもすこしつまずきました。 Application.Wait(Now + TimeValue("00:00:10"))の時間待ちも軽かったです。 IF文の使い方も助かりました。 GETID勉強になりました。「UWSC」も見てみました。 予算の都合がありますので、エクセル2003とVB2010の評価版でがんばります。 ‘メインウィンドウのハンドル取得 hMainWindow = FindWindowA("MX100STD_Viewer", "Data Viewer") ‘開くボタンのハンドル取得 OpenButton = FindWindowExA(hMainWindow, 0, "ToolbarWindow32", vbNullString) Sleep 1000 <開くボタンをクリック処理> Sleep 1000 'ファイルを開くダイアログのウィンドウハンドル取得 hOpenDlg = FindWindowA("#32770", "Open") 'ファイル名入力欄のハンドルを取得 hFNInput = FindWindowExA(hOpenDlg, 0, "Edit", vbNullString) 'ファイル名を入力 strFN = strFolderPath & strFileName(i) DoEvents Call SendMessageAny(hFNInput, WM_SETTEXT, 0, ByVal strFN) '開くボタンを押す hDlgOpenButton = FindWindowExA(hOpenDlg, 0, "Button", "開く(&O)") Call PostMessageA(hDlgOpenButton, WM_LBUTTONDOWN, MK_LBUTTON, 0) Call PostMessageA(hDlgOpenButton, WM_LBUTTONUP, MK_LBUTTON, 0) Sleep 1000 'メッセージ「同期処理を行いますか?・・・」 hMsg = FindWindowA("#32770", "情報") 'Yボタンのハンドル取得 hMsgYButton = FindWindowExA(hMsg, 0, "Button", "はい(&Y)") If hMsgYButton <> 0 Then '←メッセージが出ない時がある 'Y押す Call PostMessageA(hMsgYButton, WM_KEYDOWN, VK_Y, 0) Call PostMessageA(hMsgYButton, WM_KEYUP, VK_Y, 0) End If

すると、全ての回答が全文表示されます。

その他の回答 (5)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

#3の回答者です。 最初に直接の回答ではありませんが、他の回答者さんのために、私が把握している部分を説明しておきます。私としては、あまり無駄な書き込みも良くないし、こんなことで、無用なトラブルを見るものも好きではありません。ご質問者さんが詳しく正しい説明をしてくれれば、こんなコメントも不要なのですが……。 この質問内容で抜けている内容は、Excel VBAとは書かれていても、それは、外部ソフトをVBAで動かそうとしている話は、今回は書かれていないようです。それは、何を動かそうとしているか、三度目の質問でも公開されていません。 そういう私は、今回の質問はみえていないところがあります。 それは、 hOpenButton = FindWindowExA(hwindow, 0, "ToolbarWindow32", vbNullString) 子ウィンドウ・ハンドルでは、"ToolbarWindow32"に、直接ボタン・ハンドルなどはないような気がしています。そこは、ボタン名が入るはずです。 どんなソフトをお使いかは、公開するつもりはないようですので、そういう状況で、回答者側はきちんと回答出来ないように思います。あとは、経験的な知識で類推するしかない、極めて微妙なところです。この先のPostMessage/SendMessageでも、もう一難関が出てくるはずです。ただ、ここまで来て、全部、自力解決しているので、一体、こちらは何を書いているのか、虚しい気持ちになってしまいます。ある程度、こちらに下駄を履かせてくれればとは思いますが、ソフトがないことにはわからないかもしれません。 ソフトを外部コントロールするには、基本的には、Win32 APIぐらいしか手立てはないはずですが、もしも、そのソフトがオートメーションが可能なら、また話は別です。SendKey は、あくまでもExcel内部であり、AppActivate を使っても不可能です。目的のソフトウェアをアクティブ化して、WScript のSendKeyを使っても、ボタンを触らせないことがあります。 もしかしたら、このコードについては、開発ツールが必要な可能性があります。ボタンのリソースからロケーションを取らなくてはならないかもしれません。 しかし、前回書いたように、許せる環境なら、UWSC を考えているよりも遥かに簡単だと思います。

ddtqp
質問者

お礼

>hOpenButton = FindWindowExA(hwindow, 0, "ToolbarWindow32", vbNullString) >子ウィンドウ・ハンドルでは、"ToolbarWindow32"に、直接ボタン・ハンドルなどはないような気がし>ています。そこは、ボタン名が入るはずです。 この業者のソフトは、メニューの下に開くボタンが付いていて、「spy++のしょぼいの」というフリーソフトで調べると、クラスが"ToolbarWindow32"、キャプションが”Null”となっています。 このコードでハンドルが取得でき、実際開くことができるのです。 >ソフトを外部コントロールするには、基本的には、Win32 APIぐらいしか手立てはないはずですが、も>しも、そのソフトがオートメーションが可能なら、また話は別です。SendKey は、あくまでもExcel内>部であり、AppActivate を使っても不可能です。目的のソフトウェアをアクティブ化して、WScript >のSendKeyを使っても、ボタンを触らせないことがあります。 SendKeyはエクセル内部なのですね。わかりやすい説明ありがとうございます。 やはりAPIぐらいしか手立てなさそうですね。

すると、全ての回答が全文表示されます。
  • imogasi
  • ベストアンサー率27% (4737/17070)
回答No.4

エクセルVBA程度では余り難しいことをせず、待機と言うのは、操作者側に責任を押し付けて、操作するのを待って、操作されたイベントで再処理(続きの処理)をするように組み立てるのではないですか。 そういう方向では出来ないことですか。折角ウインドウハンドルなど意識しなくて良いようにVBAは作られているのに、なにをいまさら難しいことをいじくって、取り入れるのでしょう。 もう少し処理の長い幅で説明したら、VBAの範囲内で答えがでるような気がするが。

すると、全ての回答が全文表示されます。
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long) スコープについては分かっているとは思いますが、ここまで書くなら、Private か、Public ステートメントぐらいは使ってください。いきなりループじゃ、人には理解出来ません。 ある程度、まとまったコードで状況がわかるようなコードをだして、その使っている背景が書いてもらわない限りは、回答者は、必ず、そこに引っかかると思います。こちらでも、同様のコードは経験があるけれども、それだけではさっぱり理解できません。 ループでヒットさせるのは、いかにも乱暴な気がします。開く時に、相手側のソフトのタイムラグがあるなら、Waiting を使いますが、ふつうは、こういう場合は、ループは使いません。 ただ、もし、それで通るなら、Waiting を使う時には、DoEvents も入れます。 ただ、無限ループに入る可能性があるので、その予防策を置かなくてはなりません。Excel では、そのまま突っ込んでも、弾かれることがあります。 それと、「'開くボタンのハンドルを取得」で、  hOpenButton = FindWindowExA(hwindow, 0, "ToolbarWindow32", vbNullString) なぜ、"ToolbarWindow32"で、ボタンのハンドルが取れるのか、ここだけでは良くわかりません。このコードではありえないような気がしますが、たぶん、ソフト自体を試してみないとわからないような気がします。 >hInput = FindWindowExA(hDlg, 0, "Edit", vbNullString) こちらなら、良くあるコードですから、わかりますが。 それに、外部ツールを動かす方法としては、ショートカットやアクセスキーで動くものに関しては、そのツールをAPIでアクティブにしておいて、PostMessageあたりで、動かす手がないわけではないと思いますが、あまり、いじり回すよりも、 http://www.uwsc.info/ UWSC で、Excelから起動して動かす方法もあると思います。これはきちんとしたライセンスも貰えるそうですから、ちょっとお高いですが、会社で許可でるはずです。UWSC自体の内容は、キーボードマクロとは言いながらも、APIのオンパレードですから、APIがみえていないと使いこなせないと思います。 #1 さんのコード、取れていないというよりも、元の質問からでは、想像を逞しくしても同じ経験がないとわからないのです。何を使っているのかわからないからです。 MsgBox hWindow   ↓ MsgBox hOpenButton のはずです。だいたい、元のコードのToolBarWindow32 って、Windowsツールの一部で、Excelの中にはないような気がしますね。

ddtqp
質問者

お礼

>ループでヒットさせるのは、いかにも乱暴な気がします。開く時に、相手側のソフトのタイムラグがある>なら、Waiting を使いますが、ふつうは、こういう場合は、ループは使いません。 とてもよい回答ありがとうございます。 ボタン等が表示される前にコードが動いていて、ウィンドウハンドルが取得できていない気がします。 Waitingというものを調べてみます。 Sleepはボタンを押そうとしているソフトが止まってしまっている感じがします。 >それに、外部ツールを動かす方法としては、ショートカットやアクセスキーで動くものに関しては、その>ツールをAPIでアクティブにしておいて、PostMessageあたりで、動かす手がないわけではないと思いま>すが・・・ よい勉強になりました。覚えておきます。

すると、全ての回答が全文表示されます。
回答No.2

待機と言うことは何かを入力されるまで待たせると言うか待つだけですよね? ならば、ボタンを表示させるだけでいいと思います 上記の記述だと黙って1000ミリ秒止まっているだけでこの間にボタンが押されても何にもしないと思うのですが

ddtqp
質問者

お礼

回答ありがとうございます。 >待機と言うことは何かを入力されるまで待たせると言うか待つだけですよね? >ならば、ボタンを表示させるだけでいいと思います >上記の記述だと黙って1000ミリ秒止まっているだけでこの間にボタンが押されても何にもしないと思うのですが ちょっといじくって試してみます。

すると、全ての回答が全文表示されます。
  • mimeu
  • ベストアンサー率49% (39/79)
回答No.1

ん~~と、よく知らないんですけど ★ FindWindowEx って、非同期で動くんですかしら ? ★ それと、1秒も待たなければならないほど処理時間がかかりますか ? 一応   Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _     ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, _     ByVal lpsz2 As String) As Long   Sub test()     Dim hOpenButton As Long, hWindow As Long     hWindow = Application.Hwnd     hOpenButton = FindWindowEx(hWindow, 0, "ToolbarWindow32", vbNullString)     MsgBox hWindow   End Sub としてExcel2007VBAで動かしてみましたけど 即結果が出ましたよ。 見当違いでしたら、お許しを (^-^)

すると、全ての回答が全文表示されます。

関連するQ&A