I have an Excel 2007 VBA project with several userforms, one of which is a date picker containing a Calendar Control 12.0 object. The date picker is activated whenever the user clicks one of two textbox controls on one of the other forms. I want to control the startup position of the date picker such that, when shown, it appears in line with whichever textbox control has been clicked.
To do this, the date picker userform (frmDatePicker
) exposes three public vars: xOffset
, yOffset
and frmParent
. The intent is that, before frmDatePicker
is shown, its .Top
and .Left
properties will be set by reference to these three vars, which are themselves initialised by the calling sub. (The userform's .StartUpPosition
property is also set to zero (i.e. "Manual") to allow its initial position to be controlled in this way.)
This works perfectly... except for the first time the date picker is shown. The first time the .Show
method is invoked, frmDatePicker
does not align with the clicked textbox. From the second time onwards this problem disappears.
frmDatePicker
's code is as follows:
Option Explicit
Public InitialDate As Variant
Public xOffset As Double
Public yOffset As Double
Public frmParent As Object
Private DateSelected As Boolean
Function Execute() As Boolean
If Not frmParent Is Nothing Then
Me.StartUpPosition = 0
Me.Left = frmParent.Left + xOffset
Me.Top = frmParent.Top + yOffset
End If
If Not IsDate(InitialDate) Then InitialDate = DateSerial(Year(Now), Month(Now), 1)
calPickDate.Value = InitialDate
calPickDate.ValueIsNull = True
btnCancel.SetFocus
DateSelected = False
Me.Show
Execute = DateSelected
End Function
Private Sub btnCancel_Click()
DateSelected = False
Me.Hide
End Sub
Private Sub calPickDate_Click()
DateSelected = True
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
DateSelected = False
Me.Hide
End If
End Sub
And the calling sub is as follows:
Private Sub GetDate(Target As MSForms.TextBox)
With frmDatePicker
.Caption = IIf(Target Is txtDstart, "Start date", "End date")
Set .frmParent = frmAnalysis
.xOffset = Target.Left
.yOffset = Target.Top
.InitialDate = Target.Value
If .Execute() Then Target.Value = Format(.calPickDate, "dd/mm/yyyy")
End With
End Sub
What I have tried so far:
Tested with a fresh userform in a blank workbook to make sure this behaviour is not because of some cruft or corruption in my project (it isn't)
Setting the
.Top
and.Left
properties in theUserForm_Initialise
andUserForm_Activate
events offrmDatePicker
- individually as well as in both (no difference)Preloading
frmDatePicker
before calling my.Execute
function and setting the positional properties as above (no effect)
I really don't want to fall back on "quickly showing then hiding the form" because... well, it's just a horrible solution!
Thanks for reading! Any ideas?