Заполнение строки данными из несмежных диапазонов
Прошу подсказать, почему возникает ошибка при заполнении массива?
Несколько раз проверял синтаксис, вроде всё нормально, но не работает. Жму F8 (пошаговое выполнение макроса), но попытка заполнить массив в строке NumStrok = Array(...) вызывает ошибку.
Что не так?
Sub Макрос1()
Dim NumStrok(1 To 21) As String
NumStrok = Array("B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "H11", "I11", "J11", "K11", "H13", "I13", "J13", "K13", "B14", "D14", "B15", "D15", "H16")
Dim NumKol(1 To 21) As String
NumKol = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U")
Dim OrgData(21) As Variant
Dim KakaStroka As String
Sheets("Ввод").Select
For i = 1 To 21
OrgData(i) = Range(NumStrok)
Next
KakaStroka = CStr(CInt(OrgData(1)) + 4)
Sheets("База").Select
For i = 1 To 21
Range(NumKol + KakaStroka) = OrgData(i)
Next
End Sub
Ответы (1 шт):
Ошибка не одна, их много. А без понимания конечной задачи код смотрится сборной солянкой.
- Не нужно задавать размерность массива, если он будет заполняться диапазоном с листа или массивом констант. При объявлении массива размерность можно задать, если он впоследствии будет заполняться поэлементно.
OrgData(i) = .Range(NumStrok) Хотите передать в массив значение ячейки? Не тут-то было...
Во-первых, сразу же ошибка - не указан элемент массива-передатчика, надо
NumStrok(i).При декларации массива
OrgDataуказано, что его элементы типаVariant(т.е. могут быть любого типа). В цикле массив заполняетсяRange(NumStrok(i))... Но чем? ВOrgDataможет быть передано значение, которое находится по ссылке, но может быть записан и адрес ссылки!
Вывод. Всегда явно указывать, что хотим получить - Range(NumStrok(i)).Value
- Знак + (плюс). Это может быть и объединение текстовых строк, и суммирование числовых данных. И его действие зависит от первого элемента перед знаком.
CInt(OrgData(1)) + 4 - здесь в элементе массива может быть текст "B2" (см. выше ошибку 3). Попытка задать тексту тип "целое" - ошибка. Если без CInt, получим конкатенацию (объединение строк) - "B2" + 4 = "B24"
Range(NumKol + KakaStroka) - здесь NumKol - число, предполагается суммирование, но KakaStroka - текcт. Результат попытки суммирования с текстом - ошибка. Если в KakaStroka число в текстовом формате (ведь переменная типа String), получим суммирование двух чисел - номера столбца и номера строки. Догадайтесь, что будет :)
Вывод. Для суммирования применять + , для объединения текстов &. Если в переменной предполагается хранение числового значения, то почему эта переменная декларируется строковой?
Примечание. Почему в примере выше
B2, а неB1? Если в модуле не декларирован оператор принудительного указания первого элемента массивов, то при заполнении массивом констант по умолчанию первый элемент массива - 0 (ноль). Отсюда еще дна неточность - цикл нужно начинать с нуля, а не с единицы.Sheets("Ввод").Select. Для обращения к диапазонам не обязательно активировать лист.Массив
NumKolлишний. Ссылку можно формировать и так:Cells(KakaStroka, i) = OrgData(i)Массив
OrgDataи первый цикл тоже лишние, если значение.Range(NumStrok(i))передавать во втором цикле напрямую в ячейки.
Но можно поступить по-другому. Обращение к объектам листа - процесс медленный. Лучше значения массива передать в диапазон, без цикла.
Если задумка понята правильно, код может быть таким:
Sub Макрос1()
Dim NumStrok(), OrgData(20)
Dim KakaStroka As Long ' перевод: совсем плохая строка :) '
Dim j As Long
NumStrok = Array("B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "H11", "I11", "J11", "K11", "H13", "I13", "J13", "K13", "B14", "D14", "B15", "D15", "H16")
With Sheets("Ввод")
For j = 0 To 20
OrgData(j) = .Range(NumStrok(j)).Value
Next j
KakaStroka = OrgData(0) + 4
Sheets("Ввод").Cells(KakaStroka, 1).Resize(1, 21).Value = OrgData
End With
End Sub
Дополнение. Неважно, в каком месте кода декларируются переменные, память откусывается сразу, в начале работы макроса.