【问题标题】:Code seems to run forever and Error: block variable not set (VBA)代码似乎永远运行并且错误:未设置块变量(VBA)
【发布时间】:2018-06-30 02:22:33
【问题描述】:

我对 VBA 完全陌生,所以请多多包涵。

我正在尝试编写一个子程序,该程序将遍历某一列中的每一行并与另一张工作表的标准进行比较。例如,如果它包含“x”,则将返回该值。但是,当我尝试运行代码时,代码会永远运行并导致计算机挂起。

这是我到目前为止编写的代码。它一直提示错误:未设置对象变量和块变量。 PS:我在使用'Application.WorksheetFunction.Index'时出现错误,在阅读其他线程时,建议删除'WorksheetFunction'。我不确定这是否会导致问题,我还想澄清删除“WorksheetFunction”字样的原因

非常感谢您!

Sub sub_inputData()
Dim ws As Worksheet: Set ws = ActiveSheet
Dim lastrow as range 
lastrow = ws.Cells (ws.Rows.Count, 17).End (xlUp).row 

Dim rng As Range
Set rng = ws.Range("Q4:Q" & lastrow)
Dim rngCell As Range

On Error Resume Next

For Each rngCell In rng
    If rngCell.Offset(0, -13) = "x" Then
       rngCell = Application.Index(Sheets("Data").Range _
       ("D805:D813"), Application.Match(rngCell.Offset(0, -15), Sheets("Data").Range _
       ("D805:D813"), 1))
    ElseIf rngCell.Offset(0, -13) = "y" Then
       rngCell = Application.Index(Sheets("Data").Range _
       ("D27:D34"), Application.Match(rngCell.Offset(0, -15), Sheets("Data").Range _
       ("D27:D34"), 1))
    ElseIf rngCell.Offset(0, -13) = "z" Then
       rngCell = Application.Index(Sheets("Data").Range _
       ("D718:D726"), Application.Match(rngCell.Offset(0, -15), Sheets("Data").Range _
       ("D718:D726"), 1))
    Else: rngCell = vbNullString
    End If

Next rngCell

     Call sub_code2
     Call sub_code3
     Set rngCell = Nothing
     Set rng = Nothing
End Sub 

【问题讨论】:

  • 如果在弹出错误信息的时候点击“Debug”,你的代码的哪一行是高亮的?
  • 这一行:lastrow = ws.Cells (ws.Rows.Count, 17).End (xlUp).row
  • Q列有多少行数据?
  • 我现在有 1748 行,但列表会不断增加
  • 您不需要使用 VBA 来执行此操作...您应该能够使用 CHOOSE 功能。我很快就会发布一个例子。

标签: excel vba forever


【解决方案1】:

您在此处修改的代码存在几个问题。
1) Dim lastrow As Long,不是 Range
2)Else:不是必须的,直接使用Else
3) Set rngCell = Nothing & Set rng = Nothing 不是必须的。解释见this链接
4) 由于您只检查 1 个单元格的值,您可以使用 Select Case 获得适度清洁的代码。
5) On Error Resume Next 不适合调试代码。您想查看错误以便处理它们。我建议查找那段代码的 do'sdont's

Sub sub_inputData()
Dim ws As Worksheet: Set ws = ActiveSheet
Dim lastrow As Long: lastrow = ws.Range("Q" & ws.Rows.Count).End(xlUp).Row
Dim rng As Range: Set rng = ws.Range("Q4:Q" & lastrow)
Dim rngCell As Range

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

For Each rngCell In rng
    Select Case rngCell.Offset(0, -13)
        Case "x"
            rngCell = Application.Index(Sheets("Data").Range _
            ("D805:D813"), Application.Match(rngCell.Offset(0, -15), Sheets("Data").Range _
            ("D805:D813"), 1))
        Case "y"
            rngCell = Application.Index(Sheets("Data").Range _
            ("D27:D34"), Application.Match(rngCell.Offset(0, -15), Sheets("Data").Range _
            ("D27:D34"), 1))
        Case "z"
            rngCell = Application.Index(Sheets("Data").Range _
            ("D718:D726"), Application.Match(rngCell.Offset(0, -15), Sheets("Data").Range _
            ("D718:D726"), 1))
        Case Else
            rngCell = ""
    End Select
Next rngCell

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic

     Call sub_code2
     Call sub_code3
End Sub

【讨论】:

    【解决方案2】:

    另一种可能性是使用Switch()函数:

    Sub sub_inputData()
        Dim rngCell As Range, rangeToSearch As Range
        Dim val As Variant
    
        With ActiveSheet ' reference data sheet (better: With Worksheets("MyDataSheetName"))
            For Each rngCell In .Range("Q4", .Cells(.Rows.Count, "Q").End(xlUp)) ' loop throughreferenced sheet column Q cells from row 4 down to last not empty one
                val = rngCell.Offset(, -13).Value2 ' store column D current cell row value
                Set rangeToSearch = Sheets("Data").Range(Switch(val = "x", "D805:D813", val = "y", "D27:D34", val = "z", "D718:D726", True, "A1")) ' set range to search into with respect to stored value. set it to "A1" to signal no search is needed
                If rangeToSearch.Address <> "$A$1" Then ' if search is needed 
                    rngCell.Value = Application.Index(rangeToSearch, Application.Match(rngCell.Offset(, -15).Value2, rangeToSearch, 1)) 'do the lookup
                Else
                    rngCell.ClearContents ' clear current cell
                End If
            Next
        End With
    
        sub_code2 ' no need for 'Call' keyword
        sub_code3 ' no need for 'Call' keyword
    End Sub
    

    【讨论】:

      【解决方案3】:

      您似乎正在根据 D 列中的值有效地选择一个查找范围,然后根据 B 列中的值对该范围进行查找。

      如果是这样,您可以完全使用公式来执行此操作,这样会更有效,因为它只会在需要时(即仅在其输入发生变化时)在特定单元格上运行。

      这是一个使用表格和表格表示法的示例。表格非常适合这一点,因为您无需修改​​公式来处理新数据。

      C2中的公式是=VLOOKUP([@ID],CHOOSE(VLOOKUP([@Condition],Conditions,2,FALSE),X,Y,Z),2,FALSE)

      该公式使用 E1:F3 中的“条件”表来确定要对其他哪些表进行查找。我已将其他表命名为 X、Y 和 Z。

      【讨论】:

      • 我没有选择进行 vlookup,因为在它们返回值之前我必须满足/查找更多标准。而且我也不断收到'if'函数的错误:/
      • 好的。您可以随时将它们添加到您的原始问题中。 CHOOSE 函数肯定会让您在没有 VBA 的情况下更有效地完成这项工作。
      猜你喜欢
      • 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
      相关资源
      最近更新 更多