使用变量时,通过excel中的VBA设置验证失败

时间:2010-07-21 13:02:14

标签: excel vba excel-vba

我正在尝试使用VBA为一系列单元格设置数据验证。我用这段代码得到了运行时错误1004(非常有用)“应用程序定义或对象定义错误”。

 With rngRangeToCheck.Cells(lrownum, 1).Validation
    .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
        xlBetween, Formula1:=choice
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
End With

在Formula1中,choice是一个传递给函数的变量,类似于代码所在的工作簿中的“= SomeNamedRange”。

错误发生在代码的.Add部分。

如果我将Formula1硬编码为Formula1:="=SomeNamedRange"它的工作没有问题。我真的不会硬编码它,因为我这样做有很多可能的'选择'值,那就是我认为只是不太干净的代码。

我几天来一直在烧谷歌和大约3本不同的书,试图解决这个问题。

有什么建议吗?感谢您帮助新手。

6 个答案:

答案 0 :(得分:5)

这也许应该是一个评论,特别是因为这篇文章太老了......我遇到了同样的问题,它会在某些时候工作而不是其他工作。使用动态命名的范围。我找到的解决方案是暂时解锁工作表。

Private Sub FixDropdownLists()

Sheet1.Unprotect Password:="afei31afa"
Dim cellv As Range

For Each cellv In Sheet1.Range("B18:E18,B32:E32")
    With cellv.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=Office_Locations"
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = "Invalid Input"
        .InputMessage = ""
        .ErrorMessage = "Select the location only from the dropdown list."
        .ShowInput = False
        .ShowError = True
    End With
Next cellv
Sheet1.Protect Password:="afei31afa"
End Sub

答案 1 :(得分:3)

您确定choice变量的值是您认为的吗?也许你应该在.Add行之前设置一个断点,看看你传入了什么。我在Excel 2003和2007中测试了代码,它没有任何问题。只有当我给出Formula1和无效范围参考时,我才会得到错误1004。

你可以尝试运行这是一个新的未触动的工作簿,看看它是否适合你(确实对我有用):

Sub Test()

    'Setup '
    ActiveSheet.Range("B1:B2").Name = "SomeNamedRange"
    ActiveSheet.Range("B1").Value = "Apples"
    ActiveSheet.Range("B2").Value = "Oranges"

    Dim lrownum As Long
    lrownum = 1

    Dim choice
    choice = "=SomeNamedRange"

    Dim rngRangeToCheck As Excel.Range
    Set rngRangeToCheck = ActiveSheet.Range("A1:A10")

    With rngRangeToCheck.Cells(lrownum, 1).Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=choice
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
    End With

End Sub

(这实际上应该是一个评论,而不是一个答案,但我需要发布代码,这样就更容易。如果我拿出一个,我会编辑这个作为我的答案。)

答案 2 :(得分:2)

问题几乎可以肯定是由于命名范围的上下文与Excel中的当前上下文不同。

当调用Validation.Add时,Excel会在应用程序的当前上下文中评估公式(返回Range对象),而不是工作簿或工作表。因此,如果命名范围是基于表单的,并且该表单当前不活动,则它不会起作用。如果命名范围存在于一个工作簿中,但是另一个工作簿处于活动状态,那么它将无法工作。这就是选择随机单元格的解决方法解决问题的原因,以及执行.Select后跟Selection.Validation的解决方案。

答案 3 :(得分:1)

这是一篇相当古老的帖子,但是对于任何到达这里我遇到同样问题的人来说,问题是如何解决的:

我刚刚更换了

With Range(Cell1,Cell2).Validation

部分

Range(Cell1,Cell2).Select
With Selection.Validation

和tadaaa!它有效:)

答案 4 :(得分:0)

确保您没有进入Validation.Add行/列中的公式。例如" = R2C2:R3C3"一旦我改为" B2:C3"有效。此范围内的单元格中必须包含值,否则会出现应用程序错误。

答案 5 :(得分:0)

我已经使用INDIRECT函数引用了命名位置,并且一切运行正常。但是,用户报告了一些定期的,看似随机的错误,从日志文件中我看到此Validation.add引起了问题。 事实是,Excel工具在后台运行,而用户操作的其他Excel文件在执行此操作时可能会成为焦点。

未测试以下代码。希望对您有所帮助。

.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= xlBetween, Formula1:="=INDIRECT(""[" & ThisWorkbook.Name & "]" & sht_sfDocumentation.Name & "!" & gstrRANGE_NamedTableRange & """)"