2016-04-05 4 views
1

Следующий фрагмент кода VBA пытается выполнить простой оператор If на столбце excel длиной около 80 тыс. Строк. Произошла следующая ошибка. ОшибкаМетод «Значение» объекта «Диапазон» не выполнен

времени выполнения '-2147417848 (80010108)': Метод 'Значение' объекта 'Range' не удалось

Что происходит здесь не так?

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 
+1

В какой строке происходит ошибка? Вместо использования '.Text', вы получаете ту же ошибку с' .Value'? – BruceWayne

+0

Я думаю, что требуется более подробная информация. Этот код работает в простом тесте, который я сделал (без ошибок). – OldUgly

+0

Возможно, вам стоит рассмотреть инструкцию 'case'. – findwindow

ответ

3

Окружающая среда VBA невосприимчива к нестабильности. Если у вас было несколько сбоев, сохраните свою работу и перезагрузите компьютер (холодная загрузка).

С учетом этого каждая из этих подпрограмм работает менее чем за полсекунды, а не за 27 секунд, которые ваш оригинал взял, чтобы пройти через ячейки 80K.

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 для поиска строки в строке, как это делает ваш оригинал. Повторно используя вариантный массив для хранения новых значений, он делает условные операторы более эффективными, чем чтение по ячейкам. Значения аналогичным образом возвращаются ru masse в колонку Z.

Смежные вопросы