一个类似的问题已被问过多次,但我有一个略有不同的问题。我使用了一些来自超级用户的代码,这些代码限制了用户将值粘贴到数据验证范围中的作用:
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
这很好并且可以工作,但是我想知道是否可以再进一步。用户可能希望粘贴到这些字段中的原因是因为他们正在将数据从一个电子表格移动到另一个电子表格。我在那里进行验证以确保拼写正确(对于其他用途很重要)。根据上面的代码,如果值匹配数据验证列表中的内容,则用户是否可以将某些内容粘贴到数据验证字段中并且不拒绝它?似乎雄心勃勃,不确定是否可行。
编辑:列表存储在另一个标签中,而不是硬编码到数据验证菜单中
答案 0 :(得分:2)
如果Validation
不是Nothing
,并且类型是xlValidateList
(基础值3
),则可以使用Validation.Formula1
来获取“列表”。
那是容易的部分。
如果Formula1
并非以=
开头,则您正在查看的是用逗号分隔的简单值列表。
此函数将为您提供一维数组,其中包含指定的target
的所有有效值,而与数据验证列表的定义方式无关:
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
剩下要做的就是确定您粘贴的值是否在该数组中。