【问题标题】:Data validation list is being ignored数据验证列表被忽略
【发布时间】:2020-04-11 06:25:26
【问题描述】:

我有以下情况:在一个单元格上,我有一个数据 - 验证 - 列表,它应该限制用户只从该列表中选择项目。 在同一个单元格上,我在 VBA 中使用了更改触发器,因此当单元格值发生更改时,它还会将更改记录到更改日志表中(它使用撤消来获取以前的值,然后再次撤消以重做对新值的更改)

问题是,现在,数据 - 验证 - 列表被完全忽略,因此用户可以在该特定单元格中放置他们想要的任何内容,即使我已选中“显示错误”。

有没有办法强制执行列表验证,所以用户只能从列表中选择项目而不能输入他们想要的任何内容?还是验证后触发on cell change事件?

也许有人可以澄清这些事情发生的顺序。

【问题讨论】:

  • 暂时禁用VBA能正常工作吗?
  • (我假设您已经考虑到Application.Undo更改单元格值导致的潜在堆栈溢出,它调用Worksheet_Change事件,再次触发Application.Undo命令,等等?)
  • 帮我们帮你; 发布您当前的代码
  • 您好,我想分享更多细节:初始单元格的列表源是一个包含几个空单元格的命名范围。我为具有完全相同属性的单元格测试了相同的场景,除了列表是固定地址(“A2:A30”),并且验证按预期工作。命名范围末尾的空行是否会禁用验证?我也试图将“qwe”放在单元格中,我希望“”被接受,而不是“qwe”。
  • @DumitruDaniel 首先,您可以随时edit 您的帖子,而不是使用过多的 cmets。第二 - 你不能。虽然您可以Exit Sub 取消Worksheet_Change 事件,但它无法判断单元格验证是否失败。您必须删除“显示错误”,并使用Target.Validation.Value 来运行您自己的验证检查。或者,将旧值的副本存储在其他地方(“非常隐藏”的工作表?),并使用它们而不是使用 Application.Undo 来获取以前的值

标签: excel vba list validation


【解决方案1】:

我最近研究 range.Validation.type=xlValidateList 并希望防止粘贴和剪切并禁止在包含下拉列表的单元格中输入错误的字符(并且可以输入与列表中的条目匹配的字符并显示那个条目)。

在处理最后一件不好的事情时(剪切下拉菜单并将其粘贴到另一个已经包含下拉菜单的单元格中),我发现了一种禁止粘贴和剪切数据验证列表的简单方法,该方法确实允许根据内容进行进一步处理已输入,

以下代码必须在工作表模块上。 它可以防止用户破坏单元格上的数据验证,因此使用 Application.Undo 恢复到不再需要粘贴或剪切之前的状态。

我不知道这是否有区别,但我保护了工作表并解锁了用户可能更改的单元格。

Private Function HasValidation(ByVal rng As Range) As Boolean
' See:       https://superuser.com/questions/870926/restrict-paste-into-dropdown-cells-in-excel
' Returns True if every cell in Range r uses Data Validation
    On Error Resume Next
    Dim rngType: rngType = rng.Validation.Type
    HasValidation = (Err.number = 0)
End Function

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' Switch DragAndDrop on/off on a range containing DataValidation
    Dim modeCutCopy: modeCutCopy = Application.CutCopyMode
    Dim usesValidation: usesValidation = HasValidation(Target)
    If ((usesValidation = True) And (modeCutCopy <> 0)) Then Application.CutCopyMode = False     ' MUST reset to avoid copying / cutting xlValidateList into another xlValidateList
    ' Turn DragAnddDrop on/off depending on if a cell uses Validation or not
    If (usesValidation = Application.CellDragAndDrop) Then Application.CellDragAndDrop = (Not usesValidation)

GoTo SKIP
    ' Don't allow DragAndDrop if Target intersects with specified ranges
    Dim myRange As Range
    Set myRange = Worksheets("Evenementen").Range("Oordeel", "Waardering")
    Dim rngIntersect As Range
    Set rngIntersect = Application.Intersect(Target, myRange)
    Application.CellDragAndDrop = (rngIntersect Is Nothing)
''    CheckInputValidationList(Target)          ' Sophisticated testing and actions depending on the selection made
''    CheckInputValidationList(Target, myRange) ' Sophisticated testing and actions depending on the selection made for specific ranges

SKIP:

Debug.Print "SelectionChange  " & Target.Address & "    usesValidation=" & usesValidation & "   cellDragAndDrop=" & Application.CellDragAndDrop
End Sub

在这种情况下,有两个包含(不同)数据验证列表的命名范围。 只要用户点击一个单元格,就会检查该单元格是否使用数据验证。 如果是这样,剪切和粘贴将被关闭,并且 CutCopyMode 将被清除,直到用户选择另一个单元格。

重要的是在执行任何更改某些内容的 VBA 代码之前检索当前的 CutCopyMode,因为当某些内容发生更改时,VBA 会自动将 CutCopyMode 从 xlCut 或 xlCopy 更改为 0。 需要该初始状态以避免将下拉列表粘贴到另一个上。

Worksheet_SelectionChange 子例程包含 SKIPPED 代码,如果用户访问两个范围之一中的单元格,该代码会执行类似的操作。 它还包含(变成注释)代码以在用户选择单元格时执行其他操作。该代码也可能放在 worksheet_Change 中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多