【问题标题】:Use of INDIRECT in data validation在数据验证中使用 INDIRECT
【发布时间】:2026-02-04 21:55:01
【问题描述】:

我想在 VBA 的数据验证中应用 Excel 的 INDIRECT 函数。

我正在使用 VBA 填充数据验证条件,并使用 INDIRECT 通过 HLOOKUP 从另一个命名范围中找到适当的工作簿命名范围。

我认为我的问题在于 VBA 代码的语法。我无法弄清楚双引号的正确位置。这将返回错误 400 通知。

我有以下内容(为清楚起见,省略了功能代码部分)。 HLOOKUP 引用的列 F 包含一个用户可选择的值,而 DepartmentRef 是一个命名范围:

Sub AddNewRoom()
Dim targetRow As Integer
targetRow = Range("EndRoomData").Row
With Worksheets("RoomData")
    With .Range("G" & targetRow).Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
            xlBetween, Formula1:="=indirect(hlookup(F" & targetRow & ",DepartmentRef,2,false))"
    End With
End With
End Sub

当我更改验证公式以删除代码变量时,代码正常运行:

With .Range("G" & targetRow).Validation
    .Delete
    .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
        xlBetween, Formula1:="=indirect(hlookup(F7,DepartmentRef,2,false))"
End With

【问题讨论】:

  • 我刚刚尝试过Worksheets("Sheet5").Range("k2").Validation.Add _ Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _ xlBetween, Formula1:="=indirect(vlookup(1,test!A:B,2,0))",效果很好。你能提供更多的见解吗?如果您在验证设置之前放置一个断点,是否填充了targetRow?另外,我不明白您如何从中获取列表?是否最好设置此值,然后可以使用或添加静态公式?
  • 另外,生成的公式是否有返回值,所以如果推导的范围错误地说“Q1000000”,这会导致公式产生错误吗?
  • 如果公式返回错误会出现问题,但我认为这不应该取决于Fn 的构造方式。您的语法似乎正确。此外,您将无法处理 > 32767 的行,因为这是 Integer 数据类型的限制。创建公式时TargetRow的内容是什么?
  • @Nathan_Sav:是的,'targetRow' 在运行时填充,它在代码的许多其他部分中使用没有问题。问题似乎出在数据验证设置中,好像正在创建无效引用。代码中止并出现错误框,仅显示消息“400”;没有通常预期的结束/调试选项。目标单元格中​​未出现数据验证设置。
  • @RonRosenfeld:'targetRow' 从第 6 行开始,不太可能超出第 1000 行,因此整数限制在实践中不太可能成为问题,当然在测试中也不会出现问题,但我注意到潜在的限制。在我的测试中,到目前为止它被限制为

标签: excel vba validation syntax


【解决方案1】:

不要使用直接的“名称”单元格引用,而是尝试:

Formula1:="=INDIRECT(HLOOKUP(" & Worksheets("RoomData").Cells(targetRow, 6).Address(False, False) & ",DepartmentRef,2,FALSE))"

【讨论】:

  • 谢谢,我明白为什么这可能会更好,但它仍然给我同样的错误。
  • 我有同样的错误,但上面的解决方案没有了。您是否使用美国语言版本?并使用 , 作为公式分隔符或 ; ?
  • Windows 系统语言为英语(澳大利亚);选定的 Excel 校对语言为英语(澳大利亚)和英语(美国)。我假设您的意思是公式中的参数之间的分隔符等:我使用','。
【解决方案2】:

验证公式的结果必须在代码运行时返回结果。如果 HLOOKUP 引用的单元格为空,则 Excel 会看到源错误并且代码终止。如果在手动输入引用时发生此错误,Excel 允许您继续,但您不能(据我所知)在 VBA 中执行此操作。要解决此问题,请在输入验证详细信息之前在引用的单元格中输入一个(合法的)值,然后删除该引用值。例如:

With Worksheets("RoomData")    
    .Range("F" & targetRow).Value = ThisWorkbook.Names("DepartmentName").RefersToRange(1, 1)
    strFormula = "=INDIRECT(HLOOKUP(" &    
        Worksheets("RoomData").Cells(targetRow,6).Address(True, True) & ",DepartmentRef,2,FALSE))"
    With .Range("G" & targetRow).Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=strFormula
    End With
    .Range("F" & targetRow).ClearContents
End With

【讨论】: