Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

1 Декабрь 2020, 08:07 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Доступно и просто о работе в офисных пакетах
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: « 1 2   Вниз
  Печать  
Автор Тема: Работа с массивами в StarBasic это ... нечто  (Прочитано 726 раз)
0 Пользователей и 1 Гость смотрят эту тему.
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 197



« Ответ #15: 15 Ноябрь 2020, 16:42 »

В соответствии с последним постом от sokol92 попробуйте заменить массивы на словари (ассоциативные массивы). В вашей структуре 2 элемента? Если так, то пусть один будет ключом, а второй значением.
https://forumooo.ru/index.php/topic,8401.msg56540.html#msg56540
« Последнее редактирование: 15 Ноябрь 2020, 16:44 от eeigor » Записан
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 197



« Ответ #16: 15 Ноябрь 2020, 17:29 »

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

UPD:
oRange.setDataArray(vArray)  'диапазон под размеры массива
vArray = oRange.getDataArray()
« Последнее редактирование: 15 Ноябрь 2020, 17:59 от eeigor » Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 3 031


iMac, LibreOffice и Apache OpenOffice


« Ответ #17: 15 Ноябрь 2020, 18:04 »

...отсортируйте данные на листе (не средствами Basic, а методами Calc’а) и верните данные обратно в процедуру, также одним движением…
Данные в диапазоне в текстовом формате, поэтому сортироваться они будут как текст, а не как числа. Хотя, можно задать пользовательскую сортировку, но это может быть сложно.

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

* dem1.ods (18.34 Кб - загружено 4 раз.)
Записан

Kadet
Форумчанин
***
Offline Offline

Сообщений: 400


« Ответ #18: 15 Ноябрь 2020, 18:06 »

В вашей структуре 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), но он и так по сути ключ.

создайте скрытый лист
Это бесперспективное направление. Это в демке я выложил вариант где всего 47 строк и 6 столбцов, но ведь их может быть и десятки и сотни тысяч (представьте себе факториал 25, может меньше, но соизмеримо). А, думаю, не стоит напоминать, что процедура печати в документ одна из самых длительных процедур. Сколько по времени будет заполняться лист их 50 000 строк? А потом сколько по времени эти данные будут считываться?
Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 400


« Ответ #19: 15 Ноябрь 2020, 18:07 »

Данные в диапазоне в текстовом формате
Не, ну не проблема их занести и как числа, но суть не в этом.
Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 400


« Ответ #20: 15 Ноябрь 2020, 18:17 »

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

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

Кстати, сказать, что некоторые решения моей итоговой задачи (которая здесь не показана) с ошибкой в сортировке, гораздо лучше, чем с нормальной сортировкой, что весьма удивительно. Именно это и подвигло меня исследовать этот феномен.
« Последнее редактирование: 15 Ноябрь 2020, 18:23 от Kadet » Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 400


« Ответ #21: 15 Ноябрь 2020, 18:28 »

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

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

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

* dem2.ods (14.52 Кб - загружено 2 раз.)
Записан
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 197



« Ответ #22: 15 Ноябрь 2020, 18:32 »

Как-то так...

Код:
'    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
« Последнее редактирование: 15 Ноябрь 2020, 22:11 от eeigor » Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 400


« Ответ #23: 15 Ноябрь 2020, 18:48 »

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

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

В принципе, эту проблему я уже решил, тем самым "не_самым_правильным" образом - при формировании массива данных сразу же параллельно сформировал и его копии, как отдельные независимые массивы, с полностью зеркальными данными. И уже и над этими несвязанными массивами провожу эксперименты.
Результаты получились весьма хорошие.
Записан
eeigor
Ubuntu 18.04 LTS • LO 7.0.2.2
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 197



« Ответ #24: 15 Ноябрь 2020, 18:54 »

Понятно.
Ну, проблему с массивами, как я понял, решают...
И в дальнейшем будем использовать, скорее всего, тот вариант, о котором писали выше:
ReDim Preserve aArr(n)
« Последнее редактирование: 16 Ноябрь 2020, 00:34 от eeigor » Записан
kompilainenn
Мастер
*****
Online Online

Сообщений: 3 095



« Ответ #25: 15 Ноябрь 2020, 19:49 »

Ну, проблему с массивами, как я понял, решают...
нет
Записан

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

Пол: Мужской
Сообщений: 229


WWW
« Ответ #26: 15 Ноябрь 2020, 20:07 »

Я 14.09.2020 написал баг про Redim.
Записан

Владимир.
Страниц: « 1 2   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!