数据validation和工作表更改事件

我使用VBAmacros查询数据库并使用工作簿激活事件打开工作簿时生成可用项目的列表。 我将项目编号和项目名称合并为两个单独的数据validation列表,并应用于两个单元格。 工作表更改事件testing这些单元格中的更改,将其数据validation列表拆分为数组,并从另一个数组中select相应的项目信息。 例如,如果我select项目编号,则工作表变更事件将在项目编号数组中find项目编号的位置,然后根据位置从名称数组中select项目名称。

无论何时从下拉列表中select一个值,这都可以很好地工作,但是当列表中的值被input时,我会遇到问题。 例如,如果我input一个空白单元格,我可能会得到数据validation错误,或者当我使用匹配在数组中findinput的值时,可能会出现types不匹配。 我有一个error handling程序来处理types不匹配,但我想每次都触发数据validation错误。 另一个问题是事件有时会被禁用。 这是更严重的,因为用户将无法将其重新打开。

最重要的是,我无法弄清楚这是怎么发生的。 我不能复制如何使用中断来禁用事件,因为复制导致事件被禁用的步骤只能导致我的error handling程序。 但是,如果不应用中断,则error handling程序有时将无法触发,并且事件将被禁用。 由于我正在parsing数组之前禁用事件,我认为工作表更改失败在Loc=Application.Match(Target.Text, NumArr, 0) - 1行,但我不明白为什么没有错误会被触发。 至less,我应该得到一个错误号和描述的消息,事件应该重新启用。

任何人都可以build议工作表变更和数据validation之间的交互? 这里的电话订单是什么? 还有其他build议吗? 任何我失踪?

ETA:我已经谷歌search了,但我还没有find任何帮助。 所出现的一切都是关于如何将数据validation工作变成工作表变更,与交互或呼叫顺序无关。

ETA#2:在下面的答案(谢谢加里的学生)尝试实验后,这有点奇怪。 如果我select“重试”并select旧的,默认值,我得到旧值三次。 如果我点击删除,我会在消息框中获得一个空格,但只有一个消息框。 然后单元格留空。 我可以通过点击“重试”并接受空间将DV放入循环。 DV错误将会出现,直到我点击取消。 然后,我会得到一系列空的文本消息框,每次我重试空单元格。 如果我从列出的值开始,用退格清除单元格,单击“重试”,然后尝试select另一个值,工作表更改事件在相交3次时失败。 我想下面的答案可以更清楚地说明正在发生的事情,但是它也提出了更多的问题。

这里是我有的代码:

 Private Sub Worksheet_Change(ByVal Target As Range) Dim NumArr() As String Dim ProjArr() As String Dim Loc As Integer On Error GoTo ErrHandler: If Target.Address = "$E$4" Then 'Disable events to prevent worksheet change trigger on cell upates Application.EnableEvents = False 'Parse validation lists to arrays NumArr = Split(Target.Validation.Formula1, ",") ProjArr = Split(Target.Offset(1, 0).Validation.Formula1, ",") 'Change error handler On Error GoTo SpaceHandler: 'Determine project number location in array Loc = Application.Match(Target.Text, NumArr, 0) - 1 'Change error handler On Error GoTo ErrHandler: 'Change cell value to corresponding project name based on array location Target.Offset(1, 0) = ProjArr(Loc) 'Unlock cells to prepare for editing, reset any previously imported codes Range("C8:G32").Locked = False 'Run revenue code import RevenueCodeCollector.ImportRevenueCodes 'Re-enable events Application.EnableEvents = True End If If Target.Address = "$E$5" Then Application.EnableEvents = False NumArr = Split(Target.Validation.Formula1, ",") ProjArr = Split(Target.Offset(-1, 0).Validation.Formula1, ",") Loc = Application.Match(Target.Text, NumArr, 0) - 1 Target.Offset(-1, 0) = ProjArr(Loc) Range("C8:G32").Locked = False RevenueCodeCollector.ImportRevenueCodes Application.EnableEvents = True End If Exit Sub ErrHandler: MsgBox Err.Number & " " & Err.Description Application.EnableEvents = True Exit Sub SpaceHandler: MsgBox "Pick a project from the dropdown.", vbOKOnly, "Error" Application.EnableEvents = True End Sub 

你有一个非常开放的问题………..没有时间做一个完整的白皮书,这里是一个简单的实验。 我使用事件代码:

 Private Sub Worksheet_Change(ByVal Target As Range) Dim A1 As Range, rINT As Range Set A1 = Range("A1") Set rINT = Intersect(A1, Target) If rINT Is Nothing Then Exit Sub MsgBox A1.Value End Sub 

A1中 ,我设置DV如下:

在这里输入图像说明

如果我使用下拉列表,我得到input的值,我也得到MsgBox 。 但是,如果我点击单元格并input一些垃圾,会发生什么情况是:

  1. 发生DV警报,然后触摸取消button
  2. 我得到2 MsgBox发生,每个与原始内容,而不是企图垃圾!

我完全不知道为什么这个事件会提出,因为这个单元格实际上并没有改变,更不用说为什么这个事件会重复两次了 ! 就好像事件发生在垃圾邮件上,但是DV警报优先,DV反向录入,另一个事件发生,最后两个事件都被处理。

希望有一个比我聪明的人会唱歌。

通过参考查询,pipe理DV和更改事件的解决方法。

 Public strRange As String Public bCheck As Boolean Private Sub Worksheet_Change(ByVal Target As Range) If bCheck Then Exit Sub MsgBox "Correct Entry!" strRange = Target.Address bCheck = True End Sub Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address <> strRange Then bCheck = False End Sub 

http://forum.chandoo.org/threads/multiple-worksheet-change-event-with-data-validation.32750