Используйте массив Variant
.
Dim values() As Variant
Теперь ваш код делает предположения, которые следует удалить.
BT = Range("A12") '<~ implicit: ActiveSheet.Range("A12").Value
Если вы хотите получить значение A12
из определенного указанного c листа, тогда вы должны квалифицировать этот Range
вызов участника с правильным Worksheet
объектом. См. CodeName: Sheet1 для получения дополнительной информации, но если коротко, если этот лист находится в ThisWorkbook
, вы можете сделать это:
BT = Sheet1.Range("A12").Value
И теперь предположения пропали. Правильно? Неправильно. BT
не объявлено (по крайней мере, не здесь). Если он объявлен и не является Variant
, то при таком назначении существует потенциальная ошибка несоответствие типов . Фактически, единственный тип данных, который может принимать любое значение ячейки, это Variant
:
Dim BT As Variant
BT = Sheet1.Range("A12").Value
Здесь мы предполагаем, что BT
является числовым значением c :
ReDim IT(BT) As String
Это еще одно предположение. Мы не знаем , что BT
это число c. Мы даже не знаем, что это значение, которое может быть приведено к типу цифр c: мы должны выручить, если это не так:
If Not IsNumeric(BT) Then
MsgBox "Cell A12 contains a non-numeric value; please fix & try again."
Exit Sub
End If
ReDim IT(BT) As String
Теперь, когда будет работать ... но тогда, только верхняя граница является явной; это массив на основе 0 или 1? Если модуль говорит Option Base 1
, то он основан на 1. В противном случае это основано на 0 - неявные нижние границы массива являются простым источником ошибок "off-by-one" (например, как вы заполняете массивы, начиная с индекса 1, оставляя индекс 0 пустым). Всегда делайте границы массива явными:
ReDim IT(1 To BT) As String
Непонятно, зачем вам вообще нужно 3 массива, и почему вы только заполняете (i,i)
в третьем - вы не можете заполнить 2D-массив Do...Loop
структура; вам нужно каждое значение y
для каждого значения x
, и если вы не жестко закодируете ширину массива, это будет вложенное l oop.
Более того, цикл на ActiveCell
и Select
из-за Offset
делает код 1) очень трудным для понимания и 2) невероятно неэффективным.
Рассмотрим:
Dim lastRow As Long
lastRow = Sheet1.Range("B" & Sheet1.Rows).End(xlUp).Row
ReDim values(1 To lastRow, 1 To 2) As Variant
Dim currentRow As Long
For currentRow = 2 To lastRow
Dim currentColumn As Long
For currentColumn = 1 To 2
values(currentRow, currentColumn) = Sheet1.Cells(currentRow, currentColumn).Value
Next
Next
Теперь, если мы этого не сделаем нам нужен любой вид логики c в этом l oop, и все, что нам нужно, это получить массив 2D-вариантов, который содержит каждую ячейку в B2:B???
, тогда нам не нужны никакие циклы:
Dim values As Variant
values = Sheet1.Range("A2:B" & lastRow).Value
И готово: values
- это двумерный вариантный массив на основе 1 (потому что он взят из Range
), который содержит значения каждой ячейки в A2:B{lastRow}
.
Примечание. Код, который потребляет этот массив должен избегать предположений о типах данных в нем.