我有一个Excel表,其中D列(第4列)是有两个选项的每一行的下拉列表:
当我单击“否”时,会弹出一个Userform,其中一个简单的“文本区域”要求输入一个值,还有一个"Submit“按钮进行验证。
当单击"Submit按钮“时,我希望将"text zone”的值实现到右边的单元格中:偏移量(0,1)。
示例: D5:"No“->在用户表单”-> E5:“5中输入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 SubUserForm:
Private Sub CommandButton1_Click()
ActiveCell.Offset(0, 1).Value = TextBox1.Value
UserForm1.Hide
End Sub如果我把UserForm1.Hide放在ActiveCell前面,它会做我想做的事情,但是UserForm不会关闭。如果我拿出ActiveCell,UserForm就会关闭,但我似乎不能让两者同时工作。
发布于 2018-06-18 15:39:13
您正在更改Worksheet_Change处理程序中的单元格,这意味着如果您没有一个窗体来阻止UI,那么您将很快吹掉调用堆栈,并运行到一个“堆栈外空间”错误,也称为.堆栈溢出。
您需要防止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或工作表--它收集数据,并将其公开以供调用代码查看。没有更多,没有更少。
https://stackoverflow.com/questions/50912331
复制相似问题