【问题标题】:Method 'Value' of object 'Range' failed对象“范围”的方法“值”失败
【发布时间】:2022-03-15 04:09:40
【问题描述】:

以下 VBA 代码的 sn-p 尝试在大约 80k 行长的 excel 列上执行简单的 If 语句。发生以下错误。

运行时错误“-2147417848 (80010108)”: 对象“范围”的方法“值”失败

这里出了什么问题?

Dim r As Long
Dim lastrow As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For r = 2 To lastrow
    If InStr(Range("I" & r).Text, "WH") Then
        Range("Z" & r).Value = "O"
    ElseIf InStr(Range("I" & r).Text, "MOD") Then
        Range("Z" & r).Value = "M"
    ElseIf InStr(Range("I" & r).Text, "VER") Then
        Range("Z" & r).Value = "V"
    ElseIf InStr(Range("I" & r).Text, "WT") Then
        Range("Z" & r).Value = "WT"
    ElseIf InStr(Range("E" & r).Text, "OIL") Then
        Range("Z" & r).Value = "OIL"
    Else: Range("Z" & r).Value = "N"
    End If
Next r

【问题讨论】:

  • 错误出现在哪一行?不是使用.Text,而是使用.Value 得到同样的错误?
  • 我认为需要更多细节。这段代码在我做的简单测试中有效(没有错误)。
  • 可能要考虑case声明。
  • 当前工作表是您正在搜索的工作表吗?当您收到错误消息时,r 的值是多少?
  • 真的需要 InStr 吗? MOD、VER、OIL 等是整个单元格还是单元格内较长字符串的一部分?

标签: vba excel


【解决方案1】:

VBA 环境无法避免不稳定。如果您有多次崩溃,请保存您的工作并重新启动您的机器(冷启动)。

话虽如此,这些例程中的每一个都在不到半秒的时间内运行,而您的原始例程通过 80K 单元需要 27 秒。

Sub oilWT2()
    Dim r As Long, vVALs As Variant

    Debug.Print Timer
    With Worksheets("Sheet5")
        vVALs = .Range(.Cells(2, "I"), .Cells(rows.Count, "A").End(xlUp).Offset(0, 8)).Value2
        For r = LBound(vVALs, 1) To UBound(vVALs, 1)
            Select Case UCase(vVALs(r, 1))
                Case "WH"
                    vVALs(r, 1) = "O"
                Case "MOD", "VER"
                    vVALs(r, 1) = Right(vVALs(r, 1), 1)
                Case "WT", "OIL"
                    'do nothing - value already correct
                Case Else
                    vVALs(r, 1) = "N"
            End Select
        Next r
        .Cells(2, "Z").Resize(UBound(vVALs, 1), 1) = vVALs
    End With
    Debug.Print Timer
End Sub

Sub oilWT3()
    Dim r As Long, vVALs As Variant

    Debug.Print Timer
    With Worksheets("Sheet5")
        vVALs = .Range(.Cells(2, "I"), .Cells(rows.Count, "A").End(xlUp).Offset(0, 8)).Value2
        For r = LBound(vVALs, 1) To UBound(vVALs, 1)
            Select Case True
                Case CBool(InStr(1, vVALs(r, 1), "WH", vbTextCompare))
                    vVALs(r, 1) = "O"
                Case CBool(InStr(1, vVALs(r, 1), "MOD", vbTextCompare)) Or _
                     CBool(InStr(1, vVALs(r, 1), "VER", vbTextCompare))
                    vVALs(r, 1) = Right(vVALs(r, 1), 1)
                Case CBool(InStr(1, vVALs(r, 1), "WT", vbTextCompare))
                    vVALs(r, 1) = "WT"
                Case CBool(InStr(1, vVALs(r, 1), "OIL", vbTextCompare))
                    vVALs(r, 1) = "OIL"
                Case Else
                    vVALs(r, 1) = "N"
            End Select
        Next r
        .Cells(2, "Z").Resize(UBound(vVALs, 1), 1) = vVALs
    End With
    Debug.Print Timer
End Sub

前者只是查看整个单元格内容;后者使用 InStr function 来搜索字符串中的字符串,就像您原来的那样。通过重用变量数组来存储新值,它使条件语句比逐个单元格读取更有效。这些值类似地en masse返回到Z列。

【讨论】:

    【解决方案2】:

    当我收到此错误时,是因为我创建了一个无限循环,例如,Worksheet_Change Sub 设置了 Range 的值,创建了另一个更改。仔细检查是什么触发了这些 Sub,并确保 Sub 不会无限触发自身。

    【讨论】:

      猜你喜欢
      • 2016-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-09
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多