Функция Array2worksheet позволяет быстро сформировать лист на основании данных из двумерного массива
Sub Array2worksheet(ByRef sh As Worksheet, ByVal Arr, ByVal ColumnsNames) ' Получает двумерный массив Arr с данными, ' и массив заголовков столбцов ColumnsNames. ' Заносит данные из массива на лист sh If UBound(Arr, 1) > sh.Rows.Count - 1 Or UBound(Arr, 2) > sh.Columns.Count Then MsgBox "Массив не влезет на лист " & sh.Name, vbCritical, _ "Размеры массива: " & UBound(Arr, 1) & "*" & UBound(Arr, 2): End End If With sh .UsedRange.Clear ColumnsNamesCount = UBound(ColumnsNames) - LBound(ColumnsNames) + 1 .Range("a1").Resize(, ColumnsNamesCount).Value = ColumnsNames .Range("a1").Resize(, ColumnsNamesCount).Interior.ColorIndex = 15 .Range("a2").Resize(UBound(Arr, 1), UBound(Arr, 2)).Value = Arr .UsedRange.EntireColumn.AutoFit End With End Sub
Sub ПримерИспользованияФункции_Array2worksheet() ' формируем двумерный массив, и заполняем его данными ReDim MyArr(1 To 20, 1 To 3) For i = 1 To 20: For j = 1 To 3: MyArr(i, j) = "Ячейка " & i & " * " & j: Next j: Next i ' создаём новую книгу, а в ней - лист для массива Dim sh As Worksheet: Set sh = Workbooks.Add(-4167).Worksheets(1): sh.Name = "Массив" ' заносим данные из массива MyArr на лист sh Array2worksheet sh, MyArr, Array("Столбец 1", "Столбец 2", "Столбец 3") End Sub
Несколько модернизированный вариант функции — вставку на лист можно начинать с любой выбранной ячейки:
Sub Array2worksheetEx(ByRef FirstCell As Range, ByVal Arr, ByVal ColumnsNames) ' Получает двумерный массив Arr с данными, и массив заголовков столбцов ColumnsNames. ' Заносит данные из массива на лист, начиная с ячейки FirstCell Dim sh As Worksheet: Set sh = FirstCell.Worksheet If UBound(Arr, 1) > sh.Rows.Count - FirstCell.Row Or _ UBound(Arr, 2) > sh.Columns.Count - FirstCell.Column Then MsgBox "Массив не влезет на лист " & sh.Name, vbCritical, _ "Размеры массива: " & UBound(Arr, 1) & "*" & UBound(Arr, 2): End End If ColumnsNamesCount = UBound(ColumnsNames) - LBound(ColumnsNames) + 1 On Error Resume Next With FirstCell.Resize(1, ColumnsNamesCount) .ClearContents Intersect(sh.Range((FirstCell.Row + 1) & ":" & sh.Rows.Count), _ sh.UsedRange, .EntireColumn).ClearContents .Value = ColumnsNames .Interior.ColorIndex = 15: .Font.Bold = True FirstCell.Offset(1).Resize(UBound(Arr, 1), UBound(Arr, 2)).Value = Arr .EntireColumn.AutoFit End With End Sub
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
Sub Viborka() 'запускать после выгрузки и обработки Application.ScreenUpdating = False Dim a LRow = Sheets(2).Cells(Rows.Count, "A").End(xlUp).Row ReDim a(1 To LRow, 1 To 6) 'Создаем массив с указанием размеров For i = 2 To LRow If Left(Sheets(2).Cells(i, 1), 3) = "876" Then Rem_zak = Left(Sheets(2).Cells(i, 1), 9) Name_zak = Trim(Mid(Sheets(2).Cells(i, 1), 19, 40)) 'Наполняем массив a(i, 1) = Rem_zak a(i, 2) = Name_zak a(i, 5) = Trim(Mid(Sheets(2).Cells(i + 2, 1), 25, 40)) If Sheets(2).Cells(i, 1) <> "" Then Start_str = i + 2 TM = Trim(Left(Sheets(2).Cells(Start_str, 1), 14)) End If End If On Error Resume Next a(Start_str, 2) = Name_zak If Left(Sheets(2).Cells(Start_str, 1), 3) <> "876" Then a(Start_str, 1) = Rem_zak a(Start_str, 3) = TM If Left(Sheets(2).Cells(Start_str, 1), 4) = "5000" Or Left(Sheets(2).Cells(Start_str, 1), 4) = "6000" Then a(Start_str, 4) = Trim(Left(Sheets(2).Cells(Start_str, 1), 15)) a(Start_str, 5) = Trim(Left(Sheets(2).Cells(Start_str - 1, 1), 24)) a(Start_str, 6) = Trim(Mid(Sheets(2).Cells(Start_str - 1, 1), 25, 40)) Else If Left(Sheets(2).Cells(Start_str, 1), 2) = "33" And Mid(Sheets(2).Cells(Start_str, 1), 18, 2) _ = "-3" Or Left(Sheets(2).Cells(Start_str, 1), 2) = "ДУ" And Mid(Sheets(2).Cells(Start_str, 1), 19, 2) _ = "-3" Then a(Start_str, 5) = Trim(Left(Sheets(2).Cells(Start_str, 1), 24)) a(Start_str, 6) = Trim(Mid(Sheets(2).Cells(Start_str, 1), 25, 40)) End If End If Start_str = Start_str + 1 End If Next 'Надо удалить из массива все элементы в которых 3 последних элемента a(i,4) и a(i,5) и a(i,6) пустые 'Выгрузить обработанный массив в лист1 Application.ScreenUpdating = True End Sub |
Оптимальный путь вывода большого одномерного массива на лист |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
Добрый день. Ищу человека который будет обучать меня программированию на vba in excel Что я знаю о vba. Знаю объектную модель Application, workbook, sheet, cell Что я могу научить Кому это интересно обращайтесь на почту dmitriy8308@mail.ru |
|
если честно, лучшая школа это: Я прочитал по Excel и VBA книг 20, но все прочитанные знания быстро забываются, если их не применять на практике. Я отдал все свои книги и перешёл на форум, читая ответы на вопросы других людей и пытаясь помочь другим людям быстрее осваиваешь материал и учишься. Перейдём к массивам, вот 3 примера работы с массивами Sub TestArray() ‘ВАРИАНТ 1 Dim i As Long ‘объявляем переменную типа Long (целое число) ‘ВАРИАНТ 2 ‘ВАРИАНТ 3 Скопируйте этот код в редактор VBA (только копировать в РУССКОЙ РАСКЛАДКЕ КЛАВИАТУРЫ) и запустите его через F8 (пошаговый режим) и нажимайте F8 до конца макроса, вы увидите как работает код, а комментарии вам помогут понять смысл массивов. Если что-то будет не понятно, спрашивайте Павел |
|
Теперь давайте попробуем применить массивы к данным на листе Excel Sub TestArray2() ‘заполняем диапазон А1:А5 названиями месяцев ‘переносим данные из диапазона А1:А5 в массив Так же скопируйте в русской раскладке код в VBE и запустите пошагово через F8. Павел |
|
Если для понимания нужно определение массива, то массив можно описать так: Массив — это именованный набор однотипных переменных, расположенных в памяти непосредственно друг за другом, доступ к которым осуществляется по индексу. Массивы бывают Одномерные, Двумерные и т.д. Двумерный массив — это как ячейки на листе Excel. Т.е. есть строки и есть столбцы. Если к Одномерному массиву можно обратиться так: переменная = Массив(5) То к Двумерному массиву нужно обращаться указывая и первый и второй индекс, например: Переменная = массив(5,3) Вот ещё один пример заполнения ОДНОМЕРНОГО массива Sub Test3() Павел |
|
Определение границ массива, на примере одномерного массива Sub TestArray4() ‘заполняем массив названиями месяцев ‘определяем нижнюю и верхнюю границу массива Чтобы узнать границы, например, двумерного массива нужно писать так LBound(iArray,2) UBound(iArray,2) Павел |
|
Давайте теперь рассмотрим пример работы с ДВУМЕРНЫМ массивом Sub TestArray5() Dim iArray(1 To 5, 1 To 3) ‘объявляем двумерных массив с размерностью 1 To 5, 1 To 3 For i = LBound(iArray, 1) To UBound(iArray, 1) ‘т.е. от 1 до 5 ‘сейчас у нас массив такой MsgBox «Верхний индекс ПЕРВОЙ размерости массива равен: » & UBound(iArray, 1) & vbLf & _ End Sub Так же скопируйте в русской раскладке клавиатуры код в редактор VBA и пожагово через F8 пройдитесь по коду Павел |
|
Все примеры, приведённые в этой теме я поместил в файл Excel, чтобы вам было удобнее тестировать код. См. файл P.S. Код можно посмотреть нажав Alt+F11 Павел |
|
vikttur Пользователь Сообщений: 47199 |
Студент++, здесь знаниями не отделаетесь, бутылкой тоже (не пьет). Готовьте большущую шоколадку |
{quote}{login=Ластик}{date=22.01.2012 05:36}{thema=}{post}Все примеры, приведённые в этой теме я поместил в файл Excel, чтобы вам было удобнее тестировать код. {/post}{/quote} |
|
{quote}{login=vikttur}{date=22.01.2012 06:01}{thema=}{post}Студент++, здесь знаниями не отделаетесь, бутылкой тоже (не пьет). Готовьте большущую шоколадку :){/post}{/quote} Это да |
|
nerv Пользователь Сообщений: 3071 |
Студент++, можете мне на почту написать. В теле письма: 1. Чему именно хотите научиться. p.s.: я, конечно, не супер-профессионал, но тем не менее, могу кое-чему научить. |
Hugo Пользователь Сообщений: 23251 |
Я помнится тоже не сразу массивы понял, пару раз на форуме спрашивал разъяснения. Resize тоже непонятная штука была Содержимое массивов удобно смотреть в окне Locals — сразу всё понятно, что где. |
угу, но я не стал писать об этом, чтобы на начальном этапе не запутывать. <EM>http://ru.wikipedia.org/wiki/%C8%ED%E4%E5%EA%F1%ED%FB%E9_%EC%E0%F1%F1%E8%E2</EM> |
|
VDM Пользователь Сообщений: 779 |
У меня вот ещё какой вопросы есть по массивам: Если двумерный массив мы можем рассматривать как аналог рабочего лиса Excel, то: |
Ого какая хорошая тема:) я и сам с удовольствием почитал так как с массивами тоже толком еще не умею обращаться:) но насколько я понимаю — строка массива — это цикл с фиксированным номером строки и переменной номера столбца? |
|
Hugo Пользователь Сообщений: 23251 |
VDM, 2 — это к слэну, он спец по CopyMemory, я это понять не могу но можно еще быстрее — цикл copymemory по столбцам Declare Sub CopyMemory Lib «kernel32» Alias «RtlMoveMemory» (Destination As Any, Source As Any, ByVal Length As Long) |
R Dmitry Пользователь Сообщений: 3103 Excel,MSSQL,Oracle,Qlik |
#17 22.01.2012 23:56:29 {quote}{login=VDM}{date=22.01.2012 11:26}{thema=}{post}1. Можно ли в самом массиве оперировать с «Resize»
|
|
VDM, к сожалению, нельзя. Свойства Resize, EntireRow, EntireColumn — относятся только к ячейкам листа Excel. Как бы аналог Resize для массива это Redim массив(новая размерность) т.е. можно объявить массив, например, из 5 элементов Dim myArray (1 to 5) а потом его переопределить Redim myArrray (1 to 10) но при Redim — массив полностью очищается Чтобы он не очищался используют конструкцию ReDim Preserve ReDim Preserve массив (новая верхняя граница) Вот пример. Sub TestArary6() ReDim myArray(1 To 10) ‘переопределяем размер массива (от 0 до 10 элементов) ReDim Preserve myArray(1 To 15) ‘расширяем массив до 15 элементов с сохранением значений массива End Sub НО!!! Нужно знать, что через ReDim Preserve можно изменять вниз/вверх только верхнюю границу массива. Изменение нижней границы вызовет ошибку По-английски данное условие звучит так: when you use Preserve, you can change the size of the array only by changing the upper bound; changing the lower bound causes an error. Если у нас массив двумерный, например Redim myArray (1 to 10, 1 to 3) то через ReDim Preserve можно будет менять только индекс 3 (т.е. верхний индекс второй размерности) на что-то другое, а другие индексы менять уже нельзя. Т.е. вы не можете изменить 10 на 15 ‘ так сработает ‘а так нет P.S. Пример с листом Excel это так для «умственного» восприятия. Так же можно выразиться, что двумерный массивы — это матрица. Но мне кажется, что это сложнее понять. Павел |
|
VDM Пользователь Сообщений: 779 |
УУУ, как всё сложно:) Правильно ли я понимаю, что той гибкости в работе с диапазонами как на рабочем листе массивы нам не представляют, и обращение к диапазону будет далеко не таким же прозрачным? |
vikttur Пользователь Сообщений: 47199 |
Тему прошел «по диагонали», может, это упоминалось раньше. Еще момент, на котором время тратил, пытаясь разобраться, почему созданный массив на лист выгружается на столбец правее: Простые вещи, но новички ошибаются. |
VDM Пользователь Сообщений: 779 |
Пока отвечал HUGO, получил ещё 2 ответа:) Во общем решил, что не буду впереди паровоза бежать, понял что всё это сложновато пока для восприятия. Все спасибо за разъяснения. |
Hugo Пользователь Сообщений: 23251 |
VDM, на самом деле с массивом работать проще, чем с листом. |
R Dmitry Пользователь Сообщений: 3103 Excel,MSSQL,Oracle,Qlik |
#23 23.01.2012 00:18:47 {quote}{login=VDM}{date=23.01.2012 12:04}{thema=}{post}УУУ, как всё сложно:){/post}{/quote}
|
|
VDM, Смотрите как удобно работать с данными на листе через массивы Sub Test() ‘допустим есть какие-то данные на листе ‘берём их в массив (массив получается двумерным) ‘в цикле умножаем каждое значение столбца на 2 ‘выгружаем наши новые данные обратно на лист Данный метод — намного быстрее, чем обрабатывать каждую ячейку на листе. Т.е. мы сперва берём данные с листа Excel в массив, обрабатываем их и обратно выгружаем на лист. Это быстрее, чем обращение к ячейкам листа |
|
R Dmitry Пользователь Сообщений: 3103 Excel,MSSQL,Oracle,Qlik |
#25 23.01.2012 00:32:19 Паш есть способ чуть проще
|
|
Hugo Пользователь Сообщений: 23251 |
Вот нашёл пример кода (не записал, где применял) — тут нужно было удалить строки с значениями, присутствующими на другом листе (по первым столбцам): Sub tt() Set r = Range([a1], [a65536].End(xlUp)) With Sheets(«что искать») With CreateObject(«Scripting.Dictionary») For i = 1 To UBound(a) r.Value = a End With Кода мало, работает почти моментально. Это были только числа, т.е. в удаляемые строки пишем текст, потом эти строки удаляем. |
VDM Пользователь Сообщений: 779 |
Нет, Вы меня не так поняли — я не собираюсь отказываться от массивов). 55557 |
слэн Пользователь Сообщений: 5192 |
{quote}{login=Hugo}{date=22.01.2012 02:59}{thema=}{post}Если массив типа Variant — т.е. как всюду в примерах, без явного указания типа массива, то в массиве могут храниться и числа, и даты, и строки. Т.е. что есть на листе — то и будет в массиве.{/post}{/quote} |
nerv Пользователь Сообщений: 3071 |
{quote}{login=vikttur}{date=23.01.2012 12:07}{thema=}{post}Массив, заданный как M(a To b) формирует массив строки, но не столбца. Если задать M(a To b;1), тогда a To b — строки.{/post}{/quote} это M(1 To 1) — одномерный массив Поскольку таблица excel представлена двумя измерениями, на лист можно выгрузить (через resize) только двумерный массив (насколько мне известно). |
Hugo Пользователь Сообщений: 23251 |
#30 23.01.2012 13:53:15 Чего? Sub tt() |
200?’200px’:»+(this.scrollHeight+5)+’px’);»> Option Base 1
Option Explicit
Sub proverka() ‘Для проверки
Dim i&
Dim x(1 To 77777)
For i = LBound(x) To UBound(x)
x(i) = i
Next
arToRange x, 1, 1
End Sub
Public Sub arToRange(ByVal arArray, startRow&, startColumn&) ‘arArray — входящий массив, _
startRow — строка с которой начать выгрузку, _
startColumn — колонка с которой начать выгрузку
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim ar(50000) ‘ выгружать будем по 50 тысяч
Dim tmp ‘массив для выгрузки остатка
Dim i&, v&, c& ‘ счетчики
Dim delitel&
Dim ostatok&
If Not UBound(arArray) — LBound(arArray) + 1 0 Then
ReDim tmp(1 To ostatok + 1)
For i = c To UBound(arArray)
tmp(v) = arArray(i)
v = v + 1
Next
Cells(startRow, startColumn).Resize(UBound(tmp)) = Application.WorksheetFunction.Transpose(tmp)
End If
Else
Cells(startRow, startColumn).Resize(UBound(arArray) — LBound(arArray) + 1) = Application.WorksheetFunction.Transpose(arArray)
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
200?’200px’:»+(this.scrollHeight+5)+’px’);»> Option Base 1
Option Explicit
Sub proverka() ‘Для проверки
Dim i&
Dim x(1 To 77777)
For i = LBound(x) To UBound(x)
x(i) = i
Next
arToRange x, 1, 1
End Sub
Public Sub arToRange(ByVal arArray, startRow&, startColumn&) ‘arArray — входящий массив, _
startRow — строка с которой начать выгрузку, _
startColumn — колонка с которой начать выгрузку
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim ar(50000) ‘ выгружать будем по 50 тысяч
Dim tmp ‘массив для выгрузки остатка
Dim i&, v&, c& ‘ счетчики
Dim delitel&
Dim ostatok&
If Not UBound(arArray) — LBound(arArray) + 1 0 Then
ReDim tmp(1 To ostatok + 1)
For i = c To UBound(arArray)
tmp(v) = arArray(i)
v = v + 1
Next
Cells(startRow, startColumn).Resize(UBound(tmp)) = Application.WorksheetFunction.Transpose(tmp)
End If
Else
Cells(startRow, startColumn).Resize(UBound(arArray) — LBound(arArray) + 1) = Application.WorksheetFunction.Transpose(arArray)
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
200?’200px’:»+(this.scrollHeight+5)+’px’);»> Option Base 1
Option Explicit
Sub proverka() ‘Для проверки
Dim i&
Dim x(1 To 77777)
For i = LBound(x) To UBound(x)
x(i) = i
Next
arToRange x, 1, 1
End Sub
Источник
Вывод массива
Для распечатки полученного массива на рабочий лист Excel используется следующая конструкция:
Cells(k, i) = A(i) ‘ вывод массива в ячейки электронной таблицы
Next i ‘ k – номер строки для заполнения ячеек.
Вместо переменной k можно использовать конкретное значение, например 3, тогда массив распечатается в третьей строке рабочего листа.
После заполнения ячеек их содержимое можно посмотреть, свернув окно программного кода при помощи кнопки “Свернуть” или переключившись в окно Excel с помощью соответствующей кнопки на панели задач.
В VBA удобно пользоваться различными рабочими листами в одной программе. Для установки нужного рабочего листа используется следующая команда:
Например, Worksheets(“Лист1”).Select – переход на рабочий лист с именем “Лист1”.
Пусть одномерный массив А, состоящий из десяти элементов, находится на рабочем листе “Лист1”, а массив В, состоящий из десяти элементов, находится на рабочем листе “Лист2”. Необходимо прочитать массив А с листа “Лист1” и расположить его на листе “Лист2” ниже массива В.
Dim A(10) As Integer
Dim B(10) As Integer
Dim i As Integer
Worksheets(«Лист1»).Select ‘ выбираем Лист1
A(i) = Worksheets(«Лист1»).Cells(1, i) ‘ считываем с Лист1 массив А
Worksheets(«Лист2»).Select ‘ выбираем Лист2
Worksheets(«Лист2»).Cells(2, i) = A(i) ‘ выводим на Лист2 массив А
Вычисление суммы, произведения и количества элементов в одномерном массиве
Вычисление суммы, произведения и количества элементов в одномерных массивах производится обязательно в цикле, перед которым сумма приравнивается к нулю, произведение – к единице, количество – к нулю.
Если необходимо вычислить сумму, произведение или количество элементов массива, удовлетворяющих некоторому условию, то в цикле следует записать условный оператор, в котором проверяется это условие.
Задан целочисленный массив А, состоящий из N элементов. Вычислить среднее арифметическое четных элементов и среднее геометрическое нечетных элементов.
Dim i As Integer, S As Integer
Dim K1, K2, N As Integer
Dim PR, SA, SG As Double
Dim A(50) As Integer
N = Val(InputBox(«Введите N»))
S = 0: PR = 1: K1 = 0: K2 = 0 ‘ начальные значения
A(i) = Cells(1, i) ‘ ввод массива
If A(i) mod 2 = 0 Then
S = S + A(i) ‘ вычисление суммы и
K1 = K1 + 1 ‘ количества четных элементов
If A(i) mod 2 0 Then
PR = PR * A(i) ‘ вычисление произведения и
K2 = K2 +1 ‘ количества нечетных элементов
MsgBox(«S=» & S & » K1=» & K1)
MsgBox(«PR=» & PR & » K2=» & K2)
SA = S / K1 ‘ вычисление среднего арифметического
MsgBox(«четных элементов нет»)
If K2 0 And PR>0 Then
SG = PR ^ (1 / K2) ‘ вычисление среднего геометрического
Источник
5.1 Ввод-вывод массивов
Задать значения элементам массива можно следующими способами:
с помощью арифметического оператора присваивания (см. программу предыдущего примера);
из текстового файла оператором ввода Input ;
через диалоговые окна Excel;
из ячеек активного листа рабочей книги Excel.
Ввод значений элементов массива из текстового файла организуют с использованием оператора ввода Input . При вводе (или выв о- де) массивов используются два основных способа: ввод-вывод статического массива с заранее известным числом элементов и ввод-вывод динамического массива, число элементов в котором определяется в момент выполнения программы.
Пример 5.2. Ввести и вывести в текстовый файл элементы массива вещественного типа из 10-ти элементов. Исходные данные помещаются в текстовом файле с именем «dat.txt», а в файл вывода с именем «res.txt» выводим массив по пять чисел в строке. Предполагаем, что в качестве разделителя целой и дробной части чисел в файле «dat.txt» используется символ «точка».
Dim Mas(1 To 10) As Single
Dim i As Integer
Open «dat.txt» For Input As # 1 ‘ открываем файла для ввода Open «res.txt» For Output As # 2 ‘ открываем файла для вывода
Print # 2, «Введенный массив Mas(10)»
If EOF(1) = True Then ‘ проверяем — достигли конца файла или нет ‘ конец файла достигнут, а данных меньше 10. Сообщаем об ошибке
MsgBox «В файле «»dat.txt»» всего » & i-1 & » чисел — ОШИБКА»
Exit For End If
Input # 1, Mas(i) ‘ считываем из файла очередное число
Print # 2, Mas(i), ‘ выводим число, но не заканчиваем строку вывода If Int (i/5)*5 = i Then Print # 2, Chr(13) ‘Заканчиваем вывод строки
‘ из 5-ти элементов
Close ‘ оператор Close без параметров закрывает оба открытых файла
Расположение данных в файле » dat.txt «
Расположение данных в файле » res.txt «
Введенный массив Mas(10)
изменится, если в файле
» dat.txt » данные расположить по пять чисел в строке:
Однако если в файле исходных данных будут пустые строки, то эти строки будут восприняты как нулевые значения очередных элементов. Символ «запятая» в данных воспринимается как разделитель между числами. Поэтому если задать числа с десятичной запятой между целой и дробной частью числа – будут прочитаны два целых числа. При этом оператор Print выводит дробные числа с разделителем запятая.
Если в файле «dat.txt» окажется меньше 10 чисел, то на активный лист Excel будет выведено диалоговое окно с сообщением об ошибке, а в файле «res.txt» будут напечатаны прочитанные числа. Если же в файле будет больше 10 чисел, то будут обработаны только первые 10.
Таких проблем можно избежать, если в программе использовать не статический, а динамический массив.
Пример 5.3 . Прочитать данные из файла в массив и определить количество элементов в массиве.
Dim Mas() As Single ‘объявляем динамический массив вещественного типа
Dim i As Integer ‘ рабочая переменная целого типа
Dim kol As Integer ‘ переменная для определения количества чисел в файле
Open «dat.txt» For Input As # 1 ‘ открываем файла для ввода
‘ первое чтение файла для определения количества чисел в массиве kol = 0 ‘ обнуляем переменную Kol
Do ‘ начинаем «бесконечный» цикл
If EOF(1)=True Then Exit Do ‘ достигнут конец файла — выход из цикла kol = kol + 1 ‘ подсчитываем количество прочитанных данных ReDim Preserve Mas(1 To kol) ‘ увеличиваем размер динамического
‘ массива с сохранением ранее введенной информации
Input # 1, Mas(kol) ‘ считываем из файла очередное число в массив
Close # 1 ‘ закрываем файл dat.txt
Open «res.txt» For Output As # 2 ‘ открываем файла для вывода
Print # 2, «Введенный массив содержит » & kol & » элементов»
For i = 1 To kol
Print # 2, Mas(i), ‘ выводим число, но не заканчиваем строку вывода
If Int(i / 5) * 5 = i Then Print # 2, Chr(13)
‘ Если переменная i кратна пяти – выводим в строку вывода
‘ символ «конец строки»
Close # 2 ‘ закрываем файл res.txt
При чтении файла «dat.txt» из предыдущего примера располо-
жение данных в файле « res.txt » будет следующим
Введенный массив содержит 10 элементов
Одним из способов ввода данных в программу является ввод элементов массива с использованием диалоговых окон Excel. При использовании статического массива число его элементов должно быть заранее известно. Для динамического массива в начале работы программы необходимо запросить количество элементов в массиве, а затем организовать ввод числовых данных.
Пример 5.4. Ввести одномерный массив через диалоговое окно Excel. Вывести элементы массива в первый столбец активного листа рабочей книги Excel.
‘ Ввод массива с клавиатуры
Dim A() As Single ‘ объявляем динамический массив вещественного типа
Dim N As Integer ‘ переменная для количества элементов в массиве
‘ выводим в ячейку А1 заголовок
Worksheets («Лист1») .Cells (1, 1) = «Массив А :»
N = Val(InputBox( «Введите количество элементов массива» )) ReDim A(1 To N) ‘ задаем размер массива А
A(i) = Val(InputBox( «Введите A(» & i & «)», _
«Осталось ввести » & N — i + 1 & » элемент(ов/а)» ))
Cells (i + 1, 1) = A(i)
Программа выводит в ячейку «А1» первого листа таблицы Excel заголовок «Массив А:», затем запрашивает количество элементов в массиве (рисунок 5.1). После определения количества элементов в массиве для данного сеанса работы, программа в цикле запрашивает ввод очередного числа, указывая в заголовке диалогового окна количество элементов, которое осталось ввести (рисунок 5.2). При этом пользователь видит в первом столбце таблицы Excel ранее введенные значения.
Рисунок 5.1 – Запрос на задание числа элементов в массиве
Рисунок 5.2 – Запрос на ввод очередного элемента массива
Однако наиболее удобным способом ввода данных в VBA является ввод информации непосредственно из таблицы Excel, где и хр а- нится сама программа. Обмен данными с таблицей выполняется ко-
Пример 5.5. Ввести массив данных их первого столбца активного листа рабочей книги Excel. Вывести полученные данные в текстовый файл.
Dim Mas() As Single ‘объявляем динамический массив Dim i As Integer ‘ рабочая переменная целого типа Dim kol As Integer ‘ количество чисел в файле
kol = 0 ‘ обнуляем переменную ko l
Do Until Cells(kol + 1, 1) = Empty ‘ выполняем цикл, пока есть данные kol = kol + 1 ‘ подсчитываем количество прочитанных данных ReDim Preserve Mas(1 To kol) ‘ увеличиваем размер массива
‘ с сохранением ранее введенной информации Mas(kol) = Cells(kol, 1) ‘считываем из таблицы очередное число
Open «res.txt» For Output As # 2 ‘ открываем файла для вывода
Print # 2, «Введенный массив содержит » & kol & » элементов»
For i = 1 To kol
Print # 2, Mas(i), ‘ выводим число, но не заканчиваем строку вывода
If Int( i / 5) * 5 = i Then Print # 2, Chr(13) ‘ Заканчиваем вывод
‘ строки из 5-ти элементов
If Int( kol / 5) * 5 = kol Then Print # 2, Chr(13) ‘ заканчиваем строку, ‘ если kol не кратен пяти
Close ‘ закрываем файл res.txt
Программа просматривает первый столбец активного листа таблицы Excel. В данной программе при использовании метода Cells не используется объект Worksheets («Лист1»), что позволяет обращаться к активному листу, какое бы имя у него не было. Цикл, заданный оператором Do Until , продолжается до тех пор, пока в первом столб-
Источник
Adblock
detector
I’ve written a macro that takes a 2 dimensional array, and «prints» it to equivalent cells in an excel workbook.
Is there a more elegant way to do this?
Sub PrintArray(Data, SheetName, StartRow, StartCol)
Dim Row As Integer
Dim Col As Integer
Row = StartRow
For i = LBound(Data, 1) To UBound(Data, 1)
Col = StartCol
For j = LBound(Data, 2) To UBound(Data, 2)
Sheets(SheetName).Cells(Row, Col).Value = Data(i, j)
Col = Col + 1
Next j
Row = Row + 1
Next i
End Sub
Sub Test()
Dim MyArray(1 To 3, 1 To 3)
MyArray(1, 1) = 24
MyArray(1, 2) = 21
MyArray(1, 3) = 253674
MyArray(2, 1) = "3/11/1999"
MyArray(2, 2) = 6.777777777
MyArray(2, 3) = "Test"
MyArray(3, 1) = 1345
MyArray(3, 2) = 42456
MyArray(3, 3) = 60
PrintArray MyArray, "Sheet1", 1, 1
End Sub
Return to VBA Code Examples
In this Article
- Output (Print) Array to Range
- Output Data to a Different Range
- Looping Through an Array and Outputting the data
- Transpose Array Data
- Output to Debug.Print
This tutorial will demonstrate how to output an array to a range using VBA.
Output (Print) Array to Range
Data that is stored in an array can easily be outputted into an Excel sheet. There are 3 ways to do this.
Output Data to a Different Range
We could populate an array with data from one range in Excel, and then output the data to a different range in Excel.
Public Sub TestOutput()
'declare the array
Dim rnArray() As Variant
'populate the array with the range
rnArray = Range("A1:H24")
'output the array to a different range of cells
Range("J1:Q24") = rnArray()
End Sub
The entire array is copied in one line of code to the array, and then outputted in it’s entirety to a different range of cells on the sheet.
Looping Through an Array and Outputting the data
This example will loop through an array, outputting the array to a range.
Public Sub TestLoopArray()
'declare the array
Dim rnArray() As Variant
'Declare the integer to store the number of rows
Dim iRw As Integer
'Assign range to a the array variable
rnArray = Range("A1:A10")
'loop through the values in the array
For iRw = LBound(rnArray) To UBound(rnArray)
'populate a different range with the data
Cells(iRw, 2).Value = rnArray(iRw, 1)
Next iRw
End Sub
LBound and UBound returns the Starting index (Lower Bound) and Ending index (Upper Bound) of an array, in this case 1 and 10.
Transpose Array Data
We can also transpose the data in the Array to the Excel sheet. Transpose allows you to display the data horizontally across the Excel sheet.
For example, if we have a list of states in Excel and wish to transpose them.
We could then run the following code:
Public Sub TestOutputTranspose()
'declare the array
Dim rnArray() As Variant
'populate it with the range
rnArray = Range("A1:A38")
'transpose the data
Range(Cells(1, 3), Cells(1, 40)).Value = Application.Transpose(rnArray)
End Sub
Which would result in the following:
Output to Debug.Print
We can also output the array values to the debug window.
Public Sub TestLoopArray()
'declare the array
Dim rnArray() As Variant
'Declare the integer to store the number of rows
Dim iRw As Integer
'Assign range to a the array variable
rnArray = Range("A1:A10")
'loop through the rows - 1 to 10
For iRw = 1 To UBound(rnArray)
'output to the immediate window
Debug.Print rnArray(iRw, 1)
Next iRw
End Sub
VBA Coding Made Easy
Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
Learn More!
Функция листа ИНДЕКС (INDEX):
ИНДЕКС(диапазон;строка;столбец)
Функция позволяет выбрать из диапазона значение ячейки, расположенной на пересечении указанных строки и столбца. Если не указывать строку/столбец или указать 0 (ноль), то функция создаст массив из строк/столбцов указанного столбца/строки:
=ИНДЕКС(диапазон;;12)
=ИНДЕКС(диапазон;5;0)
Функцию можно использовать в VBA для извлечения части массива:
Sub PartOfTheArray()
Dim ar(1 To 20, 1 To 5)
Dim i As Long, j As Long
For i = 1 To 20
For j = 1 To 5
ar(i, j) = i + j * 0.01
Next j
Next i
' ======= примеры выгрузки части массива ======= '
Cells(1, 1).Resize(20, 1).Value = ar ' столбец 1 '
Cells(1, 2).Resize(20, 1).Value = WorksheetFunction.Index(ar, 0, 2) ' столбец 2 '
Cells(1, 3).Resize(10, 1).Value = WorksheetFunction.Index(ar, 0, 4) ' неполный столбец 4 '
Cells(1, 4).Resize(1, 5).Value = ar ' строка 1 '
Cells(2, 4).Resize(1, 5).Value = WorksheetFunction.Index(ar, 7, 0) ' строка 7 '
Cells(3, 4).Resize(1, 3).Value = WorksheetFunction.Index(ar, 9, 0) ' неполная строка 9 '
End Sub