#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
Я записал отладочную информацию в немедленное окно, чтобы ускорить выполнение кода, это повышает эффективность устранения неполадок.