Список проверки данных игнорируется - PullRequest
0 голосов
/ 07 апреля 2020

У меня следующая ситуация: в одной ячейке у меня есть список проверки данных, который должен ограничивать выбор пользователем только элементов из этого списка. В той же ячейке, что и у меня, есть триггеры изменения в VBA, поэтому, когда значение ячейки изменяется, оно также записывает изменение в лист Changelog (оно использует отмену, чтобы получить предыдущее значение, и отмену снова, чтобы возвратить изменение в новое значение)

Проблема заключается в том, что в настоящее время список проверки данных полностью игнорируется, поэтому пользователи могут помещать все, что они хотят, в эту указанную c ячейку, даже если у меня установлен флажок «Показать ошибку» .

Есть ли способ обеспечить проверку списка, чтобы пользователи могли только выбирать элементы из списка и не вводить то, что они хотят? Или вызвать событие изменения ячейки после проверки?

Может быть, кто-то может прояснить порядок, в котором эти вещи происходят.

1 Ответ

0 голосов
/ 11 апреля 2020

Недавно я работал над 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 будет очищаться до тех пор, пока пользователь не выберет другую ячейку.

Важно, чтобы получить текущий CutCopyMode ДО того, как будет выполнен любой VBA-код, который что-то изменит, так как VBA автоматически изменится CutCopyMode из xlCut или xlCopy в 0, когда что-то меняется. Это начальное состояние требуется, чтобы избежать вставки раскрывающегося списка поверх другого.

Подпрограмма Worksheet_SelectionChange содержит код SKIPPED, который выполняет нечто подобное, если пользователь обращается к ячейке в одном из двух диапазонов. Он также содержит (превращенный в комментарий) код для выполнения дополнительных действий, когда пользователь выбирает ячейку. Этот код также может быть помещен в worksheet_Change

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...