A similar question has been asked multiple times, but I have a slightly different ask. I have used some code from superuser that restricts users from pasting values into data validation ranges:
Private Sub Worksheet_Change(ByVal Target As Range) 'Does the validation range still have validation? If HasValidation(Range("DataValidationRange")) Then Exit Sub Else Application.Undo MsgBox "Error: You cannot paste data into these cells." & _ "Please use the drop-down to enter data instead.", vbCritical End If End Sub Private Function HasValidation(r) As Boolean 'Returns True if every cell in Range r uses Data Validation On Error Resume Next x = r.Validation.Type If Err.Number = 0 Then HasValidation = True Else HasValidation = False End Function
This is great and it works, but I am wondering if it can be taken one step further. The reason users may want to paste into these fields is because they are moving data from one spreadsheet to the other. I have the validation there to ensure the spelling is correct (important for other uses). Is it possible for a user to paste something into the data validation field and it doesn’t deny it, based on the code above, IF the value matches something inside the data validation list? Seems ambitious, not sure if it is possible.
Edit: The list is stored in another tab, not hardcoded into the data validation menu
Nothing and its type is
xlValidateList (underlying value
3), then you can use
Validation.Formula1 to get the “list”.
That’s the easy part.
Formula1 doesn’t start with an
= sign, you’re looking at a plain comma-separated list of values.
This function gets you a 1-dimensional array with all the valid values of the specified
target, regardless of how the data validation list is defined:
Public Function GetValidationValues(ByVal target As Range) As Variant Dim dataValidation As Validation Set dataValidation = target.Validation If dataValidation Is Nothing Then Exit Function If dataValidation.Type <> xlValidateList Then Exit Function Dim values As Variant If Left$(dataValidation.Formula1, 1) <> "=" Then 'plain comma-separated list of values values = Split(dataValidation.Formula1, ",") Else 'validation list is a range address, or a named range Dim rngValues As Range Set rngValues = Application.Evaluate(dataValidation.Formula1) If rngValues.Columns.Count > 1 Then values = Application.Transpose(Application.Transpose(rngValues)) Else values = Application.Transpose(rngValues) End If End If GetValidationValues = values End Function
All that’s left to do is to determine whether your pasted value is in that array.