Меня попросили написать статью по поводу известной проблемы с паразитными названиями перекрёстных ссылок в тексте документа MS Word, а именно, когда вы вставляете в текст документа перекрёстную ссылку (меню ссылки/перекрёстная ссылка) Word позволяет вставить либо название типа "Рисунок ..." либо название полностью, что приводит к текстам типа "...на рисунке (Рисунок 10) мы видим..." или ещё более нелепым конструкциям, тогда как согласно ГОСТ, необходимо оставлять только номер "...на рисунке 10 мы видим...".

Эту проблему просто решить с помощью небольшого скрипта VBA.

Код перекрёстной ссылки (его можно посмотреть, переключая режимы просмотра "shift + f9") выглядит примерно так { REF _Ref127884797 \h } Для того, чтобы убрать паразитные названия и оставить только номер необходимо добавить в код ключ "\#0". При этом надо следить чтобы случайно не вставлялись лишние ключи (это приведёт к ошибкам) и корректно переключать отображение перекрёстной ссылки из вида "текст" в "код" и обратно.

Ниже приведён код, который это делает.

Sub PerSsylkiGost()

Dim I As Long, DlStroki As Long, LinkText$
    'Перебираем все поля типа ссылки
    For I = 1 To ActiveDocument.Fields.Count
           'Выбираем из них перекрёстные ссылки и выделяем их
        If ActiveDocument.Fields.Item(I).Type = wdFieldRef Then
            ActiveDocument.Fields.Item(I).Select
            
            With Selection
                
                LinkText = .Text
'   MsgBox Mid(LinkText, 2, 4)
                 'Проверка на корректность открытия кода ссылки, т.к. в тексте могут
           'присутствовать п.ссылки в виде кода и текста
           'приводим п.ссылку к виду "код"
                If Len(LinkText) < 4 Then
                    .Fields.ToggleShowCodes
                Else
                    If Mid(LinkText, 2, 4) = "Ref " Or Mid(LinkText, 2, 4) = " Ref" _
                    Or Mid(LinkText, 2, 4) = "REF " Or Mid(LinkText, 2, 4) = " REF" Then
                    Else
                        .Fields.ToggleShowCodes
                    End If
                End If
                
                .Find.ClearFormatting
                .Find.Replacement.ClearFormatting
                  'содержаение кода п.ссылки передаём переменной и обрезаем её с краёв  
                 LinkText = .Text
                 DlStroki = Len(LinkText)
                 LinkText = Mid(LinkText, 2, DlStroki - 2)
                 'Проверяем, не содержит ли уже п.ссылка нужный нам код - во избежание ошибок 
                If InStr(LinkText, "# 0") <> 0 Or InStr(LinkText, "#0") <> 0 Then
                Else
                    With .Find
                  'Если кода в п.ссылке нет, вставляем его   
                            .Text = LinkText
                            .Replacement.Text = LinkText & "\#0 "
                            .Forward = True
                            .Wrap = wdFindStop
                            .Format = False
                            .MatchCase = False
                            .MatchWholeWord = False
                            .MatchWildcards = False
                            .MatchSoundsLike = False
                            .MatchAllWordForms = False
                            .Execute Replace:=wdReplaceAll
    
                    End With
                 'Обновляем п.ссылки - приводим их к нормальному виду        
                .Fields.Update
                End If
            
            .Fields.Update
            End With

        End If
    
    Next I

End Sub

Казалось бы - очень простая задача, но почему-то Word не позволяет решить её стандартными средствами...

Дополнительные проверки на вид и содержание кода перекрёстных ссылок необходимы, т.к. часто бывает, что документ составлен из кусков других документов, в которых эти ссылки могут быть в разных состояниях.

Пользуйтесь :-) Удачи!

Комментарии (26)


  1. tsem13
    17.11.2023 18:40

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


    1. Kutush Автор
      17.11.2023 18:40
      +5

      Ну, гост призывает применять нормы русского языка при оформлении документов. Если не использовать данный подход, то по дефолту в word при использовании автообновляемых перекрёстных ссылок получаем конструкции типа "...посмотрите на рисунок Рисунок 15..." или "...это видно из рисунков Рисунок 12 - Рисунок 15..."

      Если вас (и вашего заказчика) это не смущает, то всё ок. А если всё-таки хочется чтобы текст читался гладко и не создавалось впечатления, что его писали какие-то безграмотные люди - то лучше использовать предложенный скрипт.

      К тому же я написал статью по просьбе одного из читателей, который в переписке как раз поднял эту проблему, и оказалось что у меня есть для него решение, которым я и делюсь со всеми. )


    1. starfair
      17.11.2023 18:40
      +1

      Тут проблема не в том, что подо что подгоняться должно, а в том, что долгое время вообще на этот вопрос забили, от слова совсем, потому и приходится колхозить на том что уже стало привычным, под отечественный реалии.
      Кстати говоря, я сейчас довольно глубоко погружён в тему импортозамещения в области офисных пакетов, и там так же идёт в большинстве своем просто копирование самого популярного офисного пакета. Тоже самое и в отечественных CAD системах. Требования ЕСКД там не зашитваются, а надстраиваются поверх. С одной стороны - понятно, если рассматриваешь свой продукт как продаваемый и за пределами страны, с другой, по идее приоритет внутреннего рынка должен быть.


      1. Surrogate
        17.11.2023 18:40

        Не могу оценить перспективы продаж за пределами страны, продуктов которые должны импортозамещать офисные пакеты…

        Делают громкие заявления:

        Нашей основной целью было заместить Microsoft с учётом возможности совместной работы в вебе и соответствием всех требований ГОСТа.

        (пруф)

        Но в камментах признают, что этого пока нет в реале…


        1. starfair
          17.11.2023 18:40

          Ну, может вы конечно не в курсе, но долгое время, отечественные разработчики вполне всего позиционировали свои продукты для продаж за границу (и делали это вполне успешно). Более того, до сих пор, часть ПО сперва создаётся под заграничных клиентов, и только потом обновы на отечественные ветки накатываются.


          1. Surrogate
            17.11.2023 18:40

            Действительно, я про такое слышу в первые…
            А каких конкретно разработчиков вы имеете в виду?


            1. Surrogate
              17.11.2023 18:40

              Хабро-статья из 2015 года Российский сервис «МойОфис» будет конкурировать с Microsoft Office и Google Docs

              К 2020 году компания хочет получить 25% отечественного рынка и выйти на рынки Европы и Латинской Америки.

              К 2020 году разработчики сервиса планируют получить долю в 20% на рынке Бразилии и Латинской Америки и до 10% на европейском рынке. За пределами России компания «МойОфис» будет предлагать свои продукты под другим брендом – MyOffice. Но пока 95% мирового рынка в сегменте офисных приложений принадлежит компании Microsoft.

              Интересно сколько из запланированного сбылось?


  1. Vcoderlab
    17.11.2023 18:40
    +1

    Очень интересно, как это можно сделать в LibreOffice.


    1. Kutush Автор
      17.11.2023 18:40

      А у VBA есть api для работы с LibreOffice? В принципе логика должна быть похожа, добавляем в код п.ссылки соотв. ключ.


      1. Surrogate
        17.11.2023 18:40

        В Либре есть свой встроенный аналог VBA (LibreOffice Basic), очень урезанный правда!

        Не помню есть ли там макро-рекордер

        Есть макро-рекордер.


        1. economist75
          17.11.2023 18:40
          +3

          В OpenOffice|LibreOffice - StarBasic, VBA (80% кода VBA выполняется сразу, можно смешивать код SB/VBA в одном модуле/процедуре и даже строке). Также поддерживаются макросы на Python, Java, JavaScript, C++. API доступен из любого ЯП, Макрорекордер кода SB менее функционален и тоже, как в MSO. плодит много мусорного кода.


    1. nerudo
      17.11.2023 18:40

      Я не знаю чо там в ворде но в либре пишется текст "рис. " и ставится номер в виде ссылки. Без всяких скриптов.


      1. Kutush Автор
        17.11.2023 18:40
        +1

        Открыл либру, попробовал - действительно, там такой проблемы нет - можно сразу вставить номер рисунка.


    1. Kutush Автор
      17.11.2023 18:40

      Вы имеете в виду это: если в Либре открыть сделанный в word файл *.docx и там будут перекрёстные ссылки с паразитными надписями, как можно их убрать все разом?

      Не готов ответить на этот вопрос, т.к. в Либрой знаком только шапочно, и что-то программировать в ней не пробовал...


    1. economist75
      17.11.2023 18:40
      +1

      OpenOffice|LibreOffice Writer по команде Вставка - Перекрестная ссылка - Рисунок - Вставить делает именно то что нужно в статье: вставляет номер рисунка (затененное серым поле). Затенение не печатается, может быть отключено.


  1. Kutush Автор
    17.11.2023 18:40
    +2

    Статья написана по просьбе читателя - значит задача востребована! )


  1. ginya
    17.11.2023 18:40
    +1

    Выделяем слово "рисунок" или "таблица" в перекрестной ссылке и жмём Ctrl+Shift+H. Не благодарите.


    1. Kutush Автор
      17.11.2023 18:40

      Открыл установленный на этом компе (на котором я счас пишу комент) word 2016, подгрузил документ с п.ссылками, сделал так как написано в комментарии ниже и ...ничего не произошло...

      Даже если бы этот способ работал, дополнительно надо учитывать, что скрипты пишутся для того, чтобы решить проблему сразу для всего документа в целом. Представьте, у вас документ страниц на 400 в котором 500 рисунков и к ним 700 перекрёстных ссылок - это же сколько нужно времени чтобы каждую ссылку тыкнуть мышкой и нажать три клавиши... ) А если таких документов 15-20?... А с помощью скрипта можно эти все документы прогнать за минуту в автоматическом режиме.


      1. Kutush Автор
        17.11.2023 18:40

        хотел сказать - комментарий выше. Нажимал Ctrl+Shift+H в различных раскладках, выделял строку, содержащую п.ссылку, саму перекрёстную ссылку, отдельно название "Рисунок" - ничего не меняется. Счас попробовал с ноутбука под win7 - результат тот же.


        1. sabaca
          17.11.2023 18:40

          Это делает текст не видимым, он подчеркивается пунктиром в режиме отображения всех символов и не отображается при печати. Это известный способ решения этой проблемы в Word и не только этой. Но способ так себе. Кстати, а как там в Word2016 c библиографией, все также нет шаблона для оформления её по ГОСТ?


          1. Surrogate
            17.11.2023 18:40
            +1

            как там в Word2016 c библиографией, все также нет шаблона для оформления её по ГОСТ?

            А что должен быть такой шаблон в Word из коробки?


  1. aborouhin
    17.11.2023 18:40
    +1

    Макрос ломает как минимум перекрёстные ссылки на рисунки, в которых надо отображать и номер, и название рисунка ("см. Рисунок 1. КДПВ" тоже превращается в "см. 1") Да и исключать, что кто-то хочет именно "см. Рисунок 1", где "Рисунок" подставляется в составе поля, тоже нельзя, Вы же сами пишете про документы из кусков разного происхождения.

    Так что, IMHO, не надо ломать существующий функционал, лучше добавить новый. Скажем, пройтись по всем подписям к рисункам и вдобавок к трём (!) скрытым закладкам, которые в каждой из них проставляет Word (на всю подпись, на часть "рисунок Х" и на часть с названием рисунка), добавить свою четвёртую - только на номер. Ну и сделать макрос, который обновляет эти закладки по всему документу и вставляет ссылку на нужную.


    1. Kutush Автор
      17.11.2023 18:40

      Да, если текст уже адаптирован таким образом, чтобы замаскировать эту особенность ворда, тогда да, после использования скрипта стоит пробежаться поиском по таким местам и исправить. А если делать текст изначально имея в виду, что у тебя подобный скрипт есть, то результаты будут лучше. ) Пользуйтесь, если вам нужно )


  1. NutsUnderline
    17.11.2023 18:40

    голосом Миронова "MS office - это не актуально"... что насчет R7 и прочих новых office?


  1. kot_behemot
    17.11.2023 18:40

    Всю жизнь использовал наименование рисунка - рис. 5.1. В тексте вставлял "смотреть рис. 5.1"


  1. ab86
    17.11.2023 18:40
    +1

    Интересный способ, но, к сожалению, он работает только если нумерация рисунков сквозная: 1, 2, 3 и т.д. А если нумерация в пределах раздела, то результат неверный выдает, например ссылку на Рисунок 1.1 выдает как "2".

    Чтобы сделать перекрестные ссылки в Word удобными для использования, нужен пользовательский диалог "Перекрестные ссылки", который будет автоматически переопределять границы закладок. Т.е. стандартная команда Word VBA вставляет закладку на "Рисунок X.X", а затем другие макросы сразу же двигают левую границу этой закладки вплотную к номеру, так чтобы закладка была на "X.X". Готовый шаблон с макросами есть в интернете. Ссылку не даю, т.к. это будет наполовину рекламой. (Найти этот шаблон сложно, но можно, если читать форумы по теме перекрестных ссылок Word).