ユーザーフォームとワークシートの不一致を解消する
昨日は、シート上でのオートシェイプ選択結果と、ユーザーフォームのリストボックス項目を介してのオートシェイプ選択結果を、等しくユーザーフォームのリストボックスに反映させてみました。
infoment.hatenablog.com
今日は、今のところ唯一残った「不一致」部分の解消に挑戦です。
今日やりたいこと
リストボックス内の項目が一つ以上選択状態の場合であって、うっかりセルを選択すると、以下の不一致が発生します。
- シート上では、全てのオートシェイプが選択解除される
- リストボックス上では、依然として選択が保持されている
そこで、以下手順による問題解決を図りました。
- シートが選択されたことを検知する
- ユーザーフォームが表示されている場合だけ、リストボックスの項目選択状態を解除する。
必要なこと
- ユーザーフォームの表示状態を確認する
- シートのイベントで、オートシェイプの全解除を検知する
- リストボックスの選択状態を解除する
- ユーザーフォームを閉じる際の処理を追加する
1.ユーザーフォームの表示状態を確認する
昨日は、以下の方法でユーザーフォームが非表示であることを確認していました。
If EditChartForm.Visible = False Then EditChartForm.Show vbModeless End If
しかし実は、
If EditChartForm.Visible = False Then
の部分で、ユーザーフォームが表示されてしまいます。この場合は「都度再表示しない」ことが目的であったため、問題ありませんでした。しかし今回は、表示されている場合を検知したいので、上記では不適切です。このまま利用すると、シートのどこかを選択するたびに、ユーザーフォームが表示されてしまいます。
- 表示されています
⇒ では、もう表示しなくていいです。
⇒ 表示されていてOK - 表示されていません
⇒ では、何もしないでください。
⇒ 表示されるとNG(「何か」をされてしまうため)
そこで今回は、Public変数でフラグを立てることにしました。様々な記事で「NG方法」として紹介されていた記憶があるのですが、今回はこれ以上の手段を思いつけませんでした。
【標準モジュール】
Option Explicit Public EditChartFlag As Boolean
- 表示中 ⇒ True
- 非表示 ⇒ False
【クラスモジュール】(EditChartClass)
次いで、クラスの初期化部分を変更します。ここで、ユーザーフォームを表示させたうえで、フラグを True に切り替えています。
Private Sub Class_Initialize() If EditChartFlag = False Then EditChartForm.Show vbModeless EditChartFlag = True End If End Sub
2.シートのイベントで、オートシェイプの全解除を検知する
シート上の操作でオートシェイプが全解除されるのは、いずれかのセルを選択したときです。従って今回は、シートモジュールのSelectionChangeイベントを利用します。
【フローチャートを作成するシートのシートモジュール】
先ほどのフラグを利用することで、ユーザーフォームが表示されている時だけ以下を行います。
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If EditChartFlag = True Then ' リストボックスの選択を解除する処理 End If End Sub
3.リストボックスの選択状態を解除する
上記の「リストボックスの選択を解除する処理」は、今回以下の手順で行います。
- リストボックスの内容を一旦クリア
- 改めてリストをセット
【フローチャートを作成するシートのシートモジュール】
先ほどのフラグを利用することで、ユーザーフォームが表示されている時だけ以下を行います。
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If EditChartFlag = True Then Dim EChC As EditChartClass Set EChC = New EditChartClass EditChartForm.ListBox1.Clear EditChartForm.ListBox1.List = EChC.ShapeList End If End Sub
折角なので、昨日作成したクラスモジュールの「リストボックス用のリスト」を流用しました。
4.ユーザーフォームを閉じる際の処理を追加する
ユーザーフォームを閉じる方法は、現時点で以下の二つです。
- 「終了」ボタンを押す
- 「×」ボタンを押す
そこでそれぞれに、フラグを False にする処理を追加します。
【ユーザーフォームのモジュール】(EditChartForm)
「終了」ボタン
Private Sub EndButton_Click() EditChartFlag = False Unload Me End Sub
「×」ボタン
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) If CloseMode = 0 Then EditChartFlag = False End If End Sub
結果
シート選択によるオートシェイプの全解除が、ユーザーフォームのリストボックスに反映されるようになりました。
(静止画像で結果が分かりにくいのは、相変わらずです)。
次回に続きます。
参考まで。