Vba excel выгрузка массива на лист

Функция 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

Оптимальный путь вывода большого одномерного массива на лист

SkyPro

Дата: Пятница, 08.11.2013, 02:22 |
Сообщение № 1

Группа: Друзья

Ранг: Старожил

Сообщений: 1206


Репутация:

255

±

Замечаний:
0% ±


2010

Придумал такой алгоритм:

Процедура выводит одномерный массив на лист через функцию листа Transpose.
Подскажите, пожалуйста, как можно этот код улучшить и оптимизировать?
Или есть более быстрые варианты?
ЗЫ: Планируется выгружать около 1 млн. значений.


skypro1111@gmail.com

Сообщение отредактировал SkyProПятница, 08.11.2013, 02:31

 

Ответить

RAN

Дата: Пятница, 08.11.2013, 02:54 |
Сообщение № 2

Группа: Друзья

Ранг: Экселист

Сообщений: 5645

Хитрый ты наш. Cам себя перехитрил.
[vba]

Код

ReDim tmp(1 To UBound(arArray), 1 to 1)
         For i = 1To UBound(arArray)
             tmp(i, 1) = arArray(i)
         Next

[/vba]
И никаких Transpose.


Быть или не быть, вот в чем загвоздка!

 

Ответить

PowerBoy

Дата: Пятница, 08.11.2013, 06:20 |
Сообщение № 3

Группа: Проверенные

Ранг: Участник

Сообщений: 100


Репутация:

31

±

Замечаний:
0% ±


2003

Миллионы записей надо выводить запросами.


Excel + SQL = ActiveTables (http://vk.com/ExcelSQL)

 

Ответить

MCH

Дата: Пятница, 08.11.2013, 08:39 |
Сообщение № 4

Группа: Админы

Ранг: Старожил

Сообщений: 2002


Репутация:

751

±

Замечаний:
±


т.к. исходный массив arArray() и массив ar() объявлены как Variant,
то выводить можно сразу квадратом, с учетом пустых значений в конце массива ar(), ячейки будут пустыми:

[vba]

Код

Option Explicit

Sub proverka()
Dim i&
Dim x(1 To 777777)
For i = LBound(x) To UBound(x)
     x(i) = i
Next
arToRange x, 1, 1
End Sub

Public Sub arToRange(ByVal arArray, startRow&, startColumn&)
     Application.ScreenUpdating = False
     Application.Calculation = xlCalculationManual

           Dim maxRow&, maxCol&, i&, j&, k&
     maxRow = 50000
     ‘maxRow = Rows.Count — startRow + 1
     maxCol = (UBound(arArray) — LBound(arArray)) maxRow + 1
     ReDim ar(1 To maxRow, 1 To maxCol)
     j = 1
     For k = LBound(arArray) To UBound(arArray)
         i = i + 1
         If i > maxRow Then i = 1: j = j + 1
         ar(i, j) = arArray(k)
     Next k

     Cells(startRow, startColumn).Resize(maxRow, maxCol) = ar

           Application.ScreenUpdating = True
     Application.Calculation = xlCalculationAutomatic
End Sub

[/vba]

Сообщение отредактировал MCHПятница, 08.11.2013, 08:42

 

Ответить

RAN

Дата: Пятница, 08.11.2013, 09:00 |
Сообщение № 5

Группа: Друзья

Ранг: Экселист

Сообщений: 5645

Насколько я понял — нужен 1 столбец. Так что два цикла, вкупе с Transpose, большаяяя хитрость.


Быть или не быть, вот в чем загвоздка!

 

Ответить

MCH

Дата: Пятница, 08.11.2013, 09:17 |
Сообщение № 6

Группа: Админы

Ранг: Старожил

Сообщений: 2002


Репутация:

751

±

Замечаний:
±


Насколько я понял — нужен 1 столбец. Так что два цикла, вкупе с Transpose, большаяяя хитрость.

А я даже не обратил на это внимание, думал нужно по столбцам раскидать, макрос ведь не запускал :(
а так, нужно переложить из одномерного массива в двухмерный и выложить целиком на лист,

но в моем варианте есть небольшое плюс, можно массивы более миллиона записей выкладывать, раскидывая их по столбцам

 

Ответить

SkyPro

Дата: Пятница, 08.11.2013, 11:07 |
Сообщение № 7

Группа: Друзья

Ранг: Старожил

Сообщений: 1206


Репутация:

255

±

Замечаний:
0% ±


2010

Да. Выводить нужно в столбец.
Андрей, никак не пойму, как с твоим способом обойтись без транспоза?
Александр, чуток уточнить направление поиска «выводить запросами»? Насколько я понял, вы имели ввиду SQL ?


skypro1111@gmail.com

Сообщение отредактировал SkyProПятница, 08.11.2013, 11:09

 

Ответить

SkyPro

Дата: Пятница, 08.11.2013, 11:19 |
Сообщение № 8

Группа: Друзья

Ранг: Старожил

Сообщений: 1206


Репутация:

255

±

Замечаний:
0% ±


2010

«дурная голова рукам покоя не дает»
Я думал, что массив на лист вывести можно либо циклом по ячейкам (что ооооочень долго), либо транспозом (что быстро).
Вот и выбрал быстрый вариант и голову себе вчера ломал.
А всего-то нужно было сделать из одномерного массива двумерный =
Андрей, Михаил, спасибо вам, что просветили :)


skypro1111@gmail.com

Сообщение отредактировал SkyProПятница, 08.11.2013, 11:22

 

Ответить

PowerBoy

Дата: Пятница, 08.11.2013, 12:33 |
Сообщение № 9

Группа: Проверенные

Ранг: Участник

Сообщений: 100


Репутация:

31

±

Замечаний:
0% ±


2003

Александр, чуток уточнить направление поиска «выводить запросами»? Насколько я понял, вы имели ввиду SQL ?

Я так понимаю чтобы вывести быстро миллион записей, их еще надо быстро прочитать.
Оптимально конечно с помощью SQL, ADO.

Если лень писать макрос, можно воспользоваться моей надстройкой «Активные таблицы»:
http://www.excelworld.ru/forum/3-5665-68943-16-1383896892


Excel + SQL = ActiveTables (http://vk.com/ExcelSQL)

 

Ответить

SkyPro

Дата: Пятница, 08.11.2013, 13:15 |
Сообщение № 10

Группа: Друзья

Ранг: Старожил

Сообщений: 1206


Репутация:

255

±

Замечаний:
0% ±


2010

Спасибо.
В моем случае массив фомируется, а не считывается. Так что вывод проще организовать «обычным» способом.
А вашу надстройку, при возможности, обязательно попробую :)


skypro1111@gmail.com

 

Ответить

RAN

Дата: Пятница, 08.11.2013, 16:12 |
Сообщение № 11

Группа: Друзья

Ранг: Экселист

Сообщений: 5645

Надо было вчера еще строчку кода добавить. Но не подозревал, что проблема в этом.


Быть или не быть, вот в чем загвоздка!

 

Ответить

 

Добрый день. Ищу человека который будет обучать меня программированию на vba in excel    
На условиях взаимообучения  
О себе Я близок к MCTS по SQL SERVER BI. Собственно и в Excel я не новичок. Но хотелось бы это обучение реализовать побыстрее. В целом по excel уверенный пользователь, но не такой конечно как на этом форуме, но цели пока такой и нет. Хотя бывает конечно если есть желание я захожу сюда и решаю какую-нибудь задачу.    

  Что я знаю о vba.  

  Знаю объектную модель Application, workbook, sheet, cell  
Знаю что такое переменные и как их объявлять dim i,j as variant    
Знаю чем метод отличается от свойства и области видимости  
Общее понимание циклов.    
Могу написать Msgbox «Hello world»  
В чем проблема/ зачем я все это пишу. Мне надоело читать книги по vba. Мне нужен толковый человек который мне на примерах объяснит что такое массивы и как с ними бороться и научить делать более менее сложную логику на vba  
В основном проблема с массивами. Требуется около 10 часов практических занятий, то есть по аське или как то так.    

  Что я могу научить    
Информационная поддержка  
Установка SQL server c ноля  
Насторойка тестовых баз их описание  
Общие знания T-sql, хорошие знания sql 92 стандарта реально научу языку запросов sql, научу выбирать данные из одной и более таблиц  
Научу разбираться в джойнах, отличать левый от внутреннего  
Преобразования агрегация, типы. И много другого.    
Вставлять данные, удалять    
Проектирование БД общие вопросы  
Службы SSAS научу сделать куб  
SSRS научу развернуть службу построить отчет, параметры, оформление  
SSIS научу строить интеграционные пакеты. Расскажу о том как их делать.    

  Кому это интересно обращайтесь на почту dmitriy8308@mail.ru

 

если честно, лучшая школа это:  
1) делать какое-либо задание для себя (по работе или учёбе)  
2) задавать вопросы на форуме и читать форум каждый день  

  Я прочитал по Excel и VBA книг 20, но все прочитанные знания быстро забываются, если их не применять на практике. Я отдал все свои книги и перешёл на форум, читая ответы на вопросы других людей и пытаясь помочь другим людям быстрее осваиваешь материал и учишься.  

  Перейдём к массивам, вот 3 примера работы с массивами  

  Sub TestArray()  
   Dim iArray()  ‘объявляем массив  
   ReDim iArray(1 To 5) ‘указываем размерность массива (5 элементов: от 1 до 5)  

         ‘ВАРИАНТ 1  
   ‘заполняем массив по-индексно названиями месяцев  
   iArray(1) = «Январь»  
   iArray(2) = «Февраль»  
   iArray(3) = «Март»  
   iArray(4) = «Апрель»  
   iArray(5) = «Май»  
   ‘MsgBox «3-й элемент массива равен: » & iArray(3)  

         Dim i As Long ‘объявляем переменную типа Long (целое число)  
   For i = LBound(iArray) To UBound(iArray) ‘цикл от нижней границе массива до верхней границе массива  
       MsgBox i & «-й элемент массива равен: » & iArray(i)  
   Next i  

         ‘ВАРИАНТ 2  
   ‘массив можно заполнить циклом  
   For i = LBound(iArray) To UBound(iArray) ‘цикл от нижней границе массива до верхней границе массива  
       iArray(i) = i ‘каждому индексу массива присваиваем его номер  
   Next i  
   MsgBox «4-й элемент массива равен: » & iArray(4)  

         ‘ВАРИАНТ 3  
   ‘давайте умножим каждый элемент массива на 3  
   For i = LBound(iArray) To UBound(iArray) ‘цикл от нижней границе массива до верхней границе массива  
       iArray(i) = iArray(i) * 3 ‘каждой элемент массива умнажаем на 3  
   Next i  
   MsgBox «5-й элемент массива равен: » & iArray(5)  
End Sub  

    Скопируйте этот код в редактор VBA (только копировать в РУССКОЙ РАСКЛАДКЕ КЛАВИАТУРЫ) и запустите его через F8 (пошаговый режим) и нажимайте F8 до конца макроса, вы увидите как работает код, а комментарии вам помогут понять смысл массивов.    

  Если что-то будет не понятно, спрашивайте  

  Павел

 

Теперь давайте попробуем применить массивы к данным на листе Excel  

    Sub TestArray2()  
   Dim iArray()  ‘объявляем массив. Размерность массива ниже в коде не указываем.  
   Dim i As Long  

         ‘заполняем диапазон А1:А5 названиями месяцев  
   Range(«A1») = «Январь»  
   Range(«A2») = «Февраль»  
   Range(«A3») = «Март»  
   Range(«A4») = «Апрель»  
   Range(«A5») = «Май»  

     ‘переносим данные из диапазона А1:А5 в массив  
   iArray = Range(«A1:A5»).Value  
   ‘теперь наш массив iArray имеет размерность (1 to 5, 1) — 5 строк и 1 столбец. т.е. он у нас ДВУМЕРНЫЙ  
   ‘давайте циклом посмотрим содержимое массива  
   For i = LBound(iArray) To UBound(iArray) ‘цикл от нижней границе массива до верхней границы массива  
       MsgBox i & «-й элемент массива равен: » & iArray(i, 1) ‘i — строка, 1 — это столбец  
   Next i  
   ‘а теперь давайте выгрузим обратно наш массив на лист в столбец С  
   ‘мы расширяем диапазон от ячейки С1 вниз на количество строк массива (5) и на 1 столбец  
   ‘логика — Ячейка(С1).РасширитьДиапазон(кол-во строк, кол-во столбцов) = наш_массив  
   Range(«C1»).Resize(UBound(iArray, 1), UBound(iArray, 2)) = iArray  
End Sub  

    Так же скопируйте в русской раскладке код в VBE и запустите пошагово через F8.  
Что не понятно — спрашивайте  

    Павел

 

Если для понимания нужно определение массива, то массив можно описать так:  

  Массив — это именованный набор однотипных переменных, расположенных в памяти непосредственно друг за другом, доступ к которым осуществляется по индексу.  

  Массивы бывают Одномерные, Двумерные и т.д.  

  Двумерный массив — это как ячейки на листе Excel. Т.е. есть строки и есть столбцы.  

  Если к Одномерному массиву можно обратиться так:    

  переменная = Массив(5)    

  То к Двумерному массиву нужно обращаться указывая и первый и второй индекс, например:  

  Переменная = массив(5,3)  

  Вот ещё один пример заполнения ОДНОМЕРНОГО массива  

    Sub Test3()  
   Dim iArray()  
   ‘заполнять массив можно так же через функцию Array  
   ‘нужно учесть, что первый индекс будет начинаться с 0, а не с 1  
   iArray = Array(«Январь», «Февраль», «Март», «Апрель», «Май»)  
   MsgBox «1-й элемент массива: » & iArray(1) & vbLf & «т.к. 0 элемент массива Январь», , «»  
End Sub  

    Павел

 

Определение границ массива, на примере одномерного массива  

  Sub TestArray4()  
   Dim iArray() ‘объявляем динамический массив  

     ‘заполняем массив названиями месяцев  
   iArray = Array(«Январь», «Февраль», «Март», «Апрель», «Май»)  

     ‘определяем нижнюю и верхнюю границу массива  
   MsgBox «Массив содержит 5 элементов» & vbLf & _  
   «Нижняя граница массива равно индексу: » & LBound(iArray) & vbLf & _  
       «Верхняя граница массива равно индексу: » & UBound(iArray)  
End Sub  

    Чтобы узнать границы, например, двумерного массива нужно писать так  

  LBound(iArray,2)  

  UBound(iArray,2)  

    Павел

 

Давайте теперь рассмотрим пример работы с ДВУМЕРНЫМ массивом  

  Sub TestArray5()  

         Dim iArray(1 To 5, 1 To 3) ‘объявляем двумерных массив с размерностью 1 To 5, 1 To 3  
   Dim i As Long, n As Long ‘2 числовые переменные для работы с циклами  

         For i = LBound(iArray, 1) To UBound(iArray, 1) ‘т.е. от 1 до 5  
       For n = LBound(iArray, 2) To UBound(iArray, 2) ‘т.е. от 1 до 3  
           iArray(i, n) = i * n  
       Next n  
   Next i  

         ‘сейчас у нас массив такой  
   ‘iArray(1,1)  
   ‘iArray(1,2)  
   ‘iArray(1,3)  
   ‘iArray(2,1)  
   ‘iArray(2,2)  
   ‘iArray(2,3)  
   ‘..  
   ‘..  
   ‘iArray(5,1)  
   ‘iArray(5,2)  
   ‘iArray(5,3)  

         MsgBox «Верхний индекс ПЕРВОЙ размерости массива равен: » & UBound(iArray, 1) & vbLf & _  
       «Верхний индекс ВТОРОЙ размерости массива равен: » & UBound(iArray, 2) & vbLf & _  
       «Значение индекса 5,2 равен: » & iArray(5, 2)  

          End Sub  

    Так же скопируйте в русской раскладке клавиатуры код в редактор VBA и пожагово через F8 пройдитесь по коду  

    Павел

 

Все примеры, приведённые в этой теме я поместил в файл Excel, чтобы вам было удобнее тестировать код. См. файл  

  P.S. Код можно посмотреть нажав Alt+F11  

  Павел

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

Студент++, здесь знаниями не отделаетесь, бутылкой тоже (не пьет). Готовьте большущую шоколадку :)

 

{quote}{login=Ластик}{date=22.01.2012 05:36}{thema=}{post}Все примеры, приведённые в этой теме я поместил в файл Excel, чтобы вам было удобнее тестировать код. {/post}{/quote}  
ОК. Спасибо Павел. Если что то нужно по тому (SQL BI) из того что я написал пишите мне на почту. Буду разбирать ваши примеры

 

{quote}{login=vikttur}{date=22.01.2012 06:01}{thema=}{post}Студент++, здесь знаниями не отделаетесь, бутылкой тоже (не пьет). Готовьте большущую шоколадку :){/post}{/quote}  

  Это да

 

nerv

Пользователь

Сообщений: 3071
Регистрация: 22.12.2012

Студент++, можете мне на почту написать. В теле письма:  

  1. Чему именно хотите научиться.  
2. Что уже знаете (если знаете).  
3. Знакомы ли Вы с синтаксисом vb?  
4. Для чего это Вам нужно?  
5. Изучали ли Вы и практиковались в других языках программирования?  

    p.s.: я, конечно, не супер-профессионал, но тем не менее, могу кое-чему научить.

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

Я помнится тоже не сразу массивы понял, пару раз на форуме спрашивал разъяснения. Resize тоже непонятная штука была :)  
Одно небольшое замечание по «Массив — это именованный набор однотипных переменных».  
Если массив типа Variant — т.е. как всюду в примерах, без явного указания типа массива, то в массиве могут храниться и числа, и даты, и строки. Т.е. что есть на листе — то и будет в массиве.  
С датами интересно —    
в ячейке значение 40909  
форматом выводит как 01.янв,  
а в массиве      
: a(1,1) : #01.01.2012# : Variant/Date  

  Содержимое массивов удобно смотреть в окне Locals — сразу всё понятно, что где.

 

угу, но я не стал писать об этом, чтобы на начальном этапе не запутывать.    
А определение взял из Wikipedia  

<EM>http://ru.wikipedia.org/wiki/%C8%ED%E4%E5%EA%F1%ED%FB%E9_%EC%E0%F1%F1%E8%E2</EM>

 

VDM

Пользователь

Сообщений: 779
Регистрация: 22.12.2012

У меня вот ещё какой вопросы есть по массивам:  

  Если двумерный массив мы можем рассматривать как аналог рабочего лиса Excel, то:  
1. Можно ли в самом массиве оперировать с «Resize»  
2. Можно ли оперировать целой строкой или столбцом массива, аналог EntireColumn, EntireRow  
как работая с самим массивом, так и заполняя и выгружая с рабочего листа?

 

Ого какая хорошая тема:) я и сам с удовольствием почитал так как с массивами тоже толком еще не умею обращаться:) но насколько я понимаю — строка массива — это цикл с фиксированным номером строки и переменной номера столбца?

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

VDM, 2 —  это к слэну, он спец по CopyMemory, я это понять не могу :)  
Вот его пример кода:  

    но можно еще быстрее — цикл copymemory по столбцам  

  Declare Sub CopyMemory Lib «kernel32» Alias «RtlMoveMemory» (Destination As Any, Source As Any, ByVal Length As Long)  
Sub arrdel_str_copymem()  
arr = Range(«A1:B5»).Value  
Dim delStr&, j&, mr&  
delStr = 3: mr = UBound(arr)  
For j = 1 To UBound(arr, 2)  
CopyMemory arr(delStr, j), arr(delStr + 1, j), 16 * (mr — delStr)  
arr(mr, j) = Empty  
Next  
End Sub

 

R Dmitry

Пользователь

Сообщений: 3103
Регистрация: 22.12.2012

Excel,MSSQL,Oracle,Qlik

#17

22.01.2012 23:56:29

{quote}{login=VDM}{date=22.01.2012 11:26}{thema=}{post}1. Можно ли в самом массиве оперировать с «Resize»  
2. Можно ли оперировать целой строкой или столбцом массива, аналог EntireColumn, EntireRow  
как работая с самим массивом, так и заполняя и выгружая с рабочего листа?{/post}{/quote}  
1-нет (можно увеличить последнюю размерность массива с помощью Redim Preserve)  
2-не понял чего хотите сотворить со строкой? с помощью функции index можно вытащить из двухмерного массива строку или столбец, и выгрузить их на лист или еще как нибудь приспособить :)

Спасибо

 

VDM,  

  к сожалению, нельзя.    

  Свойства Resize, EntireRow, EntireColumn — относятся только к ячейкам листа Excel.  

  Как бы аналог Resize для массива это    

  Redim массив(новая размерность)  

  т.е. можно объявить массив, например, из 5 элементов  

  Dim myArray (1 to 5)    

  а потом его переопределить    

  Redim myArrray (1 to 10)    

  но при Redim — массив полностью очищается  

  Чтобы он не очищался используют конструкцию ReDim Preserve  

  ReDim Preserve массив (новая верхняя граница)  

  Вот пример.    
1) Сперва мы создаём пустой динамический массив — в данном случае это не обязательно, т.к. Redim тоже создаёт массив  
2) через Redim определяем границы массива от 1 до 10 элементов  
3) заполняем массив данными  
4) увеличиваем верхнюю границу массива до 15 элементов  

  Sub TestArary6()  
Dim myArray() ‘объявляем динамический массив  
Dim i As Long  

     ReDim myArray(1 To 10)     ‘переопределяем размер массива (от 0 до 10 элементов)  
   For i = 1 To 10    ‘ цикл 10 раз  
       myArray(i) = i + 7  ‘ заполняем массив числами от 1 до 10  
   Next i  
   MsgBox «Значение 10-его элемента массива равно: » & myArray(10)  

             ReDim Preserve myArray(1 To 15)     ‘расширяем массив до 15 элементов с сохранением значений массива  
   MsgBox «Значение 10-его элемента массива равно: » & myArray(10) & vbLf & _  
       «Значение 12-его элемента массива равно: (пусто) » & myArray(12)  

  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  

  ‘ так сработает  
Redim myArray (1 to 10, 1 to 3)  
ReDim Preserve myArray (1 to 10, 1 to 7)  

  ‘а так нет  
Redim myArray (1 to 10, 1 to 3)  
ReDim Preserve myArray (1 to 15, 1 to 3)  

    P.S. Пример с листом Excel это так для «умственного» восприятия. Так же можно выразиться, что двумерный массивы — это матрица. Но мне кажется, что это сложнее понять.  

    Павел

 

VDM

Пользователь

Сообщений: 779
Регистрация: 22.12.2012

УУУ, как всё сложно:)  

  Правильно ли я понимаю, что той гибкости в работе с диапазонами как на рабочем листе массивы нам не представляют, и обращение к диапазону будет далеко не таким же прозрачным?  
Тогда оставлю эту затею пока, боюсь разбросаюсь.  
А жаль, сейчас данные с листа в массив забираю перебором (пользуясь полученными знаниями в той теме, где Вы с Nerv-ом мне очень помогли), но иногда нужно перебрать строки целиком и перебор выглядит как то не очень рационально.

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

Тему прошел «по диагонали», может, это упоминалось раньше.  
Небольшое предостережение, недавно сам из-за неопытности напоролся.  
Массив, заданный как M(a To b) формирует массив строки, но не столбца. Если задать M(a To b;1), тогда a To b — строки.  

  Еще момент, на котором время тратил, пытаясь разобраться, почему  созданный массив на лист  выгружается на столбец правее:  
M(a;1) — это не первый столбец, второй. Первый «0» (Option Base не объявлен).  

  Простые вещи, но новички ошибаются.

 

VDM

Пользователь

Сообщений: 779
Регистрация: 22.12.2012

Пока отвечал HUGO, получил ещё 2 ответа:)  

  Во общем решил, что не буду впереди паровоза бежать, понял что всё это сложновато пока для восприятия.  

  Все спасибо за разъяснения.

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

VDM, на самом деле с массивом работать проще, чем с листом.  
И за счёт скорости работы с массивом — при нужде его переопределить можно просто создав новый массив нужного размера и переложить данные в него.  
Но конечно если это делать часто в цикле — это очень не оптимально.  
По правде, у меня не было такой нужды — переопределять многомерные массивы. Всегда иначе можно выкрутиться.  
Но если бы можно было «удлинять» массив вниз — это было бы очень неплохо :)

 

R Dmitry

Пользователь

Сообщений: 3103
Регистрация: 22.12.2012

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()  
   Dim myArr(), i As Long, n As Long  

         ‘допустим есть какие-то данные на листе  
   Range(«A1:D1») = Array(«1», «2», «3», «4»)  
   Range(«A2:D2») = Array(«5», «6», «7», «8»)  
   Range(«A3:D3») = Array(«9», «10», «11», «12»)  

         ‘берём их в массив (массив получается двумерным)  
   myArr() = Range(«A1:D3»).Value  

         ‘в цикле умножаем каждое значение столбца на 2  
   For n = 1 To UBound(myArr, 1) ‘цикл по строкам  
       For i = 1 To UBound(myArr, 2)  ‘цикл по столбцам  
           myArr(n, i) = myArr(n, i) * 2  
       Next i  
   Next n  

         ‘выгружаем наши новые данные обратно на лист  
   Range(«F1»).Resize(UBound(myArr, 1), UBound(myArr, 2)) = myArr  
End Sub  

  Данный метод — намного быстрее, чем обрабатывать каждую ячейку на листе.  

  Т.е. мы сперва берём данные с листа Excel в массив, обрабатываем их и обратно выгружаем на лист. Это быстрее, чем обращение к ячейкам листа

 

R Dmitry

Пользователь

Сообщений: 3103
Регистрация: 22.12.2012

Excel,MSSQL,Oracle,Qlik

#25

23.01.2012 00:32:19

Паш есть способ чуть проще :) для данного примера, но ты прав на все сто%%%%%%%  
[a1:d1] = [a1:d1* 2]

Спасибо

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

Вот нашёл пример кода (не записал, где применял) — тут нужно было удалить строки с значениями, присутствующими на другом листе (по первым столбцам):  

  Sub tt()  
   Dim tm: tm = Timer  
   Dim r As Range, a(), b(), i&  
   Application.ScreenUpdating = 0  

     Set r = Range([a1], [a65536].End(xlUp))
   a = r.Value  

     With Sheets(«что искать»)  
       b = .Range(.[a1], .[a65536].End(xlUp)).Value
   End With  

     With CreateObject(«Scripting.Dictionary»)  
       .CompareMode = 1  
       For i = 1 To UBound(b)  
           .Item(b(i, 1)) = 1  
       Next  

         For i = 1 To UBound(a)  
           If .exists(a(i, 1)) Then a(i, 1) = «d»  
       Next  

         r.Value = a  
       r.SpecialCells(xlCellTypeConstants, 2).EntireRow.Delete  

     End With  
   Debug.Print Timer — tm  
End Sub  

  Кода мало, работает почти моментально.  

  Это были только числа, т.е. в удаляемые строки пишем текст, потом эти строки удаляем.

 

VDM

Пользователь

Сообщений: 779
Регистрация: 22.12.2012

Нет, Вы меня не так поняли — я не собираюсь отказываться от массивов).  
У меня уже сейчас вся отчётность на них построена.  
Просто не буду пытаться применить то, чего не знаю.    
Будем учиться постепенно.  

  55557

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

{quote}{login=Hugo}{date=22.01.2012 02:59}{thema=}{post}Если массив типа Variant — т.е. как всюду в примерах, без явного указания типа массива, то в массиве могут храниться и числа, и даты, и строки. Т.е. что есть на листе — то и будет в массиве.{/post}{/quote}  
это никаким образом не нарушает формулировку — в этом случае все элементы будут однотипно типа вариант :)

 

nerv

Пользователь

Сообщений: 3071
Регистрация: 22.12.2012

{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}  
Чего? О_о Нет вообще таких понятий как «массив строки» или «массив столбца». Существуют одномерные, многомерные и массивы массивов. Также массивы подразделяются на статические и динамические. Директива Option Base [Число] переопределяет нижнюю границу массива. По умолчанию нижней границей массива считается 0.

  это M(1 To 1) — одномерный массив  
это M(1 To 1, 1 To 1) — двумерный массив  

  Поскольку таблица excel представлена двумя измерениями, на лист можно выгрузить (через resize) только двумерный массив (насколько мне известно).

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

#30

23.01.2012 13:53:15

Чего? :)  

  Sub tt()  
Dim arr  
arr = Array(1, 2, 3)  
[a1].Resize(, UBound(arr) + 1) = arr
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

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.

vba array transpose 1

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:

vba array transpose 2

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!
vba save as

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

Понравилась статья? Поделить с друзьями:
  • Vba excel вывод сообщения да нет
  • Vba excel вывод массивы
  • Vba excel вывод значения в ячейку
  • Vba excel вывод данных на лист
  • Vba excel вывести список листов