質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1619閲覧

VBAで動的に作成したコントロール操作等の処理をPython(Tkinter)で実現するには?

kannon198

総合スコア0

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/09/16 03:54

実現したいこと

訳あってVBAで作成した業務システムをPythonに移行する必要に迫られています。
フォーム上のボタンなどのコントロールをクリックする等によって、同一フォーム上の別のコントロールの挙動を操作する、といった処理です。

ロジックは、次ような流れです。

  1. コントロールを動的に追加(ボタン、テキストボックス、ラベル、チェックボックス等)
  2. 生成したコントロールをラッパークラスのインスタンスに紐づけ
  3. 2のインスタンスをDictionaryオブジェクトに代入。Keyは自動生成されたNameプロパティを使用。

操作させたい関連コントロールのインスタンス名も、オリジナルプロパティ(RelationCtrl:コレクション)に保存。
4. 必要な時、Keyを基にして都度Dictionaryオブジェクトから取り出し、関連コントロールのインスタンスを操作する。

上記のような処理をPython(Tkinter)で書くにはどのようにすればよいのか、ご経験のある方、ご教示頂ければ幸いです。

該当のソースコード

非常に長くなるので、要点のみ抜粋します。細かい部分は端折っているので、ロジックのみご覧頂ければ幸いです。変数名も、分かりやすいように適当に変えてあります。

VBA

1'クラスモジュール - CommandButtonWrapper 2Private WithEvents InnerCommandButton As MSForms.CommandButton 3'---以下略 4Public Sub SetControl(CommandButton_New As MSForms.CommandButton) 5 Set InnerCommandButton = CommandButton_New 6'---中略 7end sub 8'以下略 コマンドボタンの他、ラベル、テキストボックスなど他コントロールも同様にクラス化して、オリジナルのメソッド・プロパティを大量に追加 9'クリックイベントなども、クラスに記述 10Private Sub InnerCommandButton_Click() 11 Call UserForm1.CommandButton_CLICK(Me) 12End Sub 13 14'ユーザーフォーム 15Private CtrlDic As Object 16'---中略 17Private Sub ControlInitialize() 18Dim Ctrl As Control 19Dim MyButton As CommandButtonWrapper 20 CtrlDic = = CreateObject("Scripting.Dictionary") 21 Set Ctrl = UserForm1.Controls.Add(TypeControl("Forms.CommandButton.1")) 22 Set MyButton = New CommandButtonWrapper 23 '独自メソッド SetControl で紐づけ 24 MyButton.SetControl Ctrl 25 '自動生成されたKeyで、インスタンスを辞書に代入 26 CtrlDic.Add Ctrl.Name, MyButton 27'---中略 各種プロパティに代入 28 Set MyButton = Nothing 29'---以下略 30End Sub 31'関連する他のコントロールを操作するとき For each やオリジナルのRelationCtrlプロパティでKeyを取得し、当該インスタンスを取得する 32'Keyが格納されているRelationCtrlプロパティを使う例 33Public Sub CommandButton_CLICK(MyCtrl As CommandButtonWrapper) 34'クリックイベントを受け取るプロシージャ 35'---中略 36 CtrlDic(MyButton.RelationCtrl(1)).Enabled = True 37'---以下略 38End Sub 39 40'For Eachで操作する例 ※CtrlTypeはオリジナルのプロパティ 41Dim DicKey as Variant 42Const TITLELABEL as Integer = 1 43 44 For Each DicKey In CtrlDic 45 If CtrlDic(DicKey).CtrlType = TITLELABEL Then 46 CtrlDic(DicKey).Visible = True 47 End If 48 Next

どうぞよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました

  1. コントロールを動的に追加(ボタン、テキストボックス、ラベル、チェックボックス等)

→フレームにButtonなど設置するだけなので容易に実現
2. 生成したコントロールをラッパークラスのインスタンスに紐づけ
→bindメソッドとeventで実現
3. 2のインスタンスをDictionaryオブジェクトに代入。Keyは自動生成されたNameプロパティを使用。
操作させたい関連コントロールのインスタンス名も、オリジナルプロパティ(RelationCtrl:コレクション)に保存。
→生成したウイジェットをDict型に格納。ユニークKeyをどうするか難儀したが、winfo_idメソッドで取得できたので、これをKeyとして使用することで解決。
4. 必要な時、Keyを基にして都度Dictionaryオブジェクトから取り出し、関連コントロールのインスタンスを操作する。
→コールバック側でもevent.widgetからwinfo_idでKeyを取得できるので、Dict型から関連するウイジェットを呼び出せた。

投稿2021/09/17 02:08

kannon198

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問