如何实现动态数据验证,例如作为 Excel VBA 函数?
Posted
技术标签:
【中文标题】如何实现动态数据验证,例如作为 Excel VBA 函数?【英文标题】:How do implement dynamic data validation e.g. as Excel VBA-function? 【发布时间】:2019-04-01 17:05:36 【问题描述】:Excel 中的数据验证是在 Excel 中验证用户输入的有用方法。标准方法是 (1) 在某处(例如在辅助表上)定义一个包含可能输入值的列表,然后 (2) 然后在 Source
字段中选择该范围。或者,也可以直接在该字段中输入不同的选项,例如:
我的问题:我们如何使数据验证列表动态化?
到目前为止,我尝试的是在数据验证对话框的 Source
字段中输入一个返回字符串列表的(可能是用户定义的 VBA)公式,例如
=INDEX("New","Mint","Very Good","Good","Acceptable","Poor",1,RANDBETWEEN(1,6))
但是,这种方法不起作用,因为它会导致错误消息
您不得使用引用运算符(例如联合、交集、 和范围)或数据验证条件的数组常量。
我错过了什么?您建议使用哪种(可能更优雅)使数据验证动态的Source
方式?
编辑:我的具体问题:
在所有(除了第一个)选项卡表上,我有一个名为 myTest
的单元格,允许值列表用于第一个选项卡上的单元格,我希望能够从由所有可能值组成的列表中myTest
.
参考资料:
Debra Dalgleish:“创建从属下拉列表”contextures.com Dynamic Data Validation in Excel (Non-VBA!)【问题讨论】:
我用一堆隐藏的列做过一次。隐藏列的公式根据该行中的某些条目给出不同的值。然后这些值可用于同一行中其他单元格中的数据验证。 当您说“使其动态化”时,您是说源将更改完整位置,还是您希望动态找到源工作表的最后一行并将数据包含在其中?本质上,您提供有关一般概念的信息,而没有为您的特定情况下需要什么和需要什么提供任何基础,这将导致一个固执己见或开放式的讨论,而不是一个可回答的问题,这个论坛需要。 @Cyril 的评论很中肯:您到底是想要做什么,还是只是在探索?如果您使用 VBA 函数作为验证列表的源,它必须在工作表上返回一个范围,并且该范围必须是连续的。 @horst:您的方法不适用于我的情况,因为允许值范围的长度可能会有所不同。 我相信您可以粘贴到 DV 对话框中的逗号分隔列表的长度是有限制的 - 超过这个长度,您需要将其指向一个范围。 【参考方案1】:您可以在第一张工作表的代码模块中使用类似的内容:
Private Sub Worksheet_Activate()
Const LIST_COL As Long = 26
Dim sht As Worksheet, i As Long
i = 1
Me.Columns(LIST_COL).ClearContents '<< clear current list
For Each sht In ThisWorkbook.Worksheets '<< collect all the values
If sht.Name <> Me.Name Then
Me.Cells(i, LIST_COL).Value = sht.Range("myTest").Value
i = i + 1
End If
Next sht
End Sub
它会将其他工作表中的值收集到您可以参考的验证列表范围内。
注意:如果其他工作表的值是通过代码或公式更新的(即,不需要您转到每个工作表来更改值),那么您需要做更多的工作。
编辑 - 这更复杂,但工作更可靠,因为只要您点击验证下拉菜单,它就会运行
1. 将其放入常规模块中(根据需要进行编辑):
'A function to return a range containing the
' various values which need to appear in the validation list
Public Function ListCompile() As Range
Const LIST_COL As Long = 26 '<< create the list in Col Z
Dim sht As Worksheet, i As Long
i = 1
Sheet1.Columns(LIST_COL).ClearContents
For Each sht In ThisWorkbook.Worksheets
If sht.Name <> Sheet1.Name Then
Sheet1.Cells(i, LIST_COL).Value = sht.Range("myTest").Value
i = i + 1
End If
Next sht
'return the list we just created
Set ListCompile = Sheet1.Cells(1, LIST_COL).Resize(i, 1)
End Function
注意:我使用的是 Sheet1 的代号(可能与选项卡名称不同)。您可以在 VB 编辑器 Project Explorer 中看到代码名称。
2.定义一个命名范围“tester”,其中“RefersTo”等于ListCompile()
3. 最后将你的数据验证列表范围设置为:=tester
【讨论】:
所有工作表上的myTest
的值实际上可以更改,因此每次用户单击下拉菜单时更新允许值列表确实是有意义的。【参考方案2】:
假设:
您的列表在 A 列中 没有标题您可以使用此公式作为来源,使用动态列表进行数据验证:
=OFFSET(A1,0,0,COUNTA(A:A),1)
编辑: 下面是在数据验证中使用上述公式应用于单元格 B1 的示例图像:
如果您能以某种方式将您的值合并到一个列中,这是一种可能。
【讨论】:
你的代码到底是做什么的?我相信我们可能误解了彼此 - 我正在寻找某种技巧,它可以在大约 5 到 20 个不同的选项卡(每个都有这个myTest
)上累积所有名为 myTest
的单元格的值。以上是关于如何实现动态数据验证,例如作为 Excel VBA 函数?的主要内容,如果未能解决你的问题,请参考以下文章