我有一个Excel 2007 VBA项目,它有几个用户表单,其中一个是包含Calendar Control12.0对象的日期选择器。每当用户单击其他窗体上的两个textbox控件之一时,日期选择器就会被激活。我希望控制日期选择器的启动位置,以便当显示时,它将与单击的文本框控件保持一致。
为此,日期选择器用户表单(frmDatePicker)公开了三个公共vars:xOffset、yOffset和frmParent。意图是,在显示frmDatePicker之前,它的.Top和.Left属性将通过引用这三个vars来设置,它们本身是由调用子初始化的。(userform的.StartUpPosition属性也设置为零(即(“手册”)允许以这种方式控制其初始位置。
这工作得很完美..。除了第一次显示日期选择器外。第一次调用.Show方法时,frmDatePicker与单击的textbox不对齐。从第二次开始,这个问题就消失了。
frmDatePicker的代码如下:
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呼叫分机如下:
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到目前为止,我已经尝试过:
.Top和UserForm_Activate事件中设置frmDatePicker和UserForm_Activate属性--单独设置和设置这两个属性(没有区别)frmDatePicker函数和设置上述位置属性之前预先加载.Execute (无效果)我真的不想回到“快速展示然后隐藏表格”上,因为.这只是个可怕的解决方案!
感谢您的阅读!有什么想法吗?
发布于 2014-02-21 16:25:09
奇怪,正如您所说的,第一次设置.Left/Top似乎是重置/被忽略的:

不知道为什么。作为一个解决办法,这似乎是可行的:
If Not frmParent Is Nothing Then
Me.StartUpPosition = 0
Me.Move frmParent.Left + xOffset, frmParent.Top + yOffset
End If发布于 2014-02-21 17:16:00
我发布这个答案只是为了完整,以提供更多关于在这个实例中实际发生的事情的信息。亚历克斯·K的治疗更好。
我做了一些更多的测试,发现这只是对.Left或.Top的第一次写入,被重置/忽略。
在我上面的例子中,事实证明.Left被重置/忽略了,但是写入.Top的值实际上是“粘住”的。在我的项目中,从默认的中心位置所需的垂直位移非常小,所以我没有发现这个。
我的解决方案是将第一个属性设置两次,即
If Not frmParent Is Nothing Then
Me.StartUpPosition = 0
Me.Left = frmParent.Left + xOffset
Me.Left = frmParent.Left + xOffset
Me.Top = frmParent.Top + yOffset
End If不管第一个是.Left还是.Top,而且假设第一行可以设置一个虚拟值,因为它无论如何都会被忽略。只要您第二次设置它,userform就会在期望的位置第一次显示出来。
https://stackoverflow.com/questions/21938455
复制相似问题