我正在使用VBA构建Excel 2016用户窗体,需要收集从中打开窗体的单元格的行和列。我用Worksheet_BeforeDoubleClick
双击单元格打开窗体,然后用UserForm_Initialize()
初始化用户窗体。我想将双击事件的Target
传递给UserForm_Initialize()
,但不确定如何传递。 This forum thread解决了这个问题,但是提供的解决方案对我不起作用。
这是我的Worksheet_BeforeDoubleClick
:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Column = Target.Column
Row = Target.Row
'Find the last non-blank cell in column B(2)
lRow = Cells(Rows.Count, 2).End(xlDown).Row
'Find the last non-blank cell in row 2
lCol = Cells(2, Columns.Count).End(xlToRight).Column
If Not Intersect(Target, Range(Cells(3, 3), Cells(lRow, lCol))) Is Nothing Then
Cancel = True
EdgeEntryForm.Show
End If
End Sub
还有我的UserForm_Initialize()
:
Private Sub UserForm_Initialize()
Dim Column As Long, Row As Long 'I would like to fill these with the Target values
MsgBox ("Row is " & Row & " Column is " & Column)
'Description.Caption = "Fill out this form to define a network edge from " & Cells(2, Row).Value & " to " & Cells(Column, 2).Value
End Sub
答案 0 :(得分:3)
如我的评论所建议,一种方法是仅使用ActiveCell
并将其分配给变量。
或者,如果您确实希望将其作为变量传递,则可以通过一个全局变量临时保存该信息来进行一些变通:
在您的工作表代码中:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'.....
With UserForm1
Set .rngTarget = Target
.Show
End With
'.....
End Sub
在您的用户表单中:
Public rngTarget As Range
Private Sub UserForm_Activate()
'....
If Not rngTarget Is Nothing Then
MsgBox ("Row is " & rngTarget.Row & " Column is " & rngTarget.Column)
Else
MsgBox "something went wrong with assigning rngTarget variable"
End If
'....
End Sub
编辑:我起初试图提出类似于@MathieuGuindon的answer的内容,但是由于我对初始化和激活之间的区别的了解有限,所以失败了。(感谢Mathieu)。 / p>
我已经更新了答案,以便在用户窗体级别使用全局变量,而不是使用模块中的全局变量。
答案 1 :(得分:2)
该表单以模态显示,因此ActiveCell
不会对您造成任何影响,应该可以安全地用于表单的代码隐藏中。
问题在于,您现在已经将表单绑定到ActiveSheet
/ ActiveCell
,并且现在为了测试任何内容,您需要Select
或{{1} }一个单元格。
如果表单代码仅需要知道单元格的Activate
,则不应为其提供Address
(给它一个Range
,它可以访问任何一个单元格中的任何单元格Range
实例中任何工作簿中的工作表)-这是知识最少的原则。但这显然是示例代码,所以让我们来看一个Application
:
Range
现在您的表单代码可以使用Option Explicit
Private internalWorkingCell As Range
Public Property Get WorkingCell() As Range
Set WorkingCell = internalWorkingCell
End Property
Public Property Set WorkingCell(ByVal value As Range)
Set internalWorkingCell = value
End Property
或WorkingCell
来完成它的工作,并且不需要全局变量;
internalWorkingCell
With New UserForm1 ' Initialize handler runs here
Set .WorkingCell = Target
.Show ' Activate handler runs here
End With
属于形式-它与全球范围无关。
请谨慎对待WorkingCell
形式的处理程序-特别是在使用默认实例时(特别是当您不Initialize
使用它时) ):您无法控制该处理程序何时运行,VBA运行时可以控制; New
将在表单实例第一次被引用(在您的情况下,紧接UserForm_Initialize
调用之前)运行,然后再运行一次,除非实例被销毁(单击红色的X按钮可以做到这一点。
.Show
处理程序中的MsgBox
调用将在显示表单之前 运行;您可能想要在导致问题之前将代码移至Initialize
处理程序。