Страницы: 1 2 След.
RSS
Быстрое преобразование массива из одномерного в двухмерный и наоборот с сохранением всех данных (BedvitCOM v1.0.5.0 и выше)
 
Мое почтение, джентльмены.
Появился следующий функционал, делюсь.
Функции:
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
Изменено: bedvit - 29.08.2022 14:03:24
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, приветствую и спасибо!

Array2Dto1D
Как уже говорил, преобразовать двумерный массив в одномерный можно 2мя способами:
поэтому, лучше добавить второй вариант опциональным булевы параметром, понимая, что он не в сравнение медленнее (происходит реальное преобразование)
Надо сказать, что перебор строки-столбцы (НЕ твой) я использую крайне редко

Array1Dto2D
Нижние границы я бы по умолчанию сделал единицами, всё таки
Ноль - это, конечно исходное состояние для любой числовой переменной, но тут логика такая, что диапазон с листа ВСЕГДА с ЕДИНИЦ, а значит двумерным массивом по умолчанию считается тоже массив с единиц (чтобы не путаться)

С одномерный проще, т.к. нет конфликта. Функция Split() ВСЕГДА возвращает одномерный массив с НОЛЯ, как и нижние границы всех объявляемых массивов ВСЕГДА начинаются с НОЛЯ, если не указано иное или не стоит параметр Option Base 1 (ни разу не видел необходимости в нём). Для Split'а же даже Option Base 1 не указ
Есть какая-то одна функция (при работе с файлами, кажется), которая возвращает массив с единицы, но она настолько редкая, что не в счёт
Изменено: Jack Famous - 06.08.2021 14:54:23
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
Надо сказать, что перебор строки-столбцы (НЕ твой) я использую крайне редко
Используется редко, поэтому нужен ли он - вопрос. Будет нужен - обдумаем.
Цитата
Jack Famous написал:
С одномерный проще, т.к. нет конфликта.
Да и с двухмерным нет конфликта, всегда же можно легко и просто поставить любую нижнюю границу в функцию.
Изменено: bedvit - 06.08.2021 17:56:35
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit: Будет нужен - обдумаем
нужен конечно  :)
Если не сделаешь, то хотя бы исправь название на Array2Dto1D_OnlyCR, а то некорректно получается
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
23/08/2022 - BedvitCOM  v2.0.0.2
Array1Dto2D() - новый параметр 4.cElements1 - размер для первой размерности, кол-во столбцов (по умолчанию=1)
Начиная с v2.0.0.2 можно задавать размер первой размерности, вторая рассчитывается автоматически, в зависимости от общего количества элементов. Размер для размерности должен задаваться так, что бы общее количество элементов массива было кратно задаваемому размеру. Порядок данных сохраняется первоначальный.
Пример в начальном топе.
Изменено: bedvit - 23.08.2022 20:59:01
«Бритва Оккама» или «Принцип Калашникова»?
 
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 - 24.08.2022 10:13:07
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit: задать количество СТОЛБЦОВ, количество строк…автоматически
не суть важно - одно от другого можно рассчитать. Может быть полезно  :idea:

Цитата
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 не был нужен, но можно и оставить возможность нижнюю задать, если хочется большей универсальности.
Изменено: Jack Famous - 26.08.2022 17:55:57
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
Что будет в arr(2,3) и arr(3,3)
Ничего не будет. Ты так не сможешь сделать. Взял бы да потестировал.
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, я правильно понимаю, что преобразовывать можно только такой одномерный массив, который при задании столбцов даст целое число строк?...
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Если тебе такая формулировка больше понятнее, чем в 5м сообщении, то да.
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, не увидел, спасибо.
А зачем так делать? Потому что больше свободы это другой алгоритм и заметно дольше?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Да. По сути мы меняем только несколько переменных в описании массива, размерности(нижняя граница и размер), эти данные хранятся как числа. Это быстро. Изменения количества элементов, это выделение памяти под новые элементы, плюс, если это строки, выделение паияти под символы строки и/или удаление элементов, освобождение памяти. Это дольше.
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, ну так дай свободу действий и делай по ситуации. Что за полумеры ...
Изменено: Jack Famous - 27.08.2022 18:27:12
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Полная свобода. Чего тебе еще надобно, старче :)) из одномерного в любой двухмерный. Но с сохранением всех данных. Как в теме топика. Про изменения количества элементов я не писал. Для этого есть redim.
Изменено: bedvit - 27.08.2022 18:43:55
«Бритва Оккама» или «Принцип Калашникова»?
 
Делаешь redim одномерного массива до любого какаого хочешь размера. Преобразовываешь в двухмерный, если тебе хочется изменить кол-во элементов
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, пормоему, ты забываешь, для чего делаешь инструменты...
У тебя тема о чём: преобразование из двумерного в одномерный и обратно.
2д в 1д опций всего 2: столбцы друг за другом или строки и нижняя граница нового одномерного массива.
1 д в 2д: либо перегоняй в двумерный с одним столбцом от единицы (нужен только для вставки на лист) без вариантов, либо дай возможность сразу создать любой двумерный массив (от единицы без вариантов или приведи пример, где может быть нужен двумерный массив от 0).
Вызывать 2 твои функции сложнее и медленнее, чем одну.

И ты пишешь про количество столбцов, но это вторая размерность, а не первая.
Изменено: Jack Famous - 27.08.2022 20:37:07
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
По делу есть замечания? Какой функционал у тебя не получилось сделать?
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit: По делу есть замечания?
Цитата
bedvit: cElements1 - размер для первой размерности, кол-во столбцов (по умолчанию=1)
первая размерность это "строки" - определись уже. Достаточно "по делу"?  :)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Нет, не по делу.
Цитата
Jack Famous написал:
определись уже.
да, определились,  как я и написал. Вот, еще раз прочитай, если забыл, об очередности элементов массива в СОМ, а не в Excel (писал в твоей же теме).
Матчасть.
Изменено: bedvit - 29.08.2022 13:48:49
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit: прочитай, если забыл, об очередности элементов массива в СОМ, а не в Excel
Цитата
Jack Famous: по-моему, ты забываешь, для чего делаешь инструменты...
если ты делаешь инструмент для работы в VBA, то почему используешь какие-то другие определения? В VBA в двухмерном, массиве с листа, 1е измерение это строки, а второе - столбцы:
Код
arr= rng.Value
→ arr(1 To rng.Rows.Count, 1 To rng.Columns.Count)
Изменено: Jack Famous - 29.08.2022 15:07:40
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
При чем здесь лист и столбцы и строки в вылеленном диапазоне? Мы говорим про масивы СОМ. Прочитай еще раз ссылку, о чем я писал.
Предлагаю писать в данном топике по теме.
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, не пойму, зачем VBA разработчику знать особенности работы с COM, чтобы работать с твоей библиотекой…
Выкладывай тогда код на сях, а дальше пусть сами адаптируют - что опять за полумеры…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Это библиотека СОМ. Ей могут пользоватся и в 1С, и в Python, и в VB и т.д. Почему я должнен писать в терминах Excel?  
Еще раз, функционал работает, а как называется параметр это вкусовщина, не относящаяся к работоспособности. Предлагаю не превращать тему в балаган.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit: Почему я должнен писать в терминах Excel?
как минимум, потому что ты предлагаешь свой продукт здесь - на сайте Excel. Считаешь, что ВСЕ тут должны подтянуться до твоего уровня знаний COM или всё же проще ТЕБЕ объяснять в понятных VBAшнику терминах?…
Изменено: Jack Famous - 29.08.2022 17:42:59
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Ребята, обсуждение в ДВУХ темах переросло в переписку двух человек, которая емкому из форумчан ничего не даёт. И конца этому не видно. Может быть вы уже перейдёте в личку? А когда всё будет готово - вариант сюда.
 
Цитата
Юрий М написал:
Может быть вы уже перейдёте в личку?
ты еще телеграмм канала не видел   :D из чата в вазап нас с Алексеем, как раз за тоже самое выгнали  ;)
Изменено: БМВ - 29.08.2022 19:04:30
По вопросам из тем форума, личку не читаю.
 
Юрий, согласен. Прошу почистить тему и удалить все начиная с 12 сообщения. Флуд не по делу.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал: Флуд не по делу.
Даже вытяжка в курилке не справляется уже )
 
Цитата
bedvit: Флуд не по делу.
извольте, если обсуждение параметров инструмента темы считаешь флудом, то я умываю руки.
Как в моих темах РЕАЛЬНО не по делу болтать, так никто не чистит (хотя я даже просил) и ты был там одним из зачинщиков. Двойные стандарты, однако...
Изменено: Jack Famous - 29.08.2022 19:59:05
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1 2 След.
Наверх