我有一个Excel片与柱d(第4列)是用于与2个选择每一行的下拉列表:
当我点击不,我有一个窗体弹出一个简单的“文本区”要求输入一个值和一个“提交按钮”来验证。
当“提交按钮”被点击时,我想从“文本区”,以实现进入细胞,以权值:(0,1)所抵消。
例如:D5: “否” - > “进入5在用户窗体” - > E5: “5”
这是我到目前为止的代码:
工作表:
Private Sub Worksheet_Change(ByVal Target As Range)
If ActiveCell.Column = 4 Then
If ActiveCell.Value = "no" Then
UserForm1.Show
End If
End If
End Sub
用户窗体:
Private Sub CommandButton1_Click()
ActiveCell.Offset(0, 1).Value = TextBox1.Value
UserForm1.Hide
End Sub
如果我把UserForm1.Hide的ActiveCell之前,我想要做什么,但用户窗体不会关闭。 如果我参加了ActiveCell用户窗体关闭,但我似乎无法一下子使双方的工作。
你改变细胞的Worksheet_Change处理程序 ,如果你没有一个形式阻止用户界面,这意味着,你会迅速吹向调用堆栈,并运行到一个“堆栈空间不足”的错误,也被称为。 .. 堆栈溢出 。
您需要防止您的Worksheet_Change
处理器从自称递归。
而这可以通过关闭来完成Application.EnableEvents
你做出改变之前,并切换回上算账:
Application.EnableEvents = False
ActiveCell.Offset(0, 1).Value = TextBox1.Value
Application.EnableEvents = True
现在,看到的问题是什么? 怎样的形式知道它正在从一个调用Worksheet_Change
处理程序等,它需要切换Application.EnableEvents
? 它不知道-而现在,它的假设它。
这是一个问题,只是因为形式正在运行的表演 。 翻转周围的事物,并留下愚蠢,因为它都不可能是这样的形式,使Worksheet_Change
处理器负责制作纸的改变和切换的Application.EnableEvents
状态:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 4 And Not IsError(Target.Value) Then
If Target.Value = "no" Then
With New UserForm1
.Show
If .Proceed Then
Application.EnableEvents = False
Target.Offset(0, 1).Value = .Contents
Application.EnableEvents = True
End If
End With
End If
End If
End Sub
几件事情:
- 触发事件的细胞是
Target
- 使用了ActiveCell
。 - 如果该单元格的值是
#N/A
或任何其它细胞误差值,您的代码鼓起。 使用IsError
以验证它是否是安全的第一比较单元的任何东西的价值。 - 窗体现在需要
Proceed
和Contents
属性,不能被允许自毁。 - 调用代码不关心任何文本框:它不知道如何
Contents
是越来越人口-这是形式的关注。
那么会是什么形式的代码隐藏样子呢?
Option Explicit
Private mProceed As Boolean
Private mContents As String
Public Property Get Proceed() As Boolean
Proceed = mProceed
End Property
Public Property Get Contents() As String
Contents = mContents
End Property
Private Sub TextBox1_Change()
mContents = TextBox1.value
End Sub
Private Sub CommandButton1_Click()
mProceed = True
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = VbQueryClose.vbFormControlMenu Then
Cancel = True
Me.Hide
End If
End Sub
现在所有的形式呢,是收集数据,并揭露它调用代码看:它不知道也不关心任何ActiveCell
或工作表-它收集数据,并公开它的调用代码看。 仅此而已,无所不及 。