フォームの表示位置を指定する
Windows APIを使ってフォームの表示位置を指定します。下記リンク先にて作成したカレンダーコントロールの表示位置が呼び出し元フォームのテキストボックスの位置に連動して変わるようにします。
【Access VBA】カレンダーコントロールの作成 - カットマンブログ

twipをpixelに変換する関数の記述
テキストボックスの位置がtwip単位で取得されるため、これをpixelに変換する関数を標準モジュールに記述します。下記サイトよりコピペしました。
Access VBA Form の位置、サイズはtwip単位で係数は567である #access - Qiita
Public Const SM_CYCAPTION As Long = 4
Public Const SM_CXFIXEDFRAME As Long = 7
Public Const SM_CYFIXEDFRAME As Long = 8
Public Const SM_CXFULLSCREEN As Long = 16
Public Const SM_CYFULLSCREEN As Long = 17
Public Const WU_LOGPIXELSX = 88
Public Const WU_LOGPIXELSY = 90
Public Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hwnd As LongPtr, ByRef lpRect As RECT) As LongPtr
Public Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Public Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As LongPtr
Public Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As LongPtr
Public Declare PtrSafe Function MoveWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As LongPtr
Public Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Public Declare PtrSafe Function GetClientRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As RECT) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public meRect_parent As RECT
Public meRect_client As RECT
Public ownerRect As RECT
Public Function ConvertTwipsToPixels(lngTwips As Long, lngDirection As Long) As Long
'Handle to device
Dim lngDC As Long
Dim lngPixelsPerInch As Long
Const nTwipsPerInch = 1440
lngDC = GetDC(0)
If (lngDirection = 0) Then 'Horizontal
lngPixelsPerInch = GetDeviceCaps(lngDC, WU_LOGPIXELSX)
Else 'Vertical
lngPixelsPerInch = GetDeviceCaps(lngDC, WU_LOGPIXELSY)
End If
lngDC = ReleaseDC(0, lngDC)
ConvertTwipsToPixels = (lngTwips / nTwipsPerInch) * lngPixelsPerInch
End Functionカレンダーフォームの開く時のイベントプロシージャの記述
Fカレンダーの開く時のイベントプロシージャに以下のコードを記述します。
Fカレンダーが画面の右側にはみ出す場合に、Fカレンダーの右端がテキストボックスの右端にくるようにしています。
Fカレンダーが画面の下側にはみ出す場合に、Fカレンダーの下端がテキストボックスの上端にくるようにしています。
Private Sub Form_Open(Cancel As Integer)
Dim leftPosition As Long
Dim topPosition As Long
Dim oForm As Object
Set oForm = Forms(Application.CurrentObjectName)
GetWindowRect Forms(Application.CurrentObjectName).hwnd, ownerRect
Dim meWidth_parent As Long
Dim meHeight_parent As Long
GetWindowRect Me.hwnd, meRect_parent
GetClientRect Me.hwnd, meRect_client
With meRect_parent
meWidth_parent = .Right - .Left 'Fカレンダーの幅
meHeight_parent = .Bottom - .Top 'Fカレンダーの高さ
End With
Dim leftPosition_owner As Long
Dim topPosition_owner As Long
Dim xframeWidth As Long
Dim titleHeight As Long
Dim leftPosition_textbox As Long
Dim topPosition_textbox As Long
Dim textboxWidth As Long
Dim textboxHeight As Long
Dim screenWidth As Long
Dim screenHeight As Long
Dim meWidth_client As Long
Dim meHeight_client As Long
leftPosition_owner = ownerRect.Left '呼び出し元フォームの左位置
topPosition_owner = ownerRect.Top '呼び出し元フォームの上位置
xframeWidth = GetSystemMetrics(SM_CXFIXEDFRAME) 'ウインドウの水平罫線の太さ
titleHeight = GetSystemMetrics(SM_CYCAPTION) 'タイトルバーの高さ
screenWidth = GetSystemMetrics(SM_CXFULLSCREEN) '全画面表示ウインドウのクライアント領域の幅
screenHeight = GetSystemMetrics(SM_CYFULLSCREEN) '全画面表示ウインドウのクライアント領域の高さ
meWidth_client = meRect_client.Right 'Fカレンダーのクライアント領域の幅
meHeight_client = meRect_client.Bottom 'Fカレンダーのクライアント領域の高さ
With oForm.Controls(OpenArgs)
leftPosition_textbox = ConvertTwipsToPixels(.Left, 0) 'テキストボックスの左位置
topPosition_textbox = ConvertTwipsToPixels(.Top, 1) 'テキストボックスの上位置
textboxWidth = ConvertTwipsToPixels(.Width, 0) 'テキストボックスの幅
textboxHeight = ConvertTwipsToPixels(.Height, 1) 'テキストボックスの高さ
End With
If leftPosition_owner + leftPosition_textbox > screenWidth - meWidth_parent Then
leftPosition = leftPosition_owner + leftPosition_textbox + textboxWidth - meWidth_client
Else
leftPosition = leftPosition_owner + leftPosition_textbox
End If
If topPosition_owner + xframeWidth + titleHeight + topPosition_textbox + textboxHeight > screenHeight - meHeight_parent Then
topPosition = topPosition_owner + topPosition_textbox - meHeight_client
Else
topPosition = topPosition_owner + xframeWidth + titleHeight + topPosition_textbox + textboxHeight
End If
MoveWindow Me.hwnd, leftPosition, topPosition, meWidth_parent, meHeight_parent, True
End Sub呼び出し元フォームのボタンクリック時イベントプロシージャの修正
呼び出し元フォームのボタンクリック時イベントプロシージャのOpenFormメソッドのOpenArgs引数にテキストボックスの名前を追加しました。
Private Sub btnCalendar_Click()
sDate = Nz(txtDate, 0)
DoCmd.OpenForm "Fカレンダー", , , , , acDialog, "txtDate"
If sDate <> 0 Then
txtDate = sDate
End If
End Sub












































