Мое почтение, джентльмены. Появился следующий функционал, делюсь. Функции: 1.Array2Dto1D() - быстрое преобразования двухмерного массива в одномерный (данные не обрезаются, 2е измерение преобразуются в очередь) (v1.0.5.0 и выше) Параметры метода: 1.array_in_out - массив, который нужно преобразовать 2.lLbound1 - нижняя граница нового массива (по умолчанию=0)
2.Array1Dto2D() - быстрое преобразование одномерного массива в двухмерный (данные не удаляются) (v1.0.5.0 и выше) Параметры метода: 1.array_in_out - массив, который нужно преобразовать 2.lLbound1 - нижняя граница нового массива, 1е измерение (по умолчанию=0) 3.lLbound2 - нижняя граница нового массива, 2е измерение (по умолчанию=0) 4.cElements1 [/B ] - размер, первой размерности - кол-во столбцов (по умолчанию=1). Вторая рассчитывается автоматически (начиная с v2.0.0.2). Размер для размерности должен задаваться так, что бы общее количество элементов массива было кратно задаваемому размеру
Использование:
Код
Sub TestArrayDtoD()
Dim r As BedvitCOM.VBA: Set r = New BedvitCOM.VBA 'раннее связывание
Dim t, arr, i
arr = [a1:a1000000]
t = Timer
For i = 1 To 1000000
r.Array2Dto1D arr 'в одномерный (нижняя граница = 0 - по умолчанию)
r.Array1Dto2D arr, 1, 1 'в двухмерный с 1м столбцом, нижние границы измерений = 1
Next
Debug.Print "bVBA.ReDimArray: " & Timer - t & " sec."
End Sub
Результат: Преобразование массива из [B]1 млн строк из двухмерного в одномерный и наоборот 1 млн. раз = 0,1210938 sec.
начиная с v2.0.0.2
Код
Sub TestArrayDtoD_()
'Dim bVBA As New BedvitCOM.VBA 'раннее связывание
Dim bVBA As Object: Set bVBA = CreateObject("BedvitCOM.VBA") 'позднее связывание
Dim arr
arr = [a1:b10] ' забираем массив 2 столбца, 10 строк
bVBA.Array2Dto1D arr 'в одномерный (нижняя граница = 0 - по умолчанию)
bVBA.Array1Dto2D arr, 1, 1, 10 'преобразуем в двухмерный с 10ю столбцами и 2 строками, нижние границы измерений = 1, порядок данных сохраняется исходный
Cells(1, 1).Resize(UBound(arr, 1), UBound(arr, 2)) = arr 'нового размера массив со старым порядком данных
End Sub
Как уже говорил, преобразовать двумерный массив в одномерный можно 2мя способами:
Код
' столбцы-строки (твой вариант). Такой же порядок будет, если просто взять диапазон в массив (arr=rng.Value) и перебирать его в цикле For Each
For c = 1 To UBound(arr, 2)
For r = 1 To UBound(arr, 1)
Next r
Next c
' строки-столбцы. Такой порядок будет, если перебирать в цикле For Each ДИАПАЗОН по ЯЧЕЙКАМ
For r = 1 To UBound(arr, 1)
For c = 1 To UBound(arr, 2)
Next c
Next r
поэтому, лучше добавить второй вариант опциональным булевы параметром, понимая, что он не в сравнение медленнее (происходит реальное преобразование) Надо сказать, что перебор строки-столбцы (НЕ твой) я использую крайне редко
Array1Dto2D Нижние границы я бы по умолчанию сделал единицами, всё таки Ноль - это, конечно исходное состояние для любой числовой переменной, но тут логика такая, что диапазон с листа ВСЕГДА с ЕДИНИЦ, а значит двумерным массивом по умолчанию считается тоже массив с единиц (чтобы не путаться)
С одномерный проще, т.к. нет конфликта. Функция Split() ВСЕГДА возвращает одномерный массив с НОЛЯ, как и нижние границы всех объявляемых массивов ВСЕГДА начинаются с НОЛЯ, если не указано иное или не стоит параметр Option Base 1 (ни разу не видел необходимости в нём). Для Split'а же даже Option Base 1 не указ Есть какая-то одна функция (при работе с файлами, кажется), которая возвращает массив с единицы, но она настолько редкая, что не в счёт
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
нужен конечно Если не сделаешь, то хотя бы исправь название на Array2Dto1D_OnlyCR, а то некорректно получается
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
23/08/2022 - BedvitCOM v2.0.0.2 Array1Dto2D() - новый параметр 4.cElements1 - размер для первой размерности, кол-во столбцов (по умолчанию=1) Начиная с v2.0.0.2 можно задавать размер первой размерности, вторая рассчитывается автоматически, в зависимости от общего количества элементов. Размер для размерности должен задаваться так, что бы общее количество элементов массива было кратно задаваемому размеру. Порядок данных сохраняется первоначальный. Пример в начальном топе.
bedvit, приветствую и спасибо! Я правильно понимаю, что простыми словами, для двумерного массива с листа это означает "можно задавать количество строк двумерного массива при создании его из одномерного"? Пустые оставшиеся элементы (незаполненный до конца столбец) будут Empty?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous, привет, нет. Можно задать новое количество СТОЛБЦОВ, количество строк расчитается автоматически. Empty не будет. Все ячейки будут заполненны в исходном порядке. Вот пример, размещал здесь
Код
Sub TestArrayFilterV()
'Dim bVBA As New BedvitCOM.VBA
Dim bVBA As Object: Set bVBA = CreateObject("BedvitCOM.VBA")
Dim i, j, t, arrRes
Dim testSize1 As Long: testSize1 = 10 'строки
Dim testSize2 As Long: testSize2 = 5 'столбцы
Dim ArrV: ReDim ArrV(1 To testSize1, 1 To testSize2)
For i = 1 To testSize1
For j = 1 To testSize2
ArrV(i, j) = CLng(Rnd * 2)
Next
Next
Cells.ClearContents
Cells(1, 1).Resize(UBound(ArrV, 1), UBound(ArrV, 2)) = ArrV 'печатаем исходные условия
t = Timer
bVBA.ArrayFilterV ArrV, 1, 1, 1, 1, arrRes 'фильтруем по первому столбцу, значения равными = 1, выводим массив индексов в массив arrRes
Debug.Print Timer - t
bVBA.Array1Dto2D arrRes, 1, 1, 1 'преобразуем в двухмерный с 1 столбцам, нижние границы измерений = 1, порядок данных сохраняется исходный
Cells(1, 7).Resize(UBound(arrRes, 1), UBound(arrRes, 2)) = arrRes 'выводим массив полученных индексов, совпавших с условием по фильтру
bVBA.Array2Dto1D ArrV 'преобразуем ArrV в одномерный (нижняя граница = 0 - по умолчанию)
bVBA.Array1Dto2D ArrV, 1, 1, 10 'преобразуем ArrV в двухмерный с 10ю столбцами, нижние границы измерений = 1, порядок данных сохраняется исходный
Cells(1, 9).Resize(UBound(ArrV, 1), UBound(ArrV, 2)) = ArrV 'печатаем нового размера массив ArrV с сохранением исходного порядка следования элементов
End Sub
bedvit: задать количество СТОЛБЦОВ, количество строк…автоматически
не суть важно - одно от другого можно рассчитать. Может быть полезно
Цитата
bedvit: Empty не будет. Все ячейки будут заполненны в исходном порядке.
невозможно. 1. Есть массив arr(1 To 7) 2. Я преобразую этот одномерный массив в двумерный с нижними границами от 1 и 3мя столбцами: bVBA.Array1Dto2D arrRes, 3, 1, 1→arr(1 To 3, 1 To 3) 3. Что будет в arr(2,3) и arr(3,3)? Должно быть Empty…
Отсюда предложение: дать возможность задавать и "строки" и "столбцы", а также контролировать порядок заполнения (строки/столбцы или столбцы/строки). Нижнюю границу я бы сделал от 1 неизменной - никогда двумерный массив от 0 не был нужен, но можно и оставить возможность нижнюю задать, если хочется большей универсальности.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
bedvit, я правильно понимаю, что преобразовывать можно только такой одномерный массив, который при задании столбцов даст целое число строк?...
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
bedvit, не увидел, спасибо. А зачем так делать? Потому что больше свободы это другой алгоритм и заметно дольше?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Да. По сути мы меняем только несколько переменных в описании массива, размерности(нижняя граница и размер), эти данные хранятся как числа. Это быстро. Изменения количества элементов, это выделение памяти под новые элементы, плюс, если это строки, выделение паияти под символы строки и/или удаление элементов, освобождение памяти. Это дольше.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Полная свобода. Чего тебе еще надобно, старче ) из одномерного в любой двухмерный. Но с сохранением всех данных. Как в теме топика. Про изменения количества элементов я не писал. Для этого есть redim.
bedvit, пормоему, ты забываешь, для чего делаешь инструменты... У тебя тема о чём: преобразование из двумерного в одномерный и обратно. 2д в 1д опций всего 2: столбцы друг за другом или строки и нижняя граница нового одномерного массива. 1 д в 2д: либо перегоняй в двумерный с одним столбцом от единицы (нужен только для вставки на лист) без вариантов, либо дай возможность сразу создать любой двумерный массив (от единицы без вариантов или приведи пример, где может быть нужен двумерный массив от 0). Вызывать 2 твои функции сложнее и медленнее, чем одну.
И ты пишешь про количество столбцов, но это вторая размерность, а не первая.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
bedvit: cElements1 - размер для первой размерности, кол-во столбцов (по умолчанию=1)
первая размерность это "строки" - определись уже. Достаточно "по делу"?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
да, определились, как я и написал. Вот, еще раз прочитай, если забыл, об очередности элементов массива в СОМ, а не в Excel (писал в твоей же теме). Матчасть.
bedvit: прочитай, если забыл, об очередности элементов массива в СОМ, а не в Excel
Цитата
Jack Famous: по-моему, ты забываешь, для чего делаешь инструменты...
если ты делаешь инструмент для работы в VBA, то почему используешь какие-то другие определения? В VBA в двухмерном, массиве с листа, 1е измерение это строки, а второе - столбцы:
Код
arr= rng.Value
→ arr(1 To rng.Rows.Count, 1 To rng.Columns.Count)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
При чем здесь лист и столбцы и строки в вылеленном диапазоне? Мы говорим про масивы СОМ. Прочитай еще раз ссылку, о чем я писал. Предлагаю писать в данном топике по теме.
bedvit, не пойму, зачем VBA разработчику знать особенности работы с COM, чтобы работать с твоей библиотекой… Выкладывай тогда код на сях, а дальше пусть сами адаптируют - что опять за полумеры…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Это библиотека СОМ. Ей могут пользоватся и в 1С, и в Python, и в VB и т.д. Почему я должнен писать в терминах Excel? Еще раз, функционал работает, а как называется параметр это вкусовщина, не относящаяся к работоспособности. Предлагаю не превращать тему в балаган.
как минимум, потому что ты предлагаешь свой продукт здесь - на сайте Excel. Считаешь, что ВСЕ тут должны подтянуться до твоего уровня знаний COM или всё же проще ТЕБЕ объяснять в понятных VBAшнику терминах?…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Ребята, обсуждение в ДВУХ темах переросло в переписку двух человек, которая емкому из форумчан ничего не даёт. И конца этому не видно. Может быть вы уже перейдёте в личку? А когда всё будет готово - вариант сюда.
извольте, если обсуждение параметров инструмента темы считаешь флудом, то я умываю руки. Как в моих темах РЕАЛЬНО не по делу болтать, так никто не чистит (хотя я даже просил) и ты был там одним из зачинщиков. Двойные стандарты, однако...
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄