Разорвать, удалить нумерацию рисунков и таблиц

Автор d.taras, 16 июля 2026, 20:48

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

d.taras

Доброго времени!
Есть несколько документов, с автоматически созданной нумерацией рисунков и таблиц (через Нумерация заголовков и вставить название). Есть ли способ автоматизации ее отключения? Несколько документов нужно объединить в один финальный файл, а рисунков и таблиц очень много и структуру нумерации надобно сохранить.

Helen

Здравствуйте.
Не очень понятно, почему Вы хотите сначала отключать нумерацию, при том, что в итоге её "надобно сохранить".
Если структура нумерации создана автоматически, разве она не подстроится при объединении нескольких Ваших файлов в один?

Ципихович Эндрю

Цитата: Helen от 17 июля 2026, 06:17Не очень понятно
присоединяюсь..... и варианты с макросами предлагать?

d.taras

Упс... Ответ исчез...
В документах (диссертациях) используется несколько подходов к нумерации. В разделах цифровая типа рис.2.1 (раздел 2 рис. 1), а в приложениях буквенная -- приложение А и рис. А.1. Созданные по отдельности файлы имеют правильную нумерацию, но при объединении в один, общий файл она сбивается. По-видимому, это связано с реализацией счетчика. Инструмент нумерация заголовков работает со стилем "Заголовок" и, соответственно, Приложения, введения и т.п. нумеруются. Если не использовать стиль "Заголовок", то и нумерации нет. Для этого и надо превратить счетчик нумерации в обычный текст для формирования сводного документа. Если нет штатной процедуры, то можно и макросом попробовать решить.

sokol92

Владимир.

McAaron

Цитата: d.taras от 17 июля 2026, 13:06В документах (диссертациях) используется несколько подходов к нумерации...
В пояснительных записках и программной документации тоже. Я пытался делать несколько стилей заголовков для разных частей документа -- их можно настроить, чтобы они по разному выходили в содержание, либо не выходили вообще, но с приложениями не получилось. Например, на странице должно быть в две строки:

Приложение А
Название приложения А

а в содержание заголовок должен выходить без слова "Приложение":

Приложения:
А Название приложения А . . . . 123
Б Название приложения Б . . . . 234

В результате, если не удается "переубедить" нормоконтроль, релиз делаю в latex'е -- руками содержание править опасно -- инозаказчик "яйцен клац-клац".
На мой неискушенный взгляд во writer'е не хватает возможности указать конкретно, как должен заголовок выходить в тексте и как в содержание.

economist

Во Writer есть все необходимое для оглавлений.

Вы можете сделать три стиля одинакового размера, но разного цвета (невидимые) и решить что войдёт в Оглавление (там свой стиль, можно менять цвет). Один из 3-х стилей м.б. и вовсе не заголовком.
Пить не буду коньяка - читану Питоньяка!

d.taras

Цитата: economist от 18 июля 2026, 13:23Вы можете сделать три стиля одинакового размера,
Можно. Но это не решает задачу автоматической нумерации рисунков как рис.2.3.
Возвращаясь к вопросу. Помучив ии, написали скрипт, который удаляет автоматически созданную нумерацию, оставляя только текст. Действие безвозвратное.
' =====================================================================
' Макрос: ConvertCaptionFieldsToText (финальная версия)
' Найденный тип поля в документе: com.sun.star.text.TextField.SetExpression
' (Number range / Sequence реализован через SetExpression с подтипом
'  "Sequence" - отсюда и путаница с именем сервиса).
'
' ПЕРЕД ЗАПУСКОМ:
'   - Сделайте резервную копию файла! Действие необратимо.
'   - Обновите поля: Ctrl+A -> F9.
' =====================================================================

Sub ConvertCaptionFieldsToText_Final
    Dim oDoc As Object
    Dim aFields(1000) As Object
    Dim nFieldCount As Integer
    Dim i As Integer

    ' Оставьте "" чтобы обработать ВСЕ подписи (и таблицы, и рисунки).
    ' Если нужно только рисунки - впишите точное имя категории, например "Рисунок"
    Dim FILTER_CATEGORY As String
    FILTER_CATEGORY = ""

    oDoc = ThisComponent
    oDoc.getTextFields().refresh()

    nFieldCount = 0

    ' ---------- ПРОХОД 1: собираем поля, ничего не меняя ----------
    CollectSetExpressionFields(oDoc.getText(), FILTER_CATEGORY, aFields, nFieldCount)

    Dim oFrames As Object
    oFrames = oDoc.getTextFrames()
    For i = 0 To oFrames.Count - 1
        CollectSetExpressionFields(oFrames.getByIndex(i).getText(), FILTER_CATEGORY, aFields, nFieldCount)
    Next i

    Dim oTables As Object, oTable As Object, oCellNames() As String, j As Integer
    oTables = oDoc.getTextTables()
    For i = 0 To oTables.Count - 1
        oTable = oTables.getByIndex(i)
        oCellNames = oTable.getCellNames()
        For j = LBound(oCellNames) To UBound(oCellNames)
            CollectSetExpressionFields(oTable.getCellByName(oCellNames(j)).getText(), FILTER_CATEGORY, aFields, nFieldCount)
        Next j
    Next i

    If nFieldCount = 0 Then
        MsgBox "Поля не найдены (0)."
        Exit Sub
    End If

    ' Подтверждение перед необратимым действием
    Dim iAnswer As Integer
    iAnswer = MsgBox("Найдено полей для преобразования: " & nFieldCount & Chr(10) & _
                      "Действие НЕОБРАТИМО (поля станут обычным текстом)." & Chr(10) & _
                      "Убедитесь, что сделали резервную копию файла." & Chr(10) & Chr(10) & _
                      "Продолжить?", 4 + 48, "Подтверждение")
    If iAnswer = 7 Then ' 7 = Нет
        Exit Sub
    End If

    ' ---------- ПРОХОД 2: заменяем собранные поля на текст ----------
    Dim oField As Object
    Dim oAnchor As Object
    Dim sPresentation As String
    Dim nDone As Integer
    nDone = 0

    For i = 0 To nFieldCount - 1
        oField = aFields(i)
        On Error Resume Next
        oAnchor = oField.getAnchor()
        sPresentation = oField.getPresentation(False)
        If Not IsNull(oAnchor) Then
            oAnchor.getText().insertString(oAnchor, sPresentation, True)
            nDone = nDone + 1
        End If
        On Error Goto 0
    Next i

    MsgBox "Найдено полей: " & nFieldCount & Chr(10) & "Успешно заменено: " & nDone
End Sub


Sub CollectSetExpressionFields(oText As Object, sFilterCategory As String, aFields() As Object, ByRef nFieldCount As Integer)
    Dim oEnum As Object, oPar As Object
    Dim oPortionEnum As Object, oPortion As Object
    Dim oField As Object
    Dim aServices() As String
    Dim k As Integer
    Dim bIsSetExpr As Boolean
    Dim sSeqName As String

    oEnum = oText.createEnumeration()

    Do While oEnum.hasMoreElements()
        oPar = oEnum.nextElement()
        If oPar.supportsService("com.sun.star.text.Paragraph") Then
            oPortionEnum = oPar.createEnumeration()
            Do While oPortionEnum.hasMoreElements()
                oPortion = oPortionEnum.nextElement()
                If oPortion.TextPortionType = "TextField" Then
                    oField = oPortion.TextField

                    bIsSetExpr = False
                    aServices = oField.SupportedServiceNames()
                    For k = LBound(aServices) To UBound(aServices)
                        If InStr(aServices(k), "SetExpression") > 0 Then bIsSetExpr = True
                    Next k

                    If bIsSetExpr Then
                        sSeqName = ""
                        On Error Resume Next
                        sSeqName = oField.SequenceName
                        If sSeqName = "" Then sSeqName = oField.Content ' на случай другого имени свойства для категории
                        On Error Goto 0

                        If sFilterCategory = "" Or InStr(sSeqName, sFilterCategory) > 0 Then
                            If nFieldCount > UBound(aFields) Then
                                ReDim Preserve aFields(UBound(aFields) + 500)
                            End If
                            aFields(nFieldCount) = oField
                            nFieldCount = nFieldCount + 1
                        End If
                    End If
                End If
            Loop
        End If
    Loop
End Sub

sokol92

Могу только повторить - без тестовых файлов трудно дать какие-либо рекомендации.
Владимир.

d.taras

Цитата: sokol92 от 19 июля 2026, 14:54Могу только повторить - без тестовых файлов трудно дать какие-либо рекомендации.
Фай через ссылку передать, али как?

sokol92

Загрузите сюда, на форум.
Оставьте только фрагменты файла (или файлов, если проблема возникает при объединении), демонстрирующие проблему(ы), и опишите проблему(ы).

В интерфейсе форума кнопки для загрузки появляются после нажатия кнопки "ПРОСМОТР".
Владимир.

d.taras

Пробую отправить.
Повторюсь. Надо превратить нумерацию в обычный текст без потерь в форматировании остального текста.

sokol92

Цитата: d.taras от 16 июля 2026, 20:48Несколько документов нужно объединить в один финальный файл, а рисунков и таблиц очень много и структуру нумерации надобно сохранить.
На примере это не понятно.
Если удалим поля для нумерации, то как потом мы пронумеруем объединенный документ?
Владимир.

sokol92

Если речь идет о замене полей нумерации документа на их значения,то вот более понятный макрос (Google AI при моем управлении).


Sub ConvertFieldsToTextReverse
    Dim oDoc As Object
    Dim oFields As Object
    Dim oField As Object
    Dim oAnchor As Object
    Dim count As Long
    Dim maxIndex As Long
    Dim i As Long
    Dim sText As String
    Dim tempArray() As Object

    oDoc = ThisComponent
    oFields = oDoc.getTextFields()
   
    maxIndex = 128
    ReDim tempArray(maxIndex)
   
    For Each oField In oFields
        If oField.supportsService("com.sun.star.text.textfield.SetExpression") Then
            If count > maxIndex Then
                maxIndex = maxIndex * 2
                ReDim Preserve tempArray(maxIndex)
            End If
            tempArray(count) = oField
            count = count + 1
        End If
    Next oField
   
    If count > 0 Then
        For i = (count - 1) To 0 Step -1
            oField = tempArray(i)
            oAnchor = oField.getAnchor()
            sText = oField.getPresentation(False)
            oAnchor.setString(sText)
        Next i
    End If
   
    MsgBox "Готово! Успешно заменено полей: " & count, 64, "Результат"
End Sub
Владимир.

d.taras

Цитата: sokol92 от 19 июля 2026, 15:39Если удалим поля для нумерации, то как потом мы пронумеруем объединенный документ
А зачем? При разрыве файл имеет правильную нумерацию таблиц и рисунков (дисер например) в рамках разделов. Создаем  объединенный документ, содержание и отдаем старшим товарищам. При этом отдельные файлы остаются с автонумерацией для работы и корректировки. Если бы не требования по использованию нескольких стилей нумерации в оф.документах, то и вопроса не было...