Всем добрый вечер.
Собственно, проблема вот в чем, пользователь вводит количество столбцов и строк массива, после чего сам же вводит значения
Как сделать так, чтобы это выводилось на лист excela?
Visual Basic | ||
|
Заранее благодарю за помощь
Добавлено через 15 минут
Visual Basic | ||
|
Вроде бы добавил это после next i, выводит на лист, но проблема теперь в другом, почему при вводе первых трех значений — например ввожу подряд 1-2-3-4 с матрицей 2х2, он выдает на лист 0 0 0 и 4-ый элемент 1, не понимаю, к сожалению
Функция 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
Добрый день. Ищу человека который будет обучать меня программированию на 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 Пользователь Сообщений: 23252 |
Я помнится тоже не сразу массивы понял, пару раз на форуме спрашивал разъяснения. 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 Пользователь Сообщений: 23252 |
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 Пользователь Сообщений: 23252 |
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 Пользователь Сообщений: 23252 |
Вот нашёл пример кода (не записал, где применял) — тут нужно было удалить строки с значениями, присутствующими на другом листе (по первым столбцам): 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 Пользователь Сообщений: 23252 |
#30 23.01.2012 13:53:15 Чего? Sub tt() |
Василий, в VBA используются в основном два вида массивов (есть ещё трёхмерный и т.д.):
- одномерный;
- двумерный.
Одномерный массив можно мысленно представить как обычную таблицу, состоящую из одной строки.
Двумерный массив можно представить как обычную таблицу, состоящую из строк и столбцов.
Vba-функция «Array» создаёт одномерный массив. Когда вы его помещаете в Excel, то он и занимает соответствующие ячейки.
Чтобы вставить массив в несколько строк, нужно создать двумерный массив. Для этого можно использовать разные способы. Ниже используется эксель-функция «Transpose». В результате её использования будет создан двумерный массив, представляющий собой таблицу, состоящую из одного столбца и несколько строк. Функция «Transpose» меняет местами строки и столбцы.
Sub TABL()
Cells(1, 1).Resize(1, 7) = Array(«ФИО», «КД», «ТИП», «ПОД», «ОСЗ», «%%», «ПЕНИ»)
Cells(2, 1).Resize(5, 1) = WorksheetFunction.Transpose(Array(«Иванов», «Петров», «Сидоров», «Козлов», «Конев»))
End Sub
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