Отладка с использованием массивов в VBA

#arrays #vba #excel

#массивы #vba #excel

Вопрос:

Мне нужно написать программу, которая хранит имена (расположенные во 2-м столбце) в массиве, когда имя имеет «X» в 8-м столбце, но у меня возникают проблемы с помещением имен в массив. Когда я запускаю его сейчас, я получаю пустое значение для значения в массиве. После некоторой отладки я обнаружил, что значение i, которое указывает, какое место в массиве выбрано, оказывается равным 0, а это не то, что я хотел.

Вот код:

 Dim rowCount As Integer
Dim duplicateNames(100) As String
Dim duplicateNameCounter As Integer
    duplicateNameCounter = 0

'Count the number of rows'
rowCount = WorksheetFunction.CountA(Range("B1:B5000"))

'Find the names with an X next to them and put them in the array'
For i = 1 To 100
    If Cells(i, 8).Value = "X" Then
        MsgBox ("Found a name to put in the array!")
        duplicateNames(i) = Cells(i, 2).Value
        duplicateNameCounter = duplicateNameCounter   1
    End If
Next i

'Show the contents of the array'
For i = 1 To duplicateNameCounter
    MsgBox ("Here's the slot in the array: " amp; i amp; vbNewLine amp; "Here's the name: " amp; duplicateNames(i))
Next i
  

Я впервые использую массивы в VBA, поэтому я думаю, что в этом и заключается моя проблема. У меня есть опыт работы с массивами C , но они не кажутся слишком разными.

Любая помощь будет оценена. Спасибо!

Комментарии:

1. Вы бы просто хотели duplicateNames(i) = Cells(i, 2).Value быть duplicateNames(duplicateNameCounter) = Cells(i, 2).Value

Ответ №1:

Вы не увеличиваете duplicateNameCounter так же, как увеличиваете свой For Each цикл. Я думаю, что это проблема.

Предположим, у вас есть «X» в строке 1, а также в строке 100, но остальные ячейки в вашем столбце 8 пустые (или что-то еще, в них нет «X»).

В конце этого блока i будет 100 , и будут имена только в слотах 1 и 100. ОДНАКО duplicateNameCounter будет только значение 2 .

 For i = 1 To 100
    If Cells(i, 8).Value = "X" Then
        MsgBox ("Found a name to put in the array!")
        duplicateNames(i) = Cells(i, 2).Value
        duplicateNameCounter = duplicateNameCounter   1
    End If
Next i
  

Поэтому, когда вы делаете это, вы в основном делаете For i = 1 to 2 , и это не даст вам ожидаемых результатов, потому что для правильного отображения второго дубликата он должен попасть в 100-й слот в массиве, чего он никогда не сделает.

 For i = 1 To duplicateNameCounter
    MsgBox ("Here's the slot in the array: " amp; i amp; vbNewLine amp; "Here's the name: " amp; duplicateNames(i))
Next i
  

Я думаю, что комментарий от @chancea выше должен решить проблему.

Комментарии:

1. Из того, что я собрал, я думаю, что это решит проблему, просто я думаю, что ему также придется инициализировать duplicateNameCounter 1 , а не 0

2. Да, хорошая точка @chancea, что переменная должна инициализироваться в 1 , а не 0.

3. Прекрасно! Большое спасибо! Это просто решило мою проблему. Это простая, глупая проблема, на которую просто нужно взглянуть свежим взглядом. Большое спасибо вам обоим!

Ответ №2:

Было несколько пунктов, которые препятствовали успешному выполнению вашего кода в Excel. Рекомендуется использовать параметр Explicit, поскольку он заставит вас объявлять все переменные и считается хорошей практикой программирования.

 Option Explicit

Public Sub asdfasdfasdf()
Dim rowCount As Integer, i As Integer
Dim duplicateNames() As String
Dim duplicateNameCounter As Integer
  

Установка счетчика в 0 позволяет массиву значений хранилища не иметь пустых значений

 duplicateNameCounter = 0
  

Ваша формула диапазона искала только 5000 строк данных, поэтому она была изменена для сканирования всего столбца, чтобы предотвратить пропущенные записи

 'Count the number of rows'
rowCount = WorksheetFunction.CountA(Range("B:B"))
  

Вы не искали буквы X в нижнем и верхнем регистре в тесте.

 'Find the names with an X next to them and put them in the array'
For i = 1 To rowCount
    If Cells(i, 8).Value = "X" Or Cells(i, 8).Value = "x" Then
        duplicateNameCounter = duplicateNameCounter   1
  

Было добавлено изменение размера массива, чтобы размер массива отображал количество найденных хранилищ

         ReDim Preserve duplicateNames(duplicateNameCounter)
        Debug.Print "Found a name to put in the array! " amp; Cells(i, 2).Value
  

Вы не использовали значение duplicateNameCounter в массиве duplicateNames.

         duplicateNames(duplicateNameCounter) = Cells(i, 2).Value
    End If
Next i

'Show the contents of the array'
For i = 1 To duplicateNameCounter
    MsgBox "Here's the slot in the array: " amp; i amp; vbNewLine amp; "Here's the name: " amp; duplicateNames(i)
Next i
End Sub
  

Я записал отладочную информацию в немедленное окно, чтобы ускорить выполнение кода, это повышает эффективность устранения неполадок.