
excel VBAで、
ユーザからの操作を待ち受け、操作に応じて外部アプリケーションを
起動し、外部アプリケーションウインドウのスクリーンショットを撮り、
保存するアプリを開発しています。
セルに保存したデータをパラメータとして外部アプリケーションに渡すために、
excel上での開発をしています。
当方、プログラミング歴は浅く、Cのポインタ、Javaのオブジェクト指向で頓挫し、
必要に迫られ、VBAとSwiftでコードを書きはじめた初心者です。
参考URL、同じような問題を解決した時の方法、前提知識の誤解の指摘等、皆様のお知恵を拝借いただけますと、幸いです。よろしくお願い致します。
<困ったこと>
・外部アプリケーションを起動し、スクリーンショット作成時に用いるwindowsAPIを
呼び出した時、オブジェクトが破棄されるため、処理が進まない
・オブジェクトの破棄は、UserFormを起動したタイミングでも起こっている模様
<知りたいこと>
・VBAコード全体でオブジェクト変数を保持するエレガントな方法を知りたい
・そもそも、VBAで外部アプリケーションとの連携をする際、
どのようなプログラム構造であるのが望ましいのか
(イベント駆動型のプログラムを書くときの作法 等)
<アプリケーションのイメージ>
UserFofmで作成したメニュー画面を表示
※マクロが入ったexcelファイルの起動時もしくは、別の起動用マクロからUserFormを表示。
ユーザ動作を待ち、UserFormに設置したコマンドボタンを押下した際、下記の処理を行う
コマンドボタン1(btnLaunch)押下時
別のアプリケーション(例えばIE)が起動する
コマンドボタン2(btnTakePicture)押下時
コマンドボタン1で起動したウインドウのスクリーンショットを撮る
※keybd_event(windowsAPI)を使用
コマンドボタン3(btnTerminate)押下時
VBAのコード全体が終了する
※コマンドボタン1で生成したアプリケーションのプロセスも正しく終了する
<アプリケーション全体の構造>
・メインのコードは標準モジュールmainに配置。
・mainモジュールから呼び出す関数は役割ごとに異なる標準モジュールに配置
・コマンドボタン押下時に起動するアプリケーションのオブジェクト変数は、
mainモジュールのグローバル変数として定義
<コード>
※細かい部分は省略しています
●mainモジュール
————————————————————————————
Option Explicit
'WindowsAPIの設定
'キーボード関係
Private Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, _
ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Function GetKeyboardState Lib "user32" _
(pbKeyState As Byte) As Long
Const VK_NUMLOCK = &H90 '「NumLock」キー
Const KEYEVENTF_EXTENDEDKEY = &H1 'キーを押す
Const KEYEVENTF_KEYUP = &H2 'キーを放す
'Sleep関数
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If
'ウインドウ制御関係
'cf. http://www.vba-ie.net/ie/foreground.html
Declare Function IsIconic Lib "user32.dll" (ByVal hWnd As Long) As Long
Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As Long) As Long
Declare Function ShowWindowAsync Lib "user32.dll" ( _
ByVal hWnd As Long, _
ByVal nCmdShow As Long _
) As Long
Const SW_RESTORE As Long = 9
'for event loop
Declare Function GetInputState Lib "user32.dll" () As Long
Public objIe As Object
Public menuKeyFlg As String
Public Sub init()
MainCtrl.Show
End Sub
Public Sub terminate()
Unload MainCtrl
‘その他、オブジェクトの破棄処理等
End Sub
Public Sub launch()
Set objIe = new_ie(***URL***)
ie_submit objIe
'無限ループにしておく
Do While True
If GetInputState() Then DoEvents
Sleep 500
Loop
End Sub
Public Sub takePicture(ByRef objIe As Object)
'ウィンドウが最小化されているかのチェック
If IsIconic(objIe.hWnd) Then
ShowWindowAsync objIe.hWnd, SW_RESTORE
End If
'IEを最前面に表示
SetForegroundWindow (objIe.hWnd)
'・ウインドウ全体のスナップショットを作成
‘ウインドウの表示イメージをクリップボードに保存
Call keystroke
Call saveClipBoard
End Sub
Private Sub keystroke()
' alt+PrtScreenを模擬し、クリップボードに保存
keybd_event VK_LMENU, 0&, fKEYDOWN, 0& 'Altキーを押す
keybd_event vbKeySnapshot, 0&, fKEYDOWN, 0&
keybd_event vbKeySnapshot, 0&, fKEYUP, 0&
keybd_event VK_LMENU, 0&, fKEYUP, 0& 'Altキーを離す
End Sub
Private Sub saveClipBoard()
クリップボードの中身を画像ファイルとして書き出す
**内容省略**
End Sub
●UserFormモジュール
————————————————————————————
Private Sub btnLaunch_Click()
call launch
End Sub
Private Sub btnTakePicture_Click()
call takePicture
End Sub
Private Sub btnTerminate_Click()
call terminate
End Sub
Private Sub UserForm_Initialize()
call init
End Sub
A 回答 (1件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
コードの詳細をよく読んでいないのですが……
> Public Sub takePicture(ByRef objIe As Object)
と引数objIeを必要とする定義にしているのに
> Private Sub btnTakePicture_Click()
> call takePicture
> End Sub
呼ぶ側で引数を与えていないのは変ですよね?
そもそもobjIeは、広域変数として宣言しているのでtakePictureの定義では引数は不要ではないでしょうか?
siffon9さん ご回答ありがとうございます。
仰るとおりですね。投稿した際に使ったコードが古いものでした。
Public Sub takePicture で定義しています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
フレームワーク「4.8.1」で、[S...
-
vcxprojファイルの修正法???
-
Windowsプログラムのビジー状態...
-
SetWindowPosについて
-
外字文字の登録
-
Vba アプリケーションが立ち上...
-
MFCアプリケーションでの終了コ...
-
FOM出版の公認テキスト&問題集...
-
VB6での二重起動(複数起動)の制...
-
対象のアプリケーションが終了...
-
pccNTmon.exeとntrtscan.exeの違い
-
Macターミナルで実行中のプログ...
-
VBAの配列サイズとメモリに関して
-
winsockでソケット通信の開発を...
-
メッセージボックスのボタン名変更
-
VB.NETで起動したExcelの閉じ方...
-
DoEvents関数って何?
-
C言語で、メモリを解放しないで...
-
ACCESS側からEXCELの書式を設定...
-
メモリが不足しています(VBA)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WSH(VBScript)でアプリケーショ...
-
フレームワーク「4.8.1」で、[S...
-
VB.NETでMessageBoxを表示した...
-
コンソールアプリケーションの...
-
SetWindowPosについて
-
pccNTmon.exeとntrtscan.exeの違い
-
Accessフォームからの外部アプ...
-
初回接続の遅い原因について
-
Console Applicationをタスクト...
-
VBSでのSendKeysでの画面の最小化
-
Vba アプリケーションが立ち上...
-
イラストレーターCS4のシリアル...
-
MFCアプリケーションでの終了コ...
-
実行時のコマンドプロンプトを...
-
C#でGUI・CUIの判断する仕方を...
-
アプリケーションをVBS(WSH?)で...
-
OSによるWinExecの動...
-
vb6で異なるのプロジェクト間で...
-
SYSTEM権限でプロセス機動
-
VB.NETでフォームアクティブの...
おすすめ情報