Как из двумерного массива сделать одномерный excel
Сохранение одномерного массива в текстовый файл с добавлением разделителя между его элементами.
Объявляем переменную универсального типа, создаем из нее массив, заполнив ее данными с помощью функции Array:
Теперь создаем текстовый файл с помощью метода CreateTextFile. Создаем, а не открываем, для того, чтобы, если такой файл с данными уже существует, от был перезаписан новым пустым файлом.
Если переменную, предназначенную для создания нового объекта TextStream объявить явно: fl As TextStream , то станут доступны подсказки для автозаполнения свойств и методов этого объекта при написании кода.
Сохраняем информацию из массива в текстовый файл с помощью цикла For… Next:
В качестве разделителя элементов массива используется символ «;». Если точка с запятой встречается в содержимом элементов массива, следует использовать другой разделитель.
Закрываем объект TextStream и открываем созданный текстовый файл для просмотра:
Полный код процедуры VBA Excel для сохранения одномерного массива в текстовый файл:
Сохранение двумерного массива
Сохранение двумерного массива в текстовый файл с использованием в качестве разделителей точки с запятой (для элементов в одной строке) и переноса строки.
Раз у нас VBA Excel, то и заполнять двумерный массив будем данными с рабочего листа:
В результате будет создан массив с размерностью (1 to 8, 1 to 4) . Первое измерение массива соответствует строкам диапазона, в второе – столбцам.
Создаем текстовый файл (или перезаписываем существующий) и открываем связанный с ним объект TextStream для записи данных из массива:
Записываем данные из двумерного массива в текстовый файл:
Закрываем объект TextStream и открываем созданный текстовый файл для просмотра:
Полный код процедуры VBA Excel для сохранения двумерного массива в текстовый файл:
Заполнение массива из текстового файла
Заполнение одномерного массива
Обратное заполнение с помощью кода VBA Excel одномерного массива данными из созданного текстового файла "C:\test\testfile1.txt" :
Заполнение двумерного массива
Обратное заполнение с помощью кода VBA Excel двумерного массива из созданного текстового файла "C:\test\testfile2.txt" .
Копируем информацию из текстового файла в переменную myString1:
Что мы теперь имеем? Все данные из файла "C:\test\testfile2.txt" скопированы в переменную myString1 с исходной структурой: со знаком переноса строки в качестве разделителя строк и точкой с запятой в качестве разделителя столбцов. Этой информацией мы и воспользуемся для заполнения массива myArray() .
__b1 b2 b3 b4 b5 .. bn
а1
а2
а3
а4
..
ak
надо привести к виду:
a1 |b1|Значение
a1 |b2|Значение
..
a1 |bn|Значение
a2 |b1|Значение
a2 |b2|Значение
..
a2 |bn|Значение
..
ak |b1|Значение
ak |b2|Значение
..
ak |bn|Значение
Так, как я делаю сейчас, получается долго и на больших объемах очень трудоемко.
Как делаю: всем непустым ячейкам присваиваю соответствующее a и b и само значение, через 2 разделителя (; и пробел на конце) потом сцепляю все непустые в одну строку и потом, транспонируя, разбиваю. Это долго
Все подробности - в образце.
Подскажите, пожалуйста, способ попроще.
__b1 b2 b3 b4 b5 .. bn
а1
а2
а3
а4
..
ak
надо привести к виду:
a1 |b1|Значение
a1 |b2|Значение
..
a1 |bn|Значение
a2 |b1|Значение
a2 |b2|Значение
..
a2 |bn|Значение
..
ak |b1|Значение
ak |b2|Значение
..
ak |bn|Значение
Так, как я делаю сейчас, получается долго и на больших объемах очень трудоемко.
Как делаю: всем непустым ячейкам присваиваю соответствующее a и b и само значение, через 2 разделителя (; и пробел на конце) потом сцепляю все непустые в одну строку и потом, транспонируя, разбиваю. Это долго
Все подробности - в образце.
Подскажите, пожалуйста, способ попроще. OlgaY
__b1 b2 b3 b4 b5 .. bn
а1
а2
а3
а4
..
ak
надо привести к виду:
a1 |b1|Значение
a1 |b2|Значение
..
a1 |bn|Значение
a2 |b1|Значение
a2 |b2|Значение
..
a2 |bn|Значение
..
ak |b1|Значение
ak |b2|Значение
..
ak |bn|Значение
Так, как я делаю сейчас, получается долго и на больших объемах очень трудоемко.
Как делаю: всем непустым ячейкам присваиваю соответствующее a и b и само значение, через 2 разделителя (; и пробел на конце) потом сцепляю все непустые в одну строку и потом, транспонируя, разбиваю. Это долго
Все подробности - в образце.
Подскажите, пожалуйста, способ попроще. Автор - OlgaY
Дата добавления - 19.06.2013 в 15:28
Добрый вечер. Появилась необходимость перевести данные из одномерного массива в двумерный, функцией =счётслимн() считает слишком долго. Видел что делают с помощью vba, но так и не смог разобраться в этом. Если кто то может помочь буду очень благодарен. На лист1 одномерный массив с данными(фамилия, дата и №Трассы) необходимо в Лист2 начиная с ячейки L3 посчитать количество повторений №Трассы у каждой фамилии отдельно, притом если дата последней записи для данной фамилии более 14 дней, то эти данные не вставлять т.е. =""
Добрый вечер. Появилась необходимость перевести данные из одномерного массива в двумерный, функцией =счётслимн() считает слишком долго. Видел что делают с помощью vba, но так и не смог разобраться в этом. Если кто то может помочь буду очень благодарен. На лист1 одномерный массив с данными(фамилия, дата и №Трассы) необходимо в Лист2 начиная с ячейки L3 посчитать количество повторений №Трассы у каждой фамилии отдельно, притом если дата последней записи для данной фамилии более 14 дней, то эти данные не вставлять т.е. ="" Anton85
Sub macro()
Dim sh1 As Worksheet, sh2 As Worksheet, fio()
Dim lr1&, lr2&, data, i&, dic As Object
Set sh1 = ThisWorkbook.Sheets("Лист1")
Set sh2 = ThisWorkbook.Sheets("Лист2")
With sh1
lr1 = .Cells(Rows.Count, 1).End(xlUp).Row
data = .Cells(2, 1).Resize(lr1 - 1, 3).Value
Set dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(data)
If Date - data(i, 2) If dic.exists(Trim(data(i, 1))) Then
fio = dic(Trim(data(i, 1)))
Else
Erase fio
ReDim fio(9)
End If
fio(data(i, 3) - 1) = fio(data(i, 3) - 1) + 1
dic(Trim(data(i, 1))) = fio
End If
Next i
End With
With sh2
lr2 = .Cells(Rows.Count, 2).End(xlUp).Row
For i = 3 To lr2
.Cells(i, "l").Resize(, 10).ClearContents
.Cells(i, "l").Resize(, 10) = dic(Trim(.Cells(i, 2)))
Next i
End With
End Sub
Sub macro()
Dim sh1 As Worksheet, sh2 As Worksheet, fio()
Dim lr1&, lr2&, data, i&, dic As Object
Set sh1 = ThisWorkbook.Sheets("Лист1")
Set sh2 = ThisWorkbook.Sheets("Лист2")
With sh1
lr1 = .Cells(Rows.Count, 1).End(xlUp).Row
data = .Cells(2, 1).Resize(lr1 - 1, 3).Value
Set dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(data)
If Date - data(i, 2) If dic.exists(Trim(data(i, 1))) Then
fio = dic(Trim(data(i, 1)))
Else
Erase fio
ReDim fio(9)
End If
fio(data(i, 3) - 1) = fio(data(i, 3) - 1) + 1
dic(Trim(data(i, 1))) = fio
End If
Next i
End With
With sh2
lr2 = .Cells(Rows.Count, 2).End(xlUp).Row
For i = 3 To lr2
.Cells(i, "l").Resize(, 10).ClearContents
.Cells(i, "l").Resize(, 10) = dic(Trim(.Cells(i, 2)))
Next i
End With
End Sub
Sub macro()
Dim sh1 As Worksheet, sh2 As Worksheet, fio()
Dim lr1&, lr2&, data, i&, dic As Object
Set sh1 = ThisWorkbook.Sheets("Лист1")
Set sh2 = ThisWorkbook.Sheets("Лист2")
With sh1
lr1 = .Cells(Rows.Count, 1).End(xlUp).Row
data = .Cells(2, 1).Resize(lr1 - 1, 3).Value
Set dic = CreateObject("scripting.dictionary")
For i = 1 To UBound(data)
If Date - data(i, 2) If dic.exists(Trim(data(i, 1))) Then
fio = dic(Trim(data(i, 1)))
Else
Erase fio
ReDim fio(9)
End If
fio(data(i, 3) - 1) = fio(data(i, 3) - 1) + 1
dic(Trim(data(i, 1))) = fio
End If
Next i
End With
With sh2
lr2 = .Cells(Rows.Count, 2).End(xlUp).Row
For i = 3 To lr2
.Cells(i, "l").Resize(, 10).ClearContents
.Cells(i, "l").Resize(, 10) = dic(Trim(.Cells(i, 2)))
Next i
End With
End Sub
у меня есть двумерный массив, и мне нужно, чтобы преобразовать его в список (тот же объект). Я не хочу делать это с for или foreach цикл, который будет принимать каждый элемент и добавлять его в список. Есть ли другой способ сделать это?
Преобразование double[, ] to List ? Если вы ищете однострочный, вот идет
Ну, вы можете заставить его использовать копию "blit", хотя это означает создание дополнительной копии : (
если вы довольны одномерным массивом, конечно, просто проигнорируйте последнюю строку:)
Buffer.BlockCopy реализуется как собственный метод, который я ожидал использовать чрезвычайно эффективное копирование после проверки. The List constructor , которая принимает IEnumerable оптимизирован для случая, когда он реализует IList , as double[] делает. Оно будет создайте резервный массив нужного размера и попросите его скопировать себя в этот массив. Надеюсь, что будет использовать Buffer.BlockCopy или что-то подобное тоже.
вот быстрый тест из трех подходов (для цикла, Cast().ToList() , и буфера.BlockCopy):
Результаты (время в миллисекундах);
EDIT: изменив цикл for для вызова array.GetLength() на каждой итерации цикл for и копия блока занимают примерно одно и то же время.
A for loop-самый быстрый способ.
вы можете сделать это с помощью LINQ, но это будет медленнее. И хотя вы сами не пишете цикл, под капотом все еще есть цикл.
- для зубчатого массива вы, вероятно, можете сделать что-то вроде arr.SelectMany(x=>x).ToList() .
On T[,] вы можете просто сделать arr.ToList() С IEnumerable of T[,] возвращает все элементы в 2D массива.похоже, что 2D-массив реализует только IEnumerable а не IEnumerable поэтому вам нужно вставить Cast как предложил yetanothercoder. Что сделает его еще медленнее из-за бокса.
единственное, что может сделать код быстрее, чем наивный цикл, - это вычислить количество элементов и построить список с правильной емкостью, поэтому ему не нужно расти.
Если Ваш массив прямоугольный, вы можете получить размер как width*height , с зубчатыми массивами это может быть сложнее.
In теория возможно использовать частное отражение и небезопасный код, чтобы сделать его немного быстрее, делая копию необработанной памяти. Но я категорически против этого.
Массивы – это множества однотипных элементов, имеющих одно имя и отличающиеся друг от друга индексами. Они могут быть одномерными (линейными), многомерными и динамическими. Массивы в VBA Excel, как и другие переменные, объявляются с помощью операторов Dim и Public. Для изменения размерности динамических массивов используется оператор ReDim. Массивы с заранее объявленной размерностью называют статическими.
Одномерные массивы
Объявление одномерных (линейных) статических массивов в VBA Excel:
В первом случае публичный массив содержит 10 элементов от 0 до 9 (нижний индекс по умолчанию — 0, верхний индекс — 9), а во втором случае локальный массив содержит 9 элементов от 1 до 9.
По умолчанию VBA Excel считает в массивах нижним индексом нуль, но, при желании, можно сделать нижним индексом по умолчанию единицу, добавив в самом начале модуля объявление «Option Base 1». Вместо верхнего индекса можно использовать переменную.
Многомерные массивы
Объявление многомерных статических массивов в VBA Excel аналогично объявлению одномерных массивов, но с добавлением размерностей дополнительных измерений через запятую:
Третий массив состоит из 10000 элементов — 10×10×10×10.
Динамические массивы
Динамические массивы в VBA Excel, в отличие от статических, объявляются без указания размерности:
Такие массивы используются, когда заранее неизвестна размерность, которая определяется в процессе выполнения программы. Когда нужная размерность массива становится известна, она в VBA Excel переопределяется с помощью оператора ReDim:
Переопределять размерность динамических массивов в процессе работы программы можно неоднократно, как по количеству измерений, так и по количеству элементов в измерении.
При переопределении размерности динамических массивов в VBA Excel теряются значения их элементов. Чтобы сохранить значения, используйте оператор Preserve:
Обратите внимание!
Переопределить с оператором Preserve можно только последнюю размерность динамического массива. Это недоработка разработчиков, которая сохранилась и в VBA Excel 2016. Без оператора Preserve можно переопределить все размерности.
Максимальный размер
Размер массива – это произведение длин всех его измерений. Он представляет собой общее количество элементов, содержащихся в данный момент в массиве.
По информации с сайта разработчиков, максимальный размер массивов зависит от операционной системы и доступного объема памяти. Использование массивов, размер которых превышает объем доступной оперативной памяти компьютера, приводит к снижению скорости, поскольку системе необходимо выполнять запись данных и чтение с диска.
Использование массивов
Приведу два примера, где не обойтись без массивов.
1. Как известно, функция Split возвращает одномерный массив подстрок, извлеченных из первоначальной строки с разделителями. Эти данные присваиваются заранее объявленному строковому (As String) одномерному динамическому массиву. Размерность устанавливается автоматически в зависимости от количества подстрок.
2. Данные в массивах обрабатываются значительно быстрее, чем в ячейках рабочего листа. Построчную обработку информации в таблице Excel можно наблюдать визуально по мерцаниям экрана, если его обновление (Application.ScreenUpdating) не отключено. Чтобы ускорить работу кода, можно значения из диапазона ячеек предварительно загрузить в динамический массив с помощью оператора присваивания (=). Размерность массива установится автоматически. После обработки данных в массиве кодом VBA полученные результаты выгружаются обратно на рабочий лист Excel. Обратите внимание, что загрузить значения в диапазон ячеек рабочего листа через оператор присваивания (=) можно только из двумерного массива.
Функции Array, LBound, UBound
Функция Array
Функция Array возвращает массив элементов типа Variant из первоначального списка элементов, перечисленных через запятую. Нумерация элементов в массиве начинается с нуля. Обратиться к элементу массива можно, указав в скобках его номер (индекс).
Читайте также: