エクセルVBAのユーザーフォームは、エクセルの中央に表示されるのがデフォルトになっています。
しかし、セルをダブルクリックして入力値をユーザーフォームから選択するような場合、ダブルクリックしたセルの近くにユーザーフォームを表示させたくなります。
ネットを検索すると、さまざまな方法が紹介されていますが、私のニーズに合うものは見つかりませんでした。
私のニーズは次のとおりです。
- コードがシンプルであること(こんなことに何10行もコードを書くのはいやだ)
- ダブルクリックしたセルの近くに表示されること(別にピッタリと一致していなくても良い)
- エクセルのウィンドウが最大表示以外の場合でも、エクセルのウィンドウ内に表示されること(そのためにセルとの位置関係がズレても構わない)
- ウィンドウ枠が固定されている場合でも正常に動作すること(これが結構難しい)
いろいろと試行錯誤した結果、次のコードで実現できました。
'アクティブウィンドウを対象
With ActiveWindow
'対象セルの画面上の位置を把握する
Dim x As Double, y As Double
x = Target.Left - .VisibleRange.Left + .Left + 460 '数値の値はシートごとに修正
y = Target.Top - .VisibleRange.Top + .Top + 124 '数値の値はシートごとに修正
End With
'ユーザーフォームを対象
With CalendarForm
'表示位置を設定する
.StartUpPosition = 0
.Left = x
.Top = y
'表示する
.Show
End With
「Target」はダブルクリックしたセルです。
「VisibleRange」は固定されたウィンドウ枠の表示範囲です。(ウィンドウ枠が固定されていない場合や固定されているウィンドウ枠の内側に対象セルがある場合は、この部分が不要です。)
これらの差に「ActiveWindow]自体の位置を加えることで、ダブルクリックしたセルの相対的な位置の変化量を把握することができます。
問題は「460」とか「124」とかの数値です。
これらは画面上の絶対的な位置の調整値で、条件を変えながらユーザーフォームを表示させてウィンドウ内に収まる値を探ったものです。(ウィンドウ枠やリボン下端などの位置によって変化します。)
ここまでできれば、あとは求めた値をユーザーフォームに設定して表示するだけです。
むちゃくちゃ適当ですが、私のニーズを満たすためにはこれで十分でした。(これをちゃんとやろうとすると、恐ろしく面倒なことになります。)
こんな適当な方法じゃなくて、ちゃんとやりたい方はこちらをどうぞ!
コメント