【问题标题】:VBA Validation Throws 1004 Application -Defined ErrorVBA 验证引发 1004 应用程序定义的错误
【发布时间】:2013-03-11 15:44:30
【问题描述】:

您好,我有以下代码触发了数千个单元格。它为每个单元格添加一个验证列表(列表值在名称范围中定义 - 名称范围在单独的选项卡中)。

Sub CreateList(cell As Variant, rng As String)
     If rng <> Empty Then
          With cell.Validation
             .Delete
             .Add Type:=xlValidateList, Formula1:="=" & rng
             .ShowError = False
          End With
       End If
    End Sub

我从另一个循环遍历单元格的函数调用子例程。注意totalCols & totalRows 是在别处设置的,但是是数据范围的界限:

    For i = 2 To totalRows
       For J = 1 To totalCols
          CreateList(Worksheets("Data").cells(i, j), GetRange(Worksheets("Data").cells(1, J).Value)
       Next
    Next

GetRange() 采用标题值(存储在“数据”表的第 1 行)并返回范围名称(存储在同一工作簿的单独工作表中):

Function GetRange(cell As Variant) As String    
       If cell.Value = "Column One Name" Then
          GetRange = "RangeOne"
       ElseIf cell.Value = "Column Two Name" Then
          GetRange = "RangeTwo"
       Else
          GetRange = ""
       End If
End Sub

当我运行代码时,它有时会失败,并出现应用程序定义的错误 1004。这里的特殊之处在于不同数据集的不同点。数据集越大,它格式化的列就越少。对于小型数据集(即 1/2 行),它可以工作 - 因为它循环遍历所有范围并相应地添加列表。

更多信息:数据表未锁定。调试时,rng 的值正确。这在调试模式下执行“添加监视”并检查范围的范围值属性时得到确认。命名范围在工作簿范围内,但包含在单独的工作表中。

第一次运行相同的数据集时,它总是停在同一个地方。它有时会在列的一半处填充具有正确范围值的单元格,然后停止并出现错误 1004。

在第一次失败后立即运行第二次时 - 它有时会在第一个需要验证的单元格处停止并显示 1004 错误。发生这种情况时,它会在第一个需要为任何数据集添加验证的单元格中停止。就好像它在这一点上打破了工作表。

【问题讨论】:

  • 错误出现在哪一行?
  • 验证失败。添加行
  • 你可以给createlist添加一个计数器,看看它成功应用了多少个单元格DV?并在您的几个数据集上进行测试。
  • 运行 1:失败 - 计数器 = 65514;运行 2:通过 - 计数器 = 70553;运行 3:失败 - 计数器 = 65514;所有都针对不同的数据集运行
  • 它只是在 counter = 81343 的单独数据集上失败

标签: excel vba


【解决方案1】:
Sub ApplyValidation()

    Dim c As Range

    For Each c In Worksheets("Data").Cells(1, 1).Resize(1, totalCols).Cells
        With c.Offset(1, 0).Resize(totalRows - 1, 1).Validation
            .Delete
            .Add Type:=xlValidateList, Formula1:="=" & GetRange(c)
            .ShowError = False
        End With
    Next c

End Sub

Function GetRange(cell As Variant) As String
    If cell.Value = "Column One Name" Then
       GetRange = "RangeOne"
    ElseIf cell.Value = "Column Two Name" Then
       GetRange = "RangeTwo"
    Else
       GetRange = ""
    End If
End Function

【讨论】:

  • 不幸的是,这在 Add 行上给出了 1004。它在尝试向第一个单元格添加验证时停止。
  • 编辑了我的答案 - 问题在于对GetRange()的调用
  • 不幸的是,在进行此更改后,excel 仍然在第一列中第一个单元格的“添加”行中阻塞
  • 我刚刚在 30,000 行 x 100 列的范围内运行它,它还可以(而且速度很快)。我确实在GetRange() 中有错字(End Sub 而不是End Function
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多