Ошибка выполнения 5: удаление некоторых элементов из коллекции VBA - PullRequest
0 голосов
/ 03 июня 2019

Я создал коллекцию Excel из столбца Excel, используя итерацию FOR для этого столбца.Тем не менее, эта коллекция включает в себя заголовок и пустые столбцы.Я хочу удалить эти пустые столбцы и заголовок из коллекции и не знаю, как.Основываясь на моем коде, я получаю сообщение об ошибке выполнения 5

Я пытался использовать итерацию For Each для элемента collection и collection_name.Remove на основе условия, которое вы можете увидеть ниже, но это не сработало,

Public Sub outer_lÖÖp()


'creating a collection of the policy numbers
Sheets("MappingSheet").Select
Dim policynums As New Collection
Dim i As Integer
For i = 1 To 100
    policynums.Add (Cells(i, 1))
Next i

'getting rid of "Policy Number" and empty strings from collection
Worksheets("GL").Activate
For Each element In policynums
    If element = "Policy Number" Or element = "" Then
        policynums.Remove element
    End If
Next element

For Each element In policynums
    MsgBox (CStr(element))
Next element


End Sub

При этом возвращается ошибка выполнения 5, недопустимый элемент процедуры или вызов.Как я могу решить мою проблему и удалить все нерелевантные строки из этой коллекции?

1 Ответ

2 голосов
/ 03 июня 2019

Данные поступают с определенного листа. Первый шаг - получить этот объект.

Dim sheet As Worksheet
'TODO make this work off a Workbook object so we don't need to care what workbook is currently active.
Set sheet = ActiveWorkbook.Worksheets("MappingSheet")

Далее нам нужен объект коллекции - избегайте As New, он создает объект с автоматически создаваемой инстанцией, и это имеет последствия, с которыми вы действительно не хотите иметь дело.

Dim elements As Collection
Set elements = New Collection

Далее мы зациклимся 1 To 100. Хотя это соответствует диапазону Integer, мы избегаем устаревшего 16-разрядного целочисленного типа, особенно для чего-то вроде номера строки, который может быть в миллионах: вместо этого используйте Long, 32-разрядный целочисленный тип.

Dim currentRow As Long
For currentRow = 1 To 100 'TODO determine how many rows we need before we start looping.
    elements.Add sheet.Cells(currentRow, 1).Value
Next

Теперь, зачем повторять коллекцию снова, просто чтобы удалить вещи, которые не должны были быть добавлены в первую очередь?

Dim currentRow As Long
For currentRow = 1 To 100 'TODO determine how many rows we need before we start looping.
    Dim cell As Range
    Set cell = sheet.Cells(currentRow, 1)
    If Not IsError(cell.Value) Then
        If Trim$(cell.Value) <> vbNullString And cell.Value <> "Policy Number" Then
            elements.Add sheet.Cells(currentRow, 1).Value
        End If
    End If
Next

Если единственная причина для проверки литерала "Policy Number" состоит в том, чтобы избежать первой записи, которая является заголовком строки, удалите эту проверку и вместо этого начните цикл со строки 2 - предполагая, что заголовок таблицы находится в строке 1:

For currentRow = 2 To 100 'TODO determine how many rows we need before we start looping.
    Dim cell As Range
    Set cell = sheet.Cells(currentRow, 1)
    If Not IsError(cell.Value) Then
        If Trim$(cell.Value) <> vbNullString Then
            elements.Add sheet.Cells(currentRow, 1).Value, Key:="Row" & currentRow
        End If
    End If
Next

Обратите внимание на именованный аргумент Key (только названный для пояснения в этом посте - у него не будет , чтобы быть названным ... хотя это тоже не повредит): если вы хотите удалить элемент с ключом "Row12" из коллекции, вы должны сделать это:

elements.Remove "Row12"

Наконец, MsgBox (и любой другой вызов процедуры, для которого вы не захватываете возвращаемое значение) должен выглядеть так:

MsgBox element

Посторонние скобки имеют синтаксическое значение, которого вы, вероятно, не ожидаете. Это не скомпилируется:

MsgBox (element, vbInformation)

Поскольку круглые скобки говорят VBA оценивать их содержимое как выражение значения и передавать результат этого выражения ByVal в вызванную процедуру. Но (foo, bar) не является допустимым выражением, поэтому код отказывается компилироваться.

В любом случае, эмпирическое правило, вы хотите Debug.Print содержимое коллекции, или просто использовать окна отладчика для проверки ее содержимого - MsgBox в цикле неприятно раздражает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...