UserForm を 「あるセルの上に表示」 という場合に、そのセルのスクリーン座標を
UserForm で指定する値に変換する関数です。
『#VALUE!』 『VBA ONLY』
ktCell2Position ( Target, [ PaneIdx ] )
返却値 ‥‥‥ Variant ( Array 関数 ) 型 Target ‥‥‥ Range 型 PaneIdx ‥‥‥ Integer 型 ( 省略可, 省略時: 0 )
Target のセル座標(セル枠の左上)をUserFormのTop/Left 値に変換し、 Array(Top, Left)
の配列として返します。 要素:0 が Top , 要素:1 が Left になります。 Top/Left は Long 型です。
Target のセルがウィンドウ 表示範囲外の場合は [ #VALUE! ] が返ります。
『 ウィンドウ 枠の固定/分割 』 を行なっている場合、エクセルバージョン によって動作が異なります。
・ 〜 Excel 2003
第 1 Pane (4分割ならば左上 , 上下分割ならば上部 , 左右分割ならば左側)のセルのみが
指定できます。
他 (第 2〜4 Pane )の領域のセルを指定すると [ #VALUE! ] が返ります。
・ Excel 2007 〜
第 1〜4 Pane の全ての領域のセルが指定できます。
ワークシート 関数 としてセルに記述すると [ #VALUE! ] が返ります (VBA専用関数です)。
Target ‥‥‥ UserForm を表示したい セル の Range オブジェクト を指定します。
セル範囲を指定した場合は先頭セル (左上セル) が対象になります。
Target のセルがウィンドウ表示範囲外の場合は [ #VALUE! ] が返ります。
PaneIdx ‥‥‥ 0 / 省略 : 分割なし or 対象領域 ( Pane ) の自動検出
1 : 左上 (4分割) or 左側 (左右分割) or 上側 (上下分割) の 領域
2 : 右上 (4分割) or 右側 (左右分割) or 下側 (上下分割) 〃
3 : 左下 (4分割) の領域
4 : 右下 (4分割) 〃
-- ウィンドウ枠の固定/分割 を行なっていない --
省略 (または 0 ) してください。 指定しても無視します。
-- ウィンドウ枠の固定 --
省略 (または 0 ) してください。 指定しても無視します。
対象領域 は Target から自動検出します。
※ 〜Excel 2003 では、対象領域 が 2 〜 4 の場合には
[ #VALUE! ] が返ります。
-- ウィンドウ枠の分割 --
省略(または 0 ) の場合は、アクティブ領域 を 対象領域 とします。
1 〜 4 を指定すると、指定の領域が 対象領域 となります。
分割枠の数以上の値を指定すると [ #VALUE! ] が返ります。
※ 〜Excel 2003 では、対象領域 が 2 〜 4 の場合には
[ #VALUE! ] が返ります。
セルのスクリーン座標 ( Top , Left ) と、UserFormの表示位置 ( Top , Left ) は、各々が使用する
座標の単位が異なる為に、セルのスクリーン座標 を、そのまま UserForm に使用する事はできません。
ktCell2Position 関数は、セルのスクリーン座標 ( Top , Left ) を UserForm の表示位置の座標
( Top , Left )に変換します。
-- ダブルクリック した セル の位置に UserForm を表示します --
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim vntPos As Variant
vntPos = ktCell2Position(Target)
If IsError(vntPos) Then
MsgBox "Error"
Cancel = True
Exit Sub
End If
Load UserForm1
With UserForm1
.StartUpPosition = 0
.Top = vntPos(0)
.Left = vntPos(1)
.Label1.Caption = Target.Address(False, False) & vbCrLf & vbCrLf & _
"CellTop = " & Target.Top & vbCrLf & vbCrLf & _
"CellLeft= " & Target.Left & vbCrLf & vbCrLf & _
"Top = " & .Top & vbCrLf & vbCrLf & _
"Left= " & .Left
.Show
End With
Cancel = True
End Sub
-- ktMsgBox での 利用 ( F5 セル の位置に表示) --
Dim vntPos As Variant
Dim vntTop As Variant
Dim vntLeft As Variant
vntPos = ktCell2Position(ActiveSheet.Range("F5"))
If IsError(vntPos) Then
'F5 セル が 表示範囲外 ⇒ Top/Left を省略
vntTop = Empty
vntLeft = Empty
Else
vntTop = vntPos(0) + 5
vntLeft = vntPos(1) + 5
End If
ktMsgBox "xxxxxxxx", vbOkOnly + vbInformation, _
Top:=vntTop, Left:=vntLeft
End If