[Решено]Writer: проход по всем параграфам.

Автор Massaraksh7, 22 мая 2024, 11:35

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

Massaraksh7

Когда я пишу такой код:
Sub Main
ParaEnum = ThisComponent.Text.createEnumeration
While ParaEnum.hasMoreElements()
  Para = ParaEnum.nextElement()
  if Para.supportsService("com.sun.star.text.Paragraph") Then Para.String = "a" & Para.String
Wend
End Sub
я получаю проход по параграфам, исключая параграфы внутри таблиц. Есть ли возможность сделать, чтобы эти параграфы включались?
DOM-модель, во всяком случае, это позволяет, неужели здесь нет?
Doc:=DocContent.getElementsByTagName('text:p');     //---Поиск параграфа
for i:=0 to Doc.Length-1 do                         //---Проход по параграфам
   begin
   Chl:=Doc.Item[i].ChildNodes;
   s:=Doc.Item[i].TextContent;
...............
   end;
end;

mikekaganski

Цитата: Massaraksh7 от 22 мая 2024, 11:35DOM-модель, во всяком случае, это позволяет

При чём здесь DOM из XML? Объектная модель Writer никакого отношения к XML не имеет.

Посмотрите код https://extensions.libreoffice.org/en/extensions/show/formatting-of-all-math-formulas. Там есть проход по всему.
С уважением,
Михаил Каганский

Massaraksh7

Цитата: mikekaganski от 22 мая 2024, 11:48При чём здесь DOM из XML?
При том, что на DOM я работу с LOW уже реализовал. А сейчас колеблюсь - то ли этим и пользоваться, то ли, унификации ради, тоже перейти на макросы.

mikekaganski

Цитата: Massaraksh7 от 22 мая 2024, 12:02DOM я работу с LOW уже реализовал

:) Это Вы не с "LOW" работу реализовали, а с ODF. Ну да ладно. Точность формулировок - не главное для разработчика ;)
С уважением,
Михаил Каганский

Massaraksh7

Посмотрел. Не знаю пока. Думать буду.

Massaraksh7

#5
Ну, примерно, вот так получилось.
Sub Main
ParaEnum = ThisComponent.Text.createEnumeration
While ParaEnum.hasMoreElements()
  Para = ParaEnum.nextElement()
  if Para.supportsService("com.sun.star.text.Paragraph") Then  Para.String = "a" & Para.String 
  if Para.supportsService("com.sun.star.text.TextTable") Then
     count = UBound(Para.cellNames)
      for i = 0 to count
        Cell = Para.getCellByName(Para.cellNames(i))
        if not IsNULL(Cell) then
           ParaCellEnum = Cell.Text.createEnumeration
           while ParaCellEnum.hasMoreElements()
              ParaCell = ParaCellEnum.nextElement()
              ParaCell.String = "b" & ParaCell.String
           wend
        end if
     next i   
  end if
Wend
End Sub
Ещё подумаю.

mikekaganski

#6
Проверьте ещё варианты с таблицами, вложенными в таблицы. И ещё проверьте работу с фреймами (и там с таблицами, в т.ч. вложенными).

Обратите внимание, что Ваш код вне таблиц обрабатывает каждый абзац отдельно. А в ячейках работает только с одним абзацем.
С уважением,
Михаил Каганский

Massaraksh7

Цитата: mikekaganski от 22 мая 2024, 14:40Проверьте ещё варианты с таблицами, вложенными в таблицы.
Вряд ли это в реальных макетах будет, но ради общего развития попробую.

Massaraksh7

Цитата: mikekaganski от 22 мая 2024, 14:40А в ячейках работает только с одним абзацем.
Спасибо, это я пропустил.

Massaraksh7

Цитата: mikekaganski от 22 мая 2024, 14:40А в ячейках работает только с одним абзацем.
Поправил пост #5

sokol92

#10
Цитата: Massaraksh7 от 22 мая 2024, 15:45Поправил пост #5
Остались вложенные таблицы.  :)
У меня в аналогичной задаче используется рекурсивный вызов.

Вот шапка сервисной функции, которая вызывается при обработке Selection для текстового документа или документа электронной таблицы.
Когда-нибудь подготовлю к публикации.

' lang:ru
' Разбивает объект obj на более мелкие объекты, поддерживающие интерфейс TextRange (до параграфа).
' Для найденных фрагментов вызывается ProcessPar.
' - obj        объект. Текстовый документ, текстовая таблица (вложенность допускается), параграф.
' - bStatus    признак формирования строки статуса (о ходе выполнения).
' - rangeName  задает для текстовой таблицы диапазон обрабатываемых ячеек.
'              Может содержать имя ячейки или имена первой и последней ячейки диапазона
'              через двоеточие (как в функции getRangeName интерфейса XTextTableCursor). 
Sub SplitObj(ByVal obj As Object, Optional ByVal bStatus as Boolean, Optional ByVal rangeName As String)

Работает быстро - проверял на книгах Л.Н.Толстого "Война и мир" и Книгах Питоньяка.  ;)
Владимир.