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

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

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

Войти
Новости: Доступно и просто о работе в офисных пакетах
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1   Вниз
  Печать  
Автор Тема: ScriptForge  (Прочитано 609 раз)
0 Пользователей и 1 Гость смотрят эту тему.
eeigor
Форумчанин
***
Offline Offline

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



« Стартовое сообщение: 28 Март 2021, 08:57 »

Сразу оговорюсь, что это ни в коем случае не критика (!), а просто попытка разобраться с новым набором инструментов
Оценить многие вещи мне не позволяет... квалификация Улыбка

ScriptForge Dictionary vs EnumerableMap (?)
Где-то @sokol92 уже писал о том, что разработчики, видимо, не знали о существования сервиса "com.sun.star.container.EnumerableMap", добавив "Dictionary" в библиотеку "ScriptForge", который реализован через VBA Collection в режиме совместимости в виде модуля класса. Осталось неясно: зачем (?).

Работает с массивом пользовательского типа данных:
ReDim Preserve MapItems(1 To _MapSize)
Вряд ли это эффективно по быстродействию.
Это из описания:
'''      Why a Dictionary class beside the builtin Collection class ?
'''         A standard Basic collection does not support the retrieval of the keys
'''         Additionally it may contain only simple data (strings, numbers, ...)

Кроме того, для этого модуля (для таких модулей) у меня не работает переход из каталога объектов к процедуре по двойному щелчку. Из-за режима совместимости, что ли? Надо прокручивать текст вручную...
Внедрён новый стиль программирования (обработка ошибок). Не хватает руководств с примерами...

Сервис EnumerableMap уже был здесь "опробован" для решения задачи с "раскраской" дубликатов в диапазоне ячеек.
« Последнее редактирование: 28 Март 2021, 12:50 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.1.1.2 Community
eeigor
Форумчанин
***
Offline Offline

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



« Ответ #1: 28 Март 2021, 11:29 »

Впрочем, таких "непоняток" много:
 Функция TrimExt() 'Extended, надо полагать, но "расширить" функциональность забыли
   If Len(InputStr) > 0 Then
      sTrim = SF_String.ReplaceRegex(InputStr, REGEXLTRIM, "")  'Trim left
      sTrim = SF_String.ReplaceRegex(sTrim, REGEXRTRIM, "")  'Trim right
   End If

Returns the input string without its leading and trailing whitespaces.
А что делает штатная функция Basic Trim()? То же самое, в отличие от одноимённой функции листа. Где же удаление лишних пробелов в центре строки? Впрочем, несложно добавить... Улыбка Кто будет использовать TrimExt вместо Trim, непонятно, и главное - зачем?
Впрочем, регулярное выражение "[\s]+" удалит не только пробелы... но всё равно этого мало. Нужна была функция TrimAll().
Недавно решал ту же задачу (блок 2 With удаляет лишние пробелы в середине строки):
Код:
With oReplace: .SearchRegularExpression = True: .SearchWords = False
.setSearchString("^\s+|\s+$")  'any spaces at the start or end…
.setReplaceString("")  '…replaces with null string
End With
nCount = oRanges.replaceAll(oReplace)

With oReplace
.setSearchString("\s{2,}")  '2+ consecutive spaces…
.setReplaceString(" ")  '…replaces with one
End With
nCount = nCount + oRanges.replaceAll(oReplace)

Прочий код перегружен своими "обёртками" разного рода, которые "собирают в кучу" то, что лучше оставить "на месте":
oTextSearch = SF_Utils._GetUNOService("TextSearch")  ' это вместо: oTextSearch = CreateUnoService("com.sun.star.util.TextSearch")

UPD:
Зачем нужны примитивные процедуры? Всё это риторические вопросы...
Код:
Sub RefreshDataPilot()
Dim oSheet As Object, oTables As Object, oTable As Object

'oSheet = ThisComponent.Sheets.getByIndex(3)
oSheet = ThisComponent.CurrentController.ActiveSheet
oTables = oSheet.getDataPilotTables()

'Dim sTableName As String
'sTableName = oTables.ElementNames(0)  '"DataPilot1"
'oTable = oTables.getByName(sTableName)
oTable = oTables.getByIndex(0)  'всего одна таблица на листе

oTable.refresh
End Sub
Я обновляю свои сводные таблицы при активации листа, и для этого не надо загружать внешнюю библиотеку.
К тому же код имеет ограничение:
oTables.getByIndex(0)  'всего одна таблица на листе

UPD2:
А функция FindRegex() может не больше (или меньше?), чем функция листа, доступная через FunctionAccess (убрали аргумент Occurrence, добавили Start: первое - это номер вхождения, что и нужно; второе - номер символа в строке). Я ожидал, что будет возращён массив всех вхождений, но здесь надо организовывать цикл, зато ищет Forward/Backward (если это нужно кому-то).
Но поиск организован с использованием объектов и методов/свойств, что и ожидалось.
@sokol92, предлагаю сравнить решение от разработчиков с нашими дискуссиями...
« Последнее редактирование: 28 Март 2021, 12:47 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.1.1.2 Community
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 2 080


« Ответ #2: 28 Март 2021, 14:49 »

предлагаю сравнить решение от разработчиков с нашими дискуссиями...

Некорректно называть это "решением от разработчиков". Фактически два человека - разработчик библиотеки макросов Access2Base и человек, занимающийся документированием скриптовых языков  LO - решили, что нужно их собственные наработки включить в пакет. Все присутствующие на форуме - в не меньшей степени разработчики, за исключением того что те двое всё-таки решили делать, а у нас doers decide.
Записан

С уважением,
Михаил Каганский
eeigor
Форумчанин
***
Offline Offline

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



« Ответ #3: 28 Март 2021, 15:16 »

@mikekaganski, добрый день. Я оговорился. Речь о разработчиках конкретных библиотек. Код в любом случае полезен, ибо туда смотрим, к себе переносим. По пути встречаем много нового. Но в отношении ссылки на решение, то там всё так, как надо: поиск по тексту организован правильно, то есть без цикла (regex vs InStr).
« Последнее редактирование: 28 Март 2021, 17:51 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.1.1.2 Community
sokol92
Форумчанин
***
Offline Offline

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


WWW
« Ответ #4: 28 Март 2021, 17:22 »

Сервис EnumerableMap создает объект, являющийся аналогом объекта Scripting.Dictionary MS Windows.
Основные отклонения:
EnumerableMap не имеет счетчика  элементов (count)
EnumerableMap не имеет метода для переименования ключа
Dictionary не имеет метода для проверки наличия значения (метод containsValue)
EnumerableMap нумерует ключи по возрастанию (хотя это и не указано явно в документации). Если мы хотим для Dictionary получить массив ключей по возрастанию, то ключи нужно отсортировать самостоятельно.

Тесты, которые я использовал для проверки быстродействия и сопоставления с Dictionary.

Код:
' Тестирование сервиса EnumerableMap
Sub testEnumerableMap
 Dim oEnumerableMap, keyEnum
 Dim nmax as Long, i as Long, key as String, t as Long, s as String, v
 
 Nmax=100000
 key=String(200, "a")
  
 oEnumerableMap = com.sun.star.container.EnumerableMap.create("string", "any")
 
 t=GetSystemTicks()
 For i=1 To nmax
    oEnumerableMap.put key & i, i
 Next i  
 
 s="Запись " & nmax & ": " & (GetSystemTicks()-t)
 t=GetSystemTicks()
 
 For i=1 To nmax
    v=oEnumerableMap.get(key & i)
 Next i  
 
 s=s & chr(10) & "Чтение " & nmax & ": " & (GetSystemTicks()-t)
 t=GetSystemTicks()

 KeyEnum=oEnumerableMap.createKeyEnumeration(0)
 i=0
 ReDim v(nmax-1)
 While KeyEnum.hasMoreElements
   v(i)=KeyEnum.NextElement
   i=i+1
 Wend
 
 s=s & chr(10) & "Нумератор " & i & ": " & (GetSystemTicks()-t)
  
 Msgbox s
End Sub

Для VBA (c объектом Scripting.Dictionary):
Код:
Option Explicit
Sub testEnumerableMap()
 Dim oEnumerableMap, keyEnum
 Dim nmax As Long, i As Long, key As String, t As Long, s As String, v
 
 nmax = 100000
 key = String(200, "a")
  
 Set oEnumerableMap = CreateObject("Scripting.Dictionary")
 
 t = GetSystemTicks()
 For i = 1 To nmax
    oEnumerableMap.Add key & i, i
 Next i
 
 s = "Запись " & nmax & ": " & (GetSystemTicks() - t)
 t = GetSystemTicks()
 
 For i = 1 To nmax
    v = oEnumerableMap.Item(key & i)
 Next i
 
 s = s & Chr(10) & "Чтение " & nmax & ": " & (GetSystemTicks() - t)
 t = GetSystemTicks()

 keyEnum = oEnumerableMap.keys
 i = UBound(keyEnum) + 1
 
 s = s & Chr(10) & "Нумератор " & i & ": " & (GetSystemTicks() - t)
  
 MsgBox s
End Sub

Function GetSystemTicks() As Long
  GetSystemTicks = CLng(Timer * 1000)
End Function

На мой взгляд, оценка для EnumerableMap - "отлично".
« Последнее редактирование: 28 Март 2021, 17:23 от sokol92 » Записан

Владимир.
eeigor
Форумчанин
***
Offline Offline

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



« Ответ #5: 28 Март 2021, 21:59 »

Просмотрел модуль SF_Timer
Честное слово, подход от @sokol92 (здесь выше) с системной функцией GetSystemTicks() в разы проще и лучше. Я под "инкапсуляцией" разумею другое. Класса я не увидел. Нет, он есть, но я его не увидел... Впрочем, это ведь не класс, а служба! Кстати, в модуле вызывается функция листа NOW через систему обёрток и завуалированных констант. Короче, налицо неоправданная сложность, имхо. Чувствуется "проникновение" Python в Basic (комментарий в начале процедуры предваряется тройной кавычкой) Улыбка . Но Python - это краткость и ясность. Однако объем проделанной работы огромен.
Это хоть какой-то учебный материал, с которым можно много и долго работать. Тем более, что с некоторыми темами, затронутыми авторами, я не знаком.
« Последнее редактирование: 29 Март 2021, 11:15 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.1.1.2 Community
eeigor
Форумчанин
***
Offline Offline

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



« Ответ #6: 29 Март 2021, 06:54 »

Презентация
На VBA написаны тонны кода… И здесь в нашем распоряжении такая "тонна" примитивного (термин авторов библиотеки, используется в значении «базового», «основного», «необходимого») кода, который авторы любезно предоставили в наше распоряжение. За это им спасибо.

UPD:
Ещё один важный момент. Присвоение имён – это не простой вопрос, как может показаться на первый взгляд. Библиотека содержит всю необходимую лексику. Пользуйтесь.

* oSLO-ScriptForge-2020-10.pdf (1272.84 Кб - загружено 7 раз.)
« Последнее редактирование: 29 Март 2021, 08:43 от eeigor » Записан

Ubuntu 18.04 LTS • LO 7.1.1.2 Community
Страниц: 1   Вверх
  Печать  
 
Перейти в:  

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