我的工作表UserEntry
有两列,Block
和Address
。我想基于另一个具有相同列名的工作表Validation
来验证这两者。 Validation
表单上的数据如下:
Block | Address
---------------
001 | 101
001 | 101.3
001A | 35
020-1 | 203
020-1 | 203.5
020-1 | 204.1
...
大约有11000个不同的块,大约40000个块/地址对。
我的目标是,如果用户在Block
工作表的UserEntry
列中输入值,则Address
列中的下拉选项会更改为与Block
列对应1}}。
我尝试使用以下公式进行自定义验证:
=VLOOKUP(UserEntry!A2,Validation!A2:B40000)
但是评估错误。我在各种论坛中看到了一些涉及设置命名范围的解决方案,然后让VLOOKUP()搜索适当的命名范围,但似乎这在这里不起作用,因为我必须创建11000个命名范围。
如何让Address
的验证下拉列表包含与给定Block
值对应的所有值?
答案 0 :(得分:6)
你没有提到VBA,但这是一个使用它的解决方案。
创建块地址关系的主表。确保在Block
上排序。我用了Sheet1:
单元格E2
很重要。你实际上不必在那里放任何东西,但宏将使用它。单元格E3
仅用于显示,但您将使用公式(此处已注释掉,以便您可以看到它)。
创建命名范围。 Refers to:
中的公式就是您在上面的E3
中看到的公式,您可以在此处看到对单元格E2
的引用。方便的公式是
=OFFSET($A$1,MATCH($E$2,$A:$A,0)-1,1,COUNTIF($A:$A,$E$2),1)
设置一个新的工作表(Sheet2),其中将发生数据输入。为Address
列创建数据验证,如图所示。
打开VBA编辑器并将此代码粘贴到Sheet2
的模块中。如果您愿意,可以删除Debug
语句。再次注意E2
上对单元格Sheet1
的引用:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Debug.Print "fired on " & ActiveCell.Address
If Not Application.Intersect(Target, Range("B:B")) Is Nothing Then
Sheets("Sheet1").Range("E2").Value = ActiveCell.Offset(0, -1).Value
End If
End Sub
享受。您的数据验证现在对上下文敏感。例子:
答案 1 :(得分:4)
您可以使用动态命名范围。
假设:
Validation!A:B
UserEntry
上,要验证的Address
单元格是ented Block
创建命名范围以用作验证来源(我使用了名称ValList
):
=OFFSET(Validation!$B$1,MATCH(INDIRECT(ADDRESS(CELL("row"),CELL("col")-1)),Validation!$A:$A,0)-1,0,COUNTIF(Validation!$A:$A,INDIRECT(ADDRESS(CELL("row"),CELL("col")-1))),1)
将数据验证添加到所需的单元格:允许List
,来源=ValList
INDIRECT
,ADDRESS
和CELL
来引用相对于活动单元格输入 Block 的用户MATCH
和COUNTIF
获取验证列表中匹配的 Blocks 的位置和大小OFFSET
设置与输入块匹配的 addreesses 的返回范围