Работа с массивами в StarBasic это ... нечто

Автор Kadet, 14 ноября 2020, 16:54

0 Пользователи и 1 гость просматривают эту тему.

eeigor

#15
В соответствии с последним постом от sokol92 попробуйте заменить массивы на словари (ассоциативные массивы). В вашей структуре 2 элемента? Если так, то пусть один будет ключом, а второй значением.
https://forumooo.ru/index.php/topic,8401.msg56540.html#msg56540
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

eeigor

#16
Или, если есть ошибки и вы уверены в этом, создайте скрытый лист, перенесите данные на лист путём присвоения массива диапазону (за один приём), отсортируйте данные на листе (не средствами Basic, а методами Calc'а) и верните данные обратно в процедуру, также одним движением... Это быстро, ибо сортировка на листе работает мгновенно. Отключите обновление экрана, если лист не скрыт. Как-то так...

UPD:
oRange.setDataArray(vArray)  'диапазон под размеры массива
vArray = oRange.getDataArray()
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

rami

Цитата: eeigor от 15 ноября 2020, 16:42...отсортируйте данные на листе (не средствами Basic, а методами Calc'а) и верните данные обратно в процедуру, также одним движением...
Данные в диапазоне в текстовом формате, поэтому сортироваться они будут как текст, а не как числа. Хотя, можно задать пользовательскую сортировку, но это может быть сложно.

Цитата: Kadet от 15 ноября 2020, 12:00
В общем - аккуратнее с массивами и с их обработкой. Там что-то нечистое творится.
Вы слишком сильно "замутили" код, отсортировать диапазон можно проще.

Kadet

Цитата: eeigor от 15 ноября 2020, 16:42В вашей структуре 2 элемента? Если так, то пусть один будет ключом, а второй значением.
Видимо не получится. Ключ, по идее, должен быть "неповторимым", уникальным, а у меня то, что можно сделать ключом - может повторяться бесчисленное количество раз.
Вот смотрите тип, который я создаю и который в котором существуют мои массивы:
Type TRaskroy
st(24) As Integer '//штук
othod% '//отход
End Type

А это значит, что позиция "othod" является просто значением типа int в каждой строчке массива. Мало того, в разных строках массива Raskroy (а это тоже сам по себе массив типа TRaskroy) значение Raskroy(i).othod может запросто повторяться. В то же время вторая часть массива Raskroy - st - это тоже массив, только внутренний, внутри типа. и наборы st(0)...st(24) могут быть только уникальными, хотя каждая из них (допустим st(0))  в разных строках массива Raskroy могут многократно повторяться.

В общем посмотрите мои таблицы в прилагаемом раньше dem. Какую позицию можно выделить в роли ключа? Разве что индекс Raskroy(i), но он и так по сути ключ.

Цитата: eeigor от 15 ноября 2020, 17:29создайте скрытый лист
Это бесперспективное направление. Это в демке я выложил вариант где всего 47 строк и 6 столбцов, но ведь их может быть и десятки и сотни тысяч (представьте себе факториал 25, может меньше, но соизмеримо). А, думаю, не стоит напоминать, что процедура печати в документ одна из самых длительных процедур. Сколько по времени будет заполняться лист их 50 000 строк? А потом сколько по времени эти данные будут считываться?

Kadet

Цитата: rami от 15 ноября 2020, 18:04Данные в диапазоне в текстовом формате
Не, ну не проблема их занести и как числа, но суть не в этом.

Kadet

#20
Цитата: rami от 15 ноября 2020, 18:04Вы слишком сильно "замутили" код, отсортировать диапазон можно проще.
Не совсем понял ваш макрос сортировки? По принципу пузырька, что ли? Что-то на него похоже?
Именно от пузырька я и уходил, вернее мне Майк посоветовал уйти от него и предложил такой вариант сортировки. Он быстрей. В принципе макрос сортировки и его подмакросы это макросы подаренные мне Майком.

А то, что я в calc-е работаю неоптимально, так не в этом же суть. Вывод и считывание с calc это только демка. В реалиях всё происходит в "компьютерном уме" и только результат выводится на поверхность, а он в сравнении с объёмом обрабатываемых данных - просто минимален - 1-20 строк всего, иногда чуть больше, но не значительно.
Просто для понимания и исследования тех данных, которыми оперирует программа я визуализирую их в calc.
И в итоге увидел такой вот косяк.

Кстати, сказать, что некоторые решения моей итоговой задачи (которая здесь не показана) с ошибкой в сортировке, гораздо лучше, чем с нормальной сортировкой, что весьма удивительно. Именно это и подвигло меня исследовать этот феномен.

Kadet

Вот, к примеру, просто демонстрационный итог этой задачи с полным набором данных (без макросов).

Лист1 - без сортировки.
Лист2 - с правильной сортировкой.
Лист3 - с ошибкой в сортировке.

Задача найти минимальное значение "Сумма". В Лист3, при ошибке, он оказывается минимальным.

eeigor

#22
Как-то так...

'    Copies an array to and from a range.
Sub CopyArrayToRange()
   Dim oSheet As Object, oRange As Object
   Dim vArr As Variant

   vArr = Array(Array("A1", "B1"), Array("A2", "B2"))

   oSheet = ThisComponent.CurrentController.ActiveSheet
   oRange = oSheet.getCellRangeByPosition(0, 0, UBound(vArr(0)), UBound(vArr))  'обратите внимание на UBound(vArr(0))
   oRange.DataArray = vArr  '.SetDataArray(vArr)

   With oRange.getCellRangeByName("A1")
       .String = .String & "*"  'changed
   End With

   Dim args(0) As New com.sun.star.beans.PropertyValue 'массив значений свойств, зд. для одного свойства "SortFields"
   Dim oSortFields(0) As New com.sun.star.util.SortField

   oSortFields(0).Field = 0  'номер столбца, по которому данные будут отсортированы (зд. A)
   oSortFields(0).SortAscending = False  'True

   args(0).Name = "SortFields"
   args(0).Value = oSortFields()
   oRange.Sort(args())

   vArr = oRange.DataArray  '.getDataArray()
   MsgBox vArr(0)(0)  '>> A2
End Sub


Данные скопированы в диапазон листа, изменена первая ячейка, данные отсортированы по первому столбцу в убывающем порядке и вновь возвращены в массив.

UPD: Код содержит ошибки, открыта новая тема... Ошибка в коде исправлена (UBound(vArr(0))
https://forumooo.ru/index.php/topic,8403.0/msg,56554.html
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

Kadet

Цитата: eeigor от 15 ноября 2020, 18:32Ну, только надо не изменять, а сортировать на листе... Будет время, допишу.
Возможно вы отклонились от сути моего посыла. С сортировкой проблем нет. Я коснулся её лишь затем, чтобы предостеречь народ и сообщить, что её нужно проверять, а не слепо доверять. Алгоритмов сортировок тьма и большинство работают безупречно.

Но вот работа с массивами в Basic... За нею глаз да глаз нужен.
Ведь показанный мною пример это не ошибка в сортировке, а ошибка в обработке массивов.
По сути, задача сводится к следующему - получить массив данных, сделать из него пару копий. Копии обработать разными способами так, чтобы при этом обработка копий не затрагивала ни оригинал ни другие копии. А это не получается.

В принципе, эту проблему я уже решил, тем самым "не_самым_правильным" образом - при формировании массива данных сразу же параллельно сформировал и его копии, как отдельные независимые массивы, с полностью зеркальными данными. И уже и над этими несвязанными массивами провожу эксперименты.
Результаты получились весьма хорошие.

eeigor

#24
Понятно.
Ну, проблему с массивами, как я понял, решают...
И в дальнейшем будем использовать, скорее всего, тот вариант, о котором писали выше:
ReDim Preserve aArr(n)
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

kompilainenn

Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

sokol92

Владимир.