[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『別ブックのユーザーフォームにチェックを入れたい』(ななな)
現在作成中の「Book1.xlsm」と既存のツール「Tool.xlsm」があります。
「Tool.xlsm」は開くとユーザーフォーム(Form1)がモードレスで立ち上がるように
なっています。
やりたいことは
1.「Book1.xlsm」から「Tool.xlsm」を起動
2.「Tool.xlsm」で表示されたユーザーフォームのCheckBox1にチェックを入れる
3.「Tool.xlsm」で表示されたユーザーフォームのCommandButton1をクリックする
の3つです。
1はWorkbooks.Openで済むので問題ないのですが、
2と3をやる方法がわかりません。
「Tool.xlsm」自体のコードを触ることはできません。
「Tool.xlsm」で表示されたユーザーフォームのCheckBox1はFrame1内にあります。
「Book1.xlsm」から以上のことを行いたいのですがどのようにしたらいいでしょうか?みなさまのお知恵を貸してください。
< 使用 Excel:Excel2016、使用 OS:Windows10 >
>「Tool.xlsm」自体のコードを触ることはできません。 ということだと、別なアプリを操作するようなものなので、かなり厳しいです。
コードを触ることができないのに、CheckBox1 とか、CommandButton1 とか コントロールの名前がわかっているのはなぜですか?
編集しちゃいけなくても、コードを見れるなら、ごっそりコードをコピーすれば いくらでも好きに改造できるとおもいますが。 (´・ω・`) 2021/11/09(火) 13:57
「Tool.xlsm」は汎用的に使用されているもので
私どもの一存で改修等入れることはできないものです。
ですので、改造はおろか、コードそのものも見ることができません。
ハンドルの取得も検討したのですが、Frame以外のコントロールの
ハンドルは取得できずで困っています。
(ななな) 2021/11/09(火) 14:22
>改造はおろか、コードそのものも見ることができません。 Tool.xlsmに、独自のSubプロシジャを追加できるなら簡単ですが、 それができないなら、私にはいい方法がありません
UserFormのコマンドボタンをクリックしたあとに実行されるプロシジャが もし標準モジュールにあるなら、ワンチャンあるかもという感じです。
>ハンドルの取得も検討したのですが、Frame以外のコントロールの >ハンドルは取得できずで困っています。 Windows API は私は全く詳しくないので、お力になれずすみません
詳しい回答者が登場されるのをお待ち下さい。 (´・ω・`) 2021/11/09(火) 14:41
> UserFormのコマンドボタンをクリックしたあとに実行されるプロシジャ
についても、フォームモジュール内の様でしたので直接実行することも
叶いませんでした。
(ななな) 2021/11/09(火) 14:49
そこまで詳しくないので無理ならばすまない。
>1.「Book1.xlsm」から「Tool.xlsm」を起動 ということであればWorkbooks.Open時にWorkbookオブジェクト変数に開いたブックを代入する。 で、 >CheckBox1 >CommandButton1 ということはActiveXコントロールだと思うので上記のWorkbookオブジェクトを通してCommandButton1_Clickプロシージャなどを 実行できないだろうか? (ねむねむ) 2021/11/09(火) 14:51
ねむねむさん シート上に配置されたコントロールであれば可能性はあるかもしれません(未検証です)が、 UserForm上のコントロールは見えないんです (´・ω・`) 2021/11/09(火) 14:56
WindowsAPIのUser32.dllを使ってマウスの自動操作を考えてみました。 ユーザフォームの位置が常に同じ位置に表示されないとうまく動かないと思いますが一案として。 API初めて使ったので色々間違ってるかも知れません…。
--------------------------------------------------------- 'カーソル位置設定 Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
'マウス操作 Declare PtrSafe Sub mouse_event Lib "user32" ( _ ByVal dwFlags As Long, _ Optional ByVal dx As Long = 0, _ Optional ByVal dy As Long = 0, _ Optional ByVal dwData As Long = 0, _ Optional ByVal dwExtractInfo As Long = 0)
Sub test()
'----------------------------------------------------------- '事前にTool.xlsmのウィンドウをアクティブ化、最大化しておく '-----------------------------------------------------------
'カーソル移動 'ユーザフォームの表示位置はTool.xlsmのウィンドウ位置に対して一定だと思うので、 'これの引数をCheckBox1、ComboBox1の位置になるよう調整する。 'この例では200がモニタ左端からのピクセル数、 '500がモニタ上からのピクセル数を示しています。 SetCursorPos 200, 500
'マウス左ボタン押下 mouse_event 2
'マウス左ボタン離す(押下と併せて1回クリック) mouse_event 4
End Sub (さくさくアジフライ) 2021/11/09(火) 15:25
余談ですが、Tool.xlsmを編集できる場合の方法の一つです
Tool.xlsm のVBE画面で、 ツール→ VBAProjectのプロパティでプロジェクト名を設定 UserFormをエクスポートして、UserForm1.frm をテキストエディタで開いて 以下の設定にする(全部Trueにしないといけないかどうかはよくわからないけどとりあえず全部True)
Attribute VB_Name = "UserForm1" Attribute VB_GlobalNameSpace = True Attribute VB_Creatable = True Attribute VB_PredeclaredId = True Attribute VB_Exposed = True
UserForm1.frmをインポートし直す Book1.xlsmで、 Tool.xlsm を参照設定する そうすると、 Book1.xlsmでは、
Dim f As TestProject.UserForm1 ' プロジェクト名は、最初に設定したプロジェクト名 Set f = New TestProject.UserForm1 f.Show
と、できます こんな感じです
Tool.xlsm に必要なSubプロシジャを追加してそれをCallするのが一番簡単ですが... (´・ω・`) 2021/11/09(火) 16:28
さくさくアジフライさん、
ユーザーによってモニタが複数台あって表示位置が全員同じ位置とはなりませんでした。
(´・ω・`)さん、
Dim f As TestProject.UserForm1
のところで「ユーザー定義型は定義されません。」と怒られます。
TestProject. の中にUserForm1がなく(Sheet1とかはある)、先に進めませんでした。
ねむねむさんもありがとうございます。
(ななな) 2021/11/11(木) 16:45
TABキーでユーザーフォーム上のコントロールを巡回できる仕様なら 単純にSendKeysで何とかなる場合もあったりなかったり...?
'=============================================================================================== '[UserForm1]モジュール(Tool.xlsm) -------------------------------------------------------------- Option Explicit Private WithEvents CommandButton1 As MSForms.CommandButton Private CheckBox1 As MSForms.CheckBox
Private Sub CommandButton1_Click() MsgBox "CommandButton1_Click" End Sub
Private Sub UserForm_Initialize() Set CheckBox1 = Me.Controls.Add("Forms.CheckBox.1", "CheckBox1") With CheckBox1 .Top = 3 .Left = 3 .Width = 96 .Caption = .Name End With Set CommandButton1 = Me.Controls.Add("Forms.CommandButton.1", "CommandButton1") With CommandButton1 .Top = 24 .Left = 3 .Width = 96 .Caption = .Name End With End Sub '[ThisWorkbook]モジュール(Tool.xlsm) ----------------------------------------------------------- Option Explicit Private Sub Workbook_Open() UserForm1.Show vbModeless End Sub '===============================================================================================
'標準モジュール(Book1.xlsm) -------------------------------------------------------------------- Sub test() Workbooks.Open "C:\xxx\Tool.xlsm" Application.SendKeys " {TAB} " 'CheckBox1でスペース → タブ → CommandButton1でスペース End Sub
(白茶) 2021/11/11(木) 18:33
ユーザフォームのウィンドウハンドルを取得して、 ユーザフォームの左上の位置を特定、 そこから相対的に操作したいコントロールの位置を 指定する方法にしてみました。
---- Option Explicit
Private Type POINTAPI x As Long y As Long End Type
Private Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type
Private Type WINDOWSPLACEMENT Length As Long flags As Long showCmd As Long ptMinPosition As POINTAPI ptMaxPosition As POINTAPI rcNormalPosition As RECT End Type
'ハンドルを取得 Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) _ As Long
'ウィンドウ位置を取得 Private Declare PtrSafe Function GetWindowPlacement Lib "user32" ( _ ByVal hwnd As Long, _ lpwndpl As WINDOWSPLACEMENT) _ As Long
'カーソル位置設定 Declare PtrSafe Function SetCursorPos Lib "user32" ( _ ByVal x As Long, _ ByVal y As Long) _ As Long
'マウス操作 Declare PtrSafe Sub mouse_event Lib "user32" ( _ ByVal dwFlags As Long, _ Optional ByVal dx As Long = 0, _ Optional ByVal dy As Long = 0, _ Optional ByVal dwData As Long = 0, _ Optional ByVal dwExtractInfo As Long = 0)
Sub test()
Dim myHwnd As Long Dim myWindowPlacement As WINDOWSPLACEMENT
'ハンドル取得 '------------------------------------------------------------ '「★★★」にフォームのタイトルバーに表示されている名称を記入 '------------------------------------------------------------ myHwnd = FindWindow(vbNullString, "★★★")
'ハンドルに対応するウィンドウ位置取得 GetWindowPlacement myHwnd, myWindowPlacement
With myWindowPlacement.rcNormalPosition
'カーソル移動 '------------------------------------------------------------------------ '◆、■の値を調整して操作したい項目の上にカーソルが来るようにしてください '------------------------------------------------------------------------ SetCursorPos .Left + ◆, .Top + ■
End With
'------------------------------------------------------------------------ '押下処理はカーソル位置が調整できてからコメント解除した方がいいと思います '------------------------------------------------------------------------ ' 'マウス左ボタン押下 ' mouse_event 2 ' ' 'マウス左ボタン離す(押下と併せて1回クリック) ' mouse_event 4
End Sub (さくさくアジフライ) 2021/11/12(金) 09:41
他の方の提案で、やりたいことが… 実現出来なかった場合は参考にしてください。*_ _))ペコ
>「Tool.xlsm」は開くとユーザーフォーム(Form1)がモードレスで立ち上がるように > なっています。
えと〜もしかしたら? ですが… モーダル( vbModal )と、モードレス ( vbModeless )では違いがあるのではないでしょうか?
[ThisWorkbook] モジュール ( Tool.xlsm ) において
Option Explicit Private Sub Workbook_Open() UserForm1.Show vbModeless End Sub
↑これだとエラー連発で 実行エラー'91 オブジェクト変数または With ブロック変数が設定されていません
ですが、 UserForm1.Show なら下記のコードで CheckBox1 の [ ON or OFF ] 切替が可能でした。 App = "C:\Users\user\Desktop\Tool.xlsm" ← ここは「摘便」変更してください。
Option Explicit Sub Sample() Dim App As String Dim AppTool As Object Dim VBProject As Object App = "C:\Users\user\Desktop\Tool.xlsm" Set AppTool = Workbooks.Open(App) 'Application.Run AppTool.VBProject.VBComponents("UserForm1").Designer.Controls("CheckBox1").Value = True '' True or False
Dim buf As String '' VBProjectの操作 With ActiveWorkbook buf = buf & .VBProject.Name & vbCrLf buf = buf & .VBProject.Filename & vbCrLf buf = buf & .VBProject.Protection & vbCrLf End With MsgBox buf End Sub
現在、私が思う有力な方法としては、(´・ω・`)さんのおっしゃっている方法で > Tool.xlsm に必要なSubプロシジャを追加してそれをCallするのが一番簡単ですが... と同じような意味なのですが…
UserForm1.Show vbModeless ←部分をVBAで置換する、または、削除して UserForm1.Show にして Tool.xlsm に必要なSubプロシジャを追加するか、Sample のようなコードで操作するかですかね?
(あみな) 2021/11/12(金) 12:47
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.