Home » excel » excel – Pasting in Data Validation IF the value exists inside the data validation list

excel – Pasting in Data Validation IF the value exists inside the data validation list

Posted by: admin May 14, 2020 Leave a comment

Questions:

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

How to&Answers:

If the Validation isn’t Nothing and its type is xlValidateList (underlying value 3), then you can use Validation.Formula1 to get the “list”.

That’s the easy part.

If 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.