[SOLVED]: LOWriter: All Tables "BackgroundColor, SizeOptimal"

Автор Smilik, 4 февраля 2021, 03:49

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

Smilik

Задача:
1. Перебрать все таблицы в текстовом документе (50..100 ).
2. Для каждой таблицы: установить цвет фона, применить "SizeOptimal"

Задумка:
1. Записать макрос действий (Курсор в таблицу -> Ctrl+A->Ctrl+A -> ColumnsOptimalWidth, RowsOptimalHeight)
2. Написать на бейсике "обертку": среду переменных и цикл обработки
3. вставить команды из записанного макроса в подготовленную обертку.

Встреченные проблемы:
1. таблицу полученную из общего списка "выделить целиком"
    oTable = oTables.getTableByName(Name)
2. передать в dispatcher (?? Args(0)...... ??).
3. dispatcher.executeDispatch(document, ".uno:SizeOptimal", "", 0, args1())
uno:SizeOptimal - команда не найдена или не работает.... (LO 5.2.7.)

Как выглядит сам принцип выделения объекта в пределах API?
/// Через наименование? Через список элементов объекта? через курсор?
как передать выделенный объект на обработку в dispatcher?

Во избежание вопросов о рассмотренных источниках и м.б. кому на доброе дело.

РАССМОТРЕННАЯ ЛИТЕРАТУРА(всё, что найдено в интернете):

Andrew_Macros_2006-01-25.odt
Andrew_Macros_2006-08-04.odt
Andrew_Macros_2007-2008_rus.odt
Andrew_Macros_2007-Полезная информация по Макросам для OpenOffice.org.odt
Andrew_Macros_2008_pro. Автоматизация работы by Питоньяк Эндрю_2008(z-lib.org)_####.pdf
Andrew_Macros_2015.odt
Andrew_oome_1_0_2003_sc01_2003.pdf
Andrew_oome_1_0_2003_sc15_2003.pdf
Andrew_OOME_1_0_2004_Explained.Master_2004.pdf
Andrew_OOME_3_0_2016.odt
Andrew_OOME_4_0_2018.odt
####################
2000-Sun StarOffice Programming tutorial - 2000.pdf
2003-French-GuideMacrosOOoAndrew4.pdf
2004-developerplatform.pdf
2006-Learn.OpenOffice.org.Spreadsheet.Macro.Programming.pdf
2008-2010-BasicGuide_OOo3.2.0.odt
2010-ИиП-Информатика и программирование-Суханов А.Я-2010-Томск.pdf     (Особо ценное)
2014-LO_4.3_Writer-WG4209-WorkingWithTables.pdf
2014-simplooo-OOo_API_intro-(French).pdf
2017-LO-Macro_insert data into table control-16075913541818061.odt
2018-LO_6.0_Basic-1-IDE-Flat-Letter-EN-v102.pdf
2018-LO_Basic_Olshevskii_Andrei_Georgievich.odt
2018-LO-Basic-1-IDE-Flat-Letter-EN-v102.odt
2018-LO-Basic-1-IDE-Flat-Letter-EN-v102-crop.odt
2018-LO-Basic-1-IDE-Flat-Letter-EN-v102-m.odt
2018-LO-Basic-2-Overview-Flat-Letter-EN-v110.odt
2018-LO-Basic-3-Calc-Flat-A4-EN-v111.odt
2018-LO-Basic-5-ExecLib-Flat-A4-EN-v101.odt
2018-LO-Basic-6-Dialogs-Flat-A4-EN-v103.odt
2019-LibreOfficeBasic-Практическое использование макросов-Якунина М.В.-2019_####.pdf
2020-LO_6.4_Calc-CG64-CalcGuide.pdf
2020-LO_7.0_MG70-MathGuide.pdf
2020-LO_7.0-Calc-CG70-CalcGuide.pdf
2021-Example_macro_to_convert_table_to_text.odt
OOA_Extensions_sf.net.odt
LO-5.x-Shortcuts-Quick-reference-guide-En.odt

economist

#1
У Питоньяка по-моему есть и перебор коллекции таблиц, и выделение всех их строк через API.

Хваленый шаблон разработки MVC - Model, View, Controller - немцы StarOffice-a в своё время возвели в абсолют, поэтому некоторые объекты (контролы на формах, текстовые поля итп - короче самые важные и часто нужные вещи) - в LO можно процедурно выделить только полным перебором через .createEnumeration(), обращаясь к их .Parent и сравнивая совпадают ли они (или называть одинаково и сопоставлять по имени). Это, конечно, всё очень сильно замедляет разработку. А когда объектов сотни - то и работает это медленно.

Если задача одноразовая, то запишите макрос для текущей таблицы, назначьте на клавишу и "дерните" его 100 раз в каждой. Будет быстрее, чем писать правильный, но "одноразовый" код. К тому же автоподбор ширины не всегда удачен, надо править ручками сам текст, вводит переносы итп.  

...
args1(1).Name = "BackgroundPattern.BackColor"
args1(1).Value = 65280 ' green
dispatcher.executeDispatch(document, ".uno:TableBackground", "", 0, args1()) '
dispatcher.executeDispatch(document, ".uno:SetOptimalColumnWidth", "", 0, Array())
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

sokol92

Цитата: Smilik от  4 февраля 2021, 03:49Задумка:
1. Записать макрос действий (Курсор в таблицу -> Ctrl+A->Ctrl+A -> ColumnsOptimalWidth, RowsOptimalHeight)

Боюсь Вас разочаровать, но макрорекордер в LibreOffice (LO) отстал от жизни. Он записывает действия пользователя как обращения к командам Диспетчера. Если же Вы хотите писать эффективные макросы, но следует использовать UNO технологии.

По счастью, есть замечательная книга А.Питоньяка OOME_4_0.odt "OpenOffice.org Macros Explained", которую надо читать и перечитывать, при этом имея в виду, что она написана давно и может не соответствовать текущему состоянию LO.

В частности, таблицам документа Writer в книге отведен подраздел 14.9.
Владимир.

Smilik

economist, спасибо за объяснение общего принципа.
концепция M-V-C - доведенная до принципиальности.
Итого делаю вывод, что для автоматизации обработки следует написать процедуру последовательного выделения всей таблицы целиком по курсору.
sokol92 спасибо, за подсказку.
два уточнения:
1. работаю на LO 5.2.7,
2. где брать достойную документацию по UNO?

ВОПРОС: при помощи макроса из книги Питоньяка получен приложенный файл со списками команд UNO (? или API?)

В любом случае, пока остается вопрос как это всё "срастить". попробую что-то с подсказкой от economist



Smilik

Цитата: economist от  4 февраля 2021, 08:54Если задача одноразовая,
Задача многоразовая. ожидаемо - 4-5 файлов с 50-100 таблиц в каждом.
И ещё, аналогичная задача - удалять разрывы страниц - это после ФайнРидера.

Вариант записать макрос и подвязать на клавиатуру - работает, но приходится пролистывать до следующей стаблицы.
Вариант выбора таблицы в навигаторе - работает с ошибкой: иногда выделение всей таблицы по первой же команде Ctrl+A (а в записанном макросе их две). Тогда вторая из записанных команд выделяет весь документ и работа макроса срывается.

// попутные вопросы:
1. насколько сложно макросом расширить функционал офиса? Конкретно: встроить фунцию множественного выбора в навигатор?
2. При каких условиях кто-то (или команда) взялся бы "поднять" Organon Extension (by X-Roemer - github) - до LO 7.0 ?
Расширение для работы с файлами большого объема и написания научных работ - самое то. Но последняя версия с которой нормально работает - LO 5.2.7. Из-за этого "привязался" к этой версии. Хотя поледние кажется и стабильнее и быстрее.
Из плюсов расширения:
-- полный оформительский функционал LO
-- Импорт / экспорт целиком и частями
-- сквозной поиск, со списком найденного - похоже на поисковик
-- планирование работы
-- работа с подразделами большого документа -> быстрая загрузка и сохранение
-- резервное копирование проекта
Было бы очень востребовано поднять этот плагин до версии 7.0 или даже встроить в штатный функционал LO.


economist

После FineReader обычно делают:
- сброс всего форматирования, загрузку стилей из др. файла, применение стилей
- сброс/удаление всех разрывы страниц. В FR настраивается их вывод, кстати
- изменение Стиля Таблицы, фон/рамки там точно можно задать, ширину - нет, но это задача плохо автоматизируема, т.к. все норовят ручные переносы слов всандолить (+FR), на них автоширина будет "неудачной"

Макросы нужно просто писать, понимание придет потом.

Sub Tables
oTextTables = ThisComponent.getTextTables()
oObj1 = oTextTables.getByIndex(0)
' сюда вставить цикл перебора всех таблиц
ThisComponent.CurrentController.select(oObj1)
' сюда форматирование макрорекордером
end sub

 

Плагины, тем более такие сложные, поднимают до свежих версий только их авторы.


Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

sokol92

Цитата: economist от  4 февраля 2021, 16:46Макросы нужно просто писать, понимание придет потом
Придерживаюсь строго противоположной точки зрения. :)

Цитата: Smilik от  4 февраля 2021, 15:56
2. где брать достойную документацию по UNO?
Официальная документация на примере интерфейса TextTable.

"Вы будете смеяться", но для Вашего случая еще, похоже, методы UNO не написали. Тогда так:

Sub TestWriterTables
  Dim oTables, i As Long, oDisp, oFrame
  oDisp=createUnoService("com.sun.star.frame.DispatchHelper")
  oFrame=ThisComponent.CurrentController.Frame
  oDisp.executeDispatch(oFrame, ".uno:SelectTable", "", 0, Array())
  oTables=ThisComponent.TextTables
  For i=0 To oTables.Count-1
     oTables(i).BackColor=RGB(0,0,255) ' фон
     ThisComponent.CurrentController.select(oTables(i))
     oDisp.executeDispatch(oFrame, ".uno:SelectTable", "", 0, Array())
     oDisp.executeDispatch(oFrame, ".uno:SetOptimalColumnWidth", "", 0, Array())
     oDisp.executeDispatch(oFrame, ".uno:SetOptimalRowHeight", "", 0, Array())
  Next i
End Sub

Владимир.

Smilik

#7
economist, sokol92 - СПАСИБО!


economist,
знаю про ФР. но... (ФР 12, лицензионный ) Всё равно "выдаёт" рарывы страниц, хотя галочка отмены стоит.
К тому же на книгах со сложным форматированием и высоким разрешением скана таблиц много выходит.
Вручную - замучиццо. даже с шорткатом на маленький макросик.
А по-поводу сложного макроса... с одной стороны - да. а с другой... там скорее всего дело в версии Питона и достаточно "пару заголовков" подправить. макрос написан для ОО3.5..4.1 нормально работает в ЛО 5.2.7, но уже слетает графическое оформление.
Если оформление отменить в опциях - всё нормально работает.
В следующих версиях расширение проходит установку, но не выдает функционал, следовательно дело в каких-то отдельных сслылках.
Так что предполагаю, что "поднять версию" более чем доступно. Но для профи в Питоне и ЛО. А не для меня.

макрос от sokol92 РАБОТАЕТ
И мне до такого решения - ещё было бы долгого полета (если вообще да)

Цитата: sokol92 от  4 февраля 2021, 18:26"Вы будете смеяться", но для Вашего случая еще, похоже, методы UNO не написали. Тогда так:
ОНО ТАКИ РАБОТАЕТ! Спасибо, Владимир

В приложении - команды UNO:   полученные макросом из документа Питоньяка.

sokol92

Здесь я выкладывал актуальный список команд "Диспетчера" с описанием аргументов. Обновлю, когда появится документация по версии 7.
Владимир.

Smilik

#9
Цитата: sokol92 от  4 февраля 2021, 19:38актуальный список команд "Диспетчера"
Владимир, если удобно может быть опишите общий алгоритм /принципы решения задачи написания макроса?
Например, как сориентироваться документации, как построить проект наследования, иерархию объектов и вызовов

Вопрос: с чего начинать и как решать.
например: как перейти
от  dispatcher.executeDispatch()
к   oDisp.executeDispatch()
Это следует из концепции ООП в приложении к ЛО или специфически из ОО/ЛО ?

Когда начинал разработку кода, набросал обыкновенный каркас:

Sub Main()
   TableFind   ()            //TODO:
   TableSelect ()           //TODO:
   TableSizeOptimal ()   //TODO:
End Sub
'---------------------------------------------------------------------------------
REM inicialisation code: 1) set variables -> 2) activate access
REM 1. code to access document
   dim document as object
         document = ThisComponent.CurrentController.Frame
REM 2.  code to use the dispatcher
   dim dispatcher as object
         dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
REM 3. The Work:
REM 3.1. set / activate local variables
 Dim oTables  'All of the text tables
     oTables = ThisComponent.TextTables  REM First, access the tables based on index.
 Dim i%         'Index variable

REM 3.2 TableObject
REM 2. prepare values
   For i = 0 To oTables.getCount() - 1
REM 3.3 Run preparational
rem //: find the table: put the cursor in the first cell or //TODO: get form books
REM 3.4. do the main
rem select the table // TODO: get from ...


И вот в какой последовательности дальше искать ...

И ещё вопрос: похоже, объявить и инициализировать переменную можно в любом месте кода перед использованием.
Тогда было бы удобно (на этапе изучения basic )держать в заготовке куски типа
dim dispatcher as object
     dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

И вставлять их в код по-мере надобности.

sokol92

Цитата: Smilik от  6 февраля 2021, 01:46Владимир, если удобно может быть опишите общий алгоритм /принципы решения задачи написания макроса?
Например, как сориентироваться документации, как построить проект наследования, иерархию объектов и вызовов

Я не так давно задавался подобными вопросами. :)  Будем ждать, пока появится новый писатель с талантом А.Питоньяка (либо Питоньяк продолжит свою подвижническую деятельность).

Цитата: Smilik от  6 февраля 2021, 01:46И ещё вопрос: похоже, объявить и инициализировать переменную можно в любом месте кода перед использованием.

Нет "канонического" стиля. Я, например, предпочитаю все описания делать в начале макроса (рудимент из других языков программирования). Главное сделать так, чтобы Вы сами и Ваши последователи через 5 и более лет могли быстро просмотреть и понять код. :)
Владимир.

economist

Так как автодополнения и IntelliSense в IDE мы лишены - произошла логичная замена
dispatcher -> oDisp, sheet - oSh итд. Какого-то соглашения по именам переменных я не видел, но
префиксы i/f/n s o a - для чисел, строк, объектов и массивов выглядят логично и встречаются в лит-ре с 90-х гг.

Объявлять ли переменные заранее, и объявлять ли вообще - дело личное.

API у OOLO такой сложный, что все знакомые мне шкодеры в основном "пишут копипастой", т.к. MRI/X-RAY неосилили после привычки к F2 в VBA IDE.   


Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Smilik

#12
Простите, economist, не до конца понял:
i - interface?
f - function?
n - ?????
s - string?
o - object?
a - array?

В таком случае, если это уместный вопрос / просьба: то, чего в готовом виде нет в книгах Питоньяка:
Составить каталог сниппетов - шаблоны
1. перебора всех абзацев, таблиц, графических объектов, картинок, фреймов.
2. перебора абзацев-
без-таблиц,
без-граф.объ.,
без-картинок,
без-фреймов
3. образцы обращения к объектам по-имени и по индексу
4. обращения к свойствам объектов через API i dispather,
5. переделки комманд из записанных диспетчером в диспетчер объекта (это было в моем вопросе)
6. алгоритм "раскапывания" параметров вызова нужного метода/сервиса/объекта

И ещё "зубодробительный" вопрос: возможно ли улучшить скрипт Питоньяка по извлечению имен методов, до состояния извлечения не только имен, но и деклараций методов?

Похожий альтернативны вариант: макрос, для просмотра всех свойств элемента текста: символа, абзаца (объекта), страницы...

Например, мне надо в большом тексте удалить всё лишнее форматирование, но сохранить выделения форматом шрифта (BIU).
Т.е. удалить прямое форматирование, цвет фона и выделений, разрывы страниц, колонок, секции, фреймы переделать в обычный текст, картинки привязать как символ, и т.п.

По идее - нужны заготовки-"сниппеты":
1. макрос-сборщик всех стилей из документа
2. описание значений для собранных свойств
3. цикл с перебором всех объектов заданного типа
4. способ установления и "вставки" нужных значений в заготовку цикла.






eeigor

#13
Стандартов нет, но есть традиции. С трудом отвязался от Венгерской нотации именования объектов.
Объявляю переменные в начале, но считаю разумным – по мере использования: например переменную цикла i лучше объявить непосредственно перед самым циклом.

Для целых чисел можно использовать общий префикс n (number), а не i (integer), l (long); с префиксом f (float: single, double) не знаю как быть: для меня это "битовый флаг"; префикс a – для UNO структур, тогда для массивов оставлять свой тип данных и добавлять пару скобок: nValues(), окончание s тоже свидетельствует о мн. ч.

Использование для пользовательских процедур префиксов типа fnName, subName считаю излишним и «некрасивым». Я с этой целью для ясности использую оператор Call.

upd1:
Автор темы, видимо, не использует инспектор объектов, например XRay. Всё не так плохо.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

Smilik

#14
Цитата: eeigor от  6 февраля 2021, 17:49Автор темы, видимо, не использует инспектор объектов, например XRay.
Нет так плохо ? по сравнению с чем?
у себя использую:
v - var
fnc  -function
prc - procedure
mth - method
prp  - property
o/obj - object
In, Ln, Fl, St,
Получается: функция, возвращающая целое:
fncIn_FunctionName()....

X-Ray - надо осваивать. Понимать бы конкретно как правильно установить... уже было бы классно.... подскажете?