Перевод кода и метаданных конфигурации на английский язык с помощью плагина EDT: Language Tool

Публикация № 1192449

Разработка - Инструментарий разработчика - EDT

EDT LanguageTool РегулярныеВыражения

Использование регулярных выражений для парсинга .mdo-файлов и составления русско-английского словаря метаданных. Перевод кода и метаданных конфигурации по словарю с помощью нового инструмента 1С - плагина EDT: Language Tool на примере УНФ 1.6

 

Введение

1C:Language Tool – это официальный плагин для среды разработки 1C:EDT, который предназначен для автоматизации перевода интерфейса на дополнительные языки, а также исходного кода и метаданных конфигураций на платформе "1С:Предприятие 8" на альтернативный язык, например с русского на английский. Инструмент предназначен для решения следующих задач:

  • Синхронный выпуск конфигурации на исходном языке кода и метаданных и конфигурации с кодом и метаданными, переведенными на другой язык, например, конфигурации на русском языке кода и метаданных и той же конфигурации на английском языке.
  • Автоматизация разработки конфигураций с интерфейсом на нескольких языках. Эта задача может решаться как одной командой разработчиков, так и с привлечением внешних команд для перевода интерфейса.
  • Разработка локализованных версий конфигурации внедряющим партнером на национальном рынке на основе международной или другой национальной поставки.

На портале ИТС доступен вебинар посвященный Language Tool: Дмитрий Мармышев, занимающийся разработкой этого инструмента, достаточно подробно рассказывает про возможности и сценарии использования плагина.

Итак, плагин EDT Language tool позволяет выполнять перевод метаданных конфигурации по словарю. Например, используем следующий словарь:

#Translations for: common

АктВыполненныхРабот=AcceptanceCertificate

После перевода конфигурации лексема "АктВыполненныхРабот" будет заменена на "AcceptanceCertificate". То есть будет переименован документ, соответственно изменены все обращения к нему, имена переменных и т.д.

Дополнительно, Language tool умеет менять язык скрипта с русского на английский (или обратно):


А значит, если составить словарь для метаданных, плагин выполнит автоматический перевод модели конфигурации. Плюс можно одновременно переключить встроенный язык платформы с русского на английский.

Концепция

В 1C Vietnam мы ведём разработку нескольких типовых конфигураций для Вьетнамского рынка. Почти все они представляют собой локализованные версии российских типовых конфигураций.
Один из продуктов - конфигурация Company Management (cокращённо CM), разработанная на основе 1С:УНФ 1.4 и полностью переведённая на английский язык, включая код и метаданные.

При переносе функционала из современных редакций УНФ в Company management, помимо различий в структуре конфигураций, дополнительную сложность вызывает отличие в языках конфигураций. И большой объём работы связан с переводом русского кода и метаданных УНФ на английский язык.

Объём этой работы можно существенно сократить, если перед переносом функционала предварительно перевести модель УНФ на английский язык. Причём выполнить перевод необходимо сохранив уже использованные в Company management термины. Например Касса перевести не как Cash или Cashbox, а как PettyCash потому что в СМ использован этот вариант перевода.

Далее, имея актуальную редакцию УНФ с именами метаданных из Company management, можем с помощью Language tool перенести контекстные переводы (сообщения, элементы форм и прочее).

Можно ли "перенести" перевод из СМ в актуальную редакцию УНФ?

Имеем конфигурацию с английским кодом и английскими метаданными. Она разработана на основе русской УНФ. Если выполнить сопоставление объектов двух конфигураций, получим англо-русский словарь для перевода метаданных. В качестве ключа сопоставления будем использовать внутренний uuid объектов.

Проверим соответствие uuid объектов с помощью сравнения конфигураций:


Как видим, у части совпадающих реквизитов uuid сохранился, а значит их имена пойдут в словарь. А например реквизит Country (Страна) был перенесён в Company management копированием, и его uuid отличается.

 

Техническая реализация

Для воплощения идеи в жизнь выполним следующие шаги:

  1. Составление словаря
  2. Нормализация словаря
  3. Перевод модели конфигурации по словарю

Рассмотрим подробно выполнение каждого этапа.

1. Составление словаря

В проекте EDT конфигурация 1С хранится в виде набора файлов, содержащих все свойства и идентификаторы объектов. Для сопоставления метаданных двух конфигураций получим необходимые сведения из этих файлов с помощью регулярных выражений.

Обратимся к файлу Банки.mdo. В файле хранится описание справочника Банки со всеми его свойствами, реквизитами, формами и прочим.


Из этого файла нас интересуют соответствия uuid - имя.

  • Чтобы собрать такие соответствия по всем объектам конфигурации, воспользуемся регулярным выражением:
    grep -Przo --include=\*.mdo '(?s)uuid=".*?"\>.*?\<name\>.*?\<\/name\>\s\n'
    Параметры:
    -P При интерпретации шаблона использовать дополнительный функционал Perl-скриптов
    -r Искать рекурсивно в папке, из которой запущена прогррамма
    -z Обрабатывайте входящие данные как набор строк, каждая из которых заканчивается нулевым байтом (символ ASCII NUL) вместо символа новой строки
    -o Выводить только совпадающий фрагмент

    В результате получим все блоки текста между uuid и тегом name:

    Банки.mdo:uuid="43c06b08-f3da-4568-a211-e6d049e6c2d7">
      <producedTypes>
        <objectType typeId="638db711-3193-4c8e-90be-e3fecbbd1c4f" valueTypeId="2b895d8f-87c4-4b55-9887-f3089d777497"/>
        <refType typeId="23d1dac7-246c-409d-ac52-03c2b847f959" valueTypeId="7e29e0a3-9091-4240-b87b-c2ec52ea6ae8"/>
        <selectionType typeId="f60daf78-b42c-46cd-8eb4-9647218a113a" valueTypeId="9cb122d4-f043-4fb0-845c-cee4fe4e375c"/>
        <listType typeId="11f9ca2d-613b-4297-95d4-04eec40d8016" valueTypeId="c9b95c6e-b2b8-44e6-87b8-b1dd7191c4d1"/>
        <managerType typeId="849bdce4-cacd-4d1b-b61f-1f242657a85a" valueTypeId="25c977ba-f402-445a-80bd-a9d0e18ec864"/>
      </producedTypes>
      <name>Банки</name>
    Банки.mdo:uuid="4a11d434-d753-49c6-b402-697eee429f34">
        <name>КоррСчет</name>
    Банки.mdo:uuid="2696a53a-2455-4a0b-bc79-b0eaa0734165">
        <name>Город</name>
    Банки.mdo:uuid="7c7741be-fa4d-4665-a05c-d71a3338dc21">
        <name>Страна</name>
    Банки.mdo:uuid="9e4f4597-380d-41b5-980d-b4ea881ffe08">
        <name>ФормаЭлемента</name>
    Банки.mdo:uuid="25b39760-a17c-40d2-b5ae-49936c78ebc3">
        <name>ФормаВыбора</name>
  • Удалим лишний текст с помощью регулярного выражения
    perl -0pe 's|(?s).*?uuid="(.*?)">.*?<name>(.*?)<\/name>|\1 \2|g'
    Команда perl в данном случае работает аналогично команде sed: поиск и замена фрагментов текста по шаблону. Но с помощью sed мне не удалось добиться замены многострочных фрагментов.

    На выходе получим:

    43c06b08-f3da-4568-a211-e6d049e6c2d7 Банки
    4a11d434-d753-49c6-b402-697eee429f34 КоррСчет
    2696a53a-2455-4a0b-bc79-b0eaa0734165 Город
    ba5226c3-2e58-4190-95f4-00d4244f5a9e Адрес
    3ec69c99-c530-4738-9cf3-f66fe89c6cd7 Телефоны
    9431f164-17e1-4dce-893e-86ddb56d248d РучноеИзменение
    8768f640-afff-452f-82e5-9925a9060d6c СВИФТБИК
    7c7741be-fa4d-4665-a05c-d71a3338dc21 Страна
    da439aff-54e8-476d-aebf-f7280718837b ФормаСписка
    36d95a22-4cfa-4468-b881-3d6d76a2a6ba ФормаГруппы
    e6866db9-ad0c-4568-a55d-9696ee37a862 ФормаВыбораГруппы
    9e4f4597-380d-41b5-980d-b4ea881ffe08 ФормаЭлемента
    25b39760-a17c-40d2-b5ae-49936c78ebc3 ФормаВыбора
    62a0f412-b215-4cd5-948b-266705660162 УдалитьКлассификаторБанков

То что нужно! uuid + имя.

  • Дополнительно обработаем результат с помощью команды sed 's/\x0//', чтобы избавиться от ненужных нам незначащих символов в начале и конце строк:
  • Соберём всё вместе (результат выводим в файл dict_ru.txt):
    grep -Przo --include=\*.mdo '(?s)uuid=".*?"\>.*?\<name\>.*?\<\/name\>\s\n' |  
    perl -0pe 's|(?s).*?uuid="(.*?)">.*?<name>(.*?)<\/name>|\1 \2|g' |  
    sed 's/\x0//' > dict_ru.txt
  • Аналогично сформируем dict_en.txt с уидами и английскими именами.

  • Теперь нужно соединить файлы dict_ru.txt и dict_en.txt по уиду и взять русское имя из первого файла, а соответствующее ему английское имя - из второго. Для этого используем команду join:
    join -o 1.2,2.2 <(sort dict_ru.txt) <(sort dict_en.txt)

    Результат:

    ФормаВыбора ChoiceForm    
    Город City  
    ФормаГруппы GroupForm  
    Телефоны PhoneNumbers  
    Банки Banks  
    КоррСчет CorrAccount  
    ФормаЭлемента ItemForm  
    Адрес Address  
    ФормаСписка ListForm  
    ФормаВыбораГруппы GroupChoiceForm  
2. Нормализация словаря

Словарь, собранный в первом шаге по метаданным справочника Банки, выглядит вполне пригодно для перевода конфигурации. Однако, если выполнить составление такого словаря по всей конфигурации, потребуется дополнительная обработка полученных данных.

Во-первых, нужно почистить дубли. Например, из каждого документа, в котором есть реквизит Автор, в словаре появится дополнительная строчка Автор=Author.
Во вторых, необходимо учесть ситуации, когда одна и та же русская лексема переведена на английский по-разному. Например слово Вид в основном переведено Kind, но кое-где как Type. Или слово Комментарий: почти везде переведено как Comment, но пару раз встречается вариант перевода Description, и так далее.

В словаре не должно быть подобных неоднозначностей, необходимо оставить только один вариант перевода для каждой лексемы. Правильно будет оставить тот вариант перевода, который используется чаще.

Для этого выполним следующие действия:

  • Подсчитаем сколько раз встречается каждый вариант перевода с помощью команд: sort | uniq -c
  • Упорядочим список по убыванию, самые часто используемые варианты перевода будут сверху списка: sort -r
  • Теперь удалим колонку с количеством использований вариантов перевода: sed -r 's/^\s*?[0-9]+ //'
  • Удалим дубли строк без изменения порядка строк. Для каждой лексемы останутся наиболее частотные варианты перевода: awk '!a[$1]++'
  • Упорядочим полученный словарь по алфавиту и выведем в файл dict_ru_en.txt: sort > dict_ru_en.txt

Всё вместе:

join -o 1.2,2.2 <(sort dict_ru.txt) <(sort dict_en.txt) |  
sort | uniq -c | sort -r |  
sed -r 's/^\s*?[0-9]+ //' | 
awk '!a[$1]++' | 
sort > dict_ru_en.txt

В итоге получаем практически готовый словарь:

АвтоматическиеСкидки=AutomaticDiscounts
Автор=Author
Адрес=Address
АдресЭлектроннойПочты=EmailAddress
АдресЭП=EmailAddress
АктВыполненныхРаботПрисоединенныеФайлы=AcceptanceCertificateAttachedFiles
АлгоритмПодписи=SignAlgorithm
АлгоритмХеширования=HashAlgorithm
АлгоритмШифрования=EncryptionAlgorithm
Артикул=SKU
БазовыйВидЦен=PricesBaseKind
БанковскиеСчета=BankAccounts
  • Проверим чтобы все имена объектов с префиксом Удалить при переводе имели префикс Delete. Таких объектов не очень много (40 строк), я сделал эту операцию вручную.

  • По-хорошему нужно выполнить ещё проверку совпадающих переводов: когда различные исходные лексемы имеют одинаковый перевод.
    Например:
    Покупатель=Customer и Заказчик=Customer
    Услуга=Service и Служебный=Service

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

    Я пока остановился на поиске дублей имён метаданных верхнего уровня. Часть ошибок исправлял непосредственно в переведённой конфигурации.

    Но вообще надо избавляться от образования дублей перевода - причесать словарь. Мы более подробно остановимся на этой работе во второй части статьи.

    Комментарий разработчиков плагина по поводу совпадающих переводов:

    [При дублировании имён] Например, параметры в СКД могут свернуться 2 в 1, поля структуры варианта отчетов, выбираемые поля запроса динамического списка и т.д. Практически в любой точке конфигурации может "выстрелить". И зачем?

    Пока идем по стратегии - что если на исходном языке слова разные - должны быть и в переводимом языке разные.

3. Анализ полученного словаря

Исходный словарь метаданных русской УНФ насчитывает 38 402 строк, из них уникальных - 19 691
Словарь Company management 11 846 строк, из них уникальных - 5 598

У нас получился русско-английский словарь, включающий 4 834 уникальные лексемы.
Количество переведённых строк исходного словаря УНФ 17 754, то есть 46%.

Процент покрытия будет выше, если использовать не УНФ 1.6, а УНФ 1.4, более родтсвенную нашей СМ. Плюс не нужно учитывать при подсчёте словари выброшенных подсистем, таких как ЕГАИС, ВЕТИС, регламентированная отчётность и другие специфичные для России возможности, неактуальные во Вьетнаме - большая часть непереведённого русского словаря связана с ними.

Перевод модели конфигурации по словарю

Мы получили русско-английский словарь метаданных. Как теперь выполнить перевод конфигурации по этому словарю?

Здесь всё просто: подсовываем в Language Tool наш словарь, нажимаем Перевести конфигурацию и ждём. Время перевода будет зависить от используемого "железа" и размера конфигурации, у меня на ноутбуке с i5 1.8 GHz, 16 GB RAM процесс занимает примерно 3 часа.
Всё - получаем переведённую работоспособную конфигурацию.

Шутка 😄 Это не наш случай.

Инструмент ещё молодой, текущая версия 0.8 говорит нам о том что это пока бета. И после перевода я столкнулся с большим количеством ошибок: как ошибки работы плагина, так и ошибки в конфигурации. Дело в том, что автоматизированный перевод кода возможен благодаря типизации, вычисляемой EDT, и далеко не всегда эту типизацию кода 1С можно провести корректно. Плюс плагин сейчас очень чувствителен к соблюдению стандартов разработки в переводимой конфигурации. И это понятно - на что-то нужно опираться. Но в коде типовой УНФ (как впрочем и в БСП) стандарты соблюдаются не на 100%.

Не смотря на текущие сложности, Language tool инструмент очень перспективный и я с интересом буду следить за его развитием и использовать в работе. Замечательно, что у нас появилось новое мощное средство локализации.

Результат перевода

Посмотрим на нескольких примерах как выглядит переведённая конфигурация.

Имена объектов метаданных:

Программный код и запросы:

Запрос динамического списка:

Отчёт на СКД:

Видим, что Language Tool выполнил перевод имён метаданных в модулях, запросах, макетах СКД и других местах.

Использованы версии EDT 1.16.0.363, Language Tool  0.7.1.14 

Перспективы и дальнейшие планы

В следующей части статьи я покажу как был составлен словарь для перевода УНФ на основе нескольких имеющихся словарей из разных источников. А так же более подробно остановлюсь на способах нормализации словаря и устранении неоднозначностей переводов.

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

 

Скачать файлы

Наименование Файл Версия Размер
Использованный при переводе словарь метаданных

.dict 341,73Kb
10.02.20
0
.dict 2020-02-07 341,73Kb Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. comol 4355 03.04.20 19:06 Сейчас в теме
На IS Event 2019 Шерстобитов по-моему делал доклад о переводе кода и интерфейса - крутейшее решение. ИМХО намного удобнее чем то что сейчас имеем в EDT. Ну и сейчас они вроде как развили эту идею. А EDT до сих пор даже 15ю платформу не поддерживает... Получается что "ты в прошлом" уже по определению :(
2. vanjushkin 21 03.04.20 21:29 Сейчас в теме
(1) если речь об этой технологии: https://infostart.ru/public/1156027/ то она решает другую задачу - перевод интерфейса конфигурации, а моя статья посвящена переводу исходного когда и имён метаданных.
check2; VKislitsin; awk; +3 Ответить
3. check2 126 04.04.20 13:23 Сейчас в теме
Коллега, я правильно понял, что Вы взяли две конфы - исходную, и ту которую муками локализовали вручную и из них составили словарь, затем использовали его в плагине для получения из новой версии автоматической локализации? Просто не оч. понял где англоязычную УНФ взяли для составления словаря, вроде как написано из 1С:Vietnam, но потом фраза
Объём этой работы можно существенно сократить, если перед переносом функционала предварительно перевести модель УНФ на английский язык.
сбивает с толку - вроде как уже есть переведённая? Что опять переводить? Ещё не понятно, если вы вручную локализовали ранее, то зачем логику перепаивали? На снимке видны расхождения по метаданным.
4. vanjushkin 21 04.04.20 14:11 Сейчас в теме
(3)
Коллега, я правильно понял, что Вы взяли две конфы - исходную, и ту которую муками локализовали вручную и из них составили словарь

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

В статье описан первый шаг перевода - составление словаря метаданных, чтобы метаданные в Company management и в переведённой УНФ имели одинаковые имена.
5. check2 126 04.04.20 14:30 Сейчас в теме
(4) Ага,
и долгое время уже развивается независимо от УНФ
вот теперь понятно. Этот момент как то я упустил по смыслу. Теперь ясно!
6. Fox-trot 117 04.04.20 15:34 Сейчас в теме
имхо перевод исходников это тупиковый путь
но как известно легких путей мы не ищем
Artem-B; Идальго; comol; +3 Ответить
7. koal@1c 37 08.04.20 06:00 Сейчас в теме
Но в коде типовой УНФ (как впрочем и в БСП) стандарты соблюдаются не на 100%

А можно я немного вступлюсь за БСП?:) На самом деле в БСП стандарты соблюдаются - они же пример для всех остальных. Но приведение к новым стандартам выполняется каждую версию. Т.е. если вышел новый стандарт, то его соблюдение появится только в новой версии. Но т.к. конфигурация довольно старая уже, то конечно с тех времен вышла куча новых стандартов на которые опирается плагин и которые не соблюдаются в старой версии БСП.
10. vanjushkin 21 08.04.20 06:37 Сейчас в теме
(7)
Но т.к. конфигурация довольно старая уже, то конечно с тех времен вышла куча новых стандартов на которые опирается плагин и которые не соблюдаются в старой версии БСП.


Это про новую УНФ 1.6
8. koal@1c 37 08.04.20 06:14 Сейчас в теме
В статье есть момент один - я уже раз пять пытался его оптимизировать, но не получается.
В самом начале, когда нужно получить пары вида uuid - имя, это делается в два этапа. Сначала ищутся большие куски текста от uuid до имени, а потом середина вырезается. Хочется написать регулярку, которая сделает это за один заход.

Я написал регулярку (?<=uuid=")(.*)(?=">)[\s\S]*?(?<=<Name>)(.*)(?=<\/Name>), которая учитывает uuid и </Name> в конце, но не включает их в результат при помощи positive lookahead и positive lookbehind, но саму середину не получается выкинуть.

Или второй вариант использовать группы. Моя регулярка как раз выводит две captured groups, которые и есть нужный результат. Я знаю как легко вытащить эти группы на питоне, но в задаче он не используется, используется только grep. А как вытащить только группы из результата регулярки через grep я тоже не знаю.

Есть знатоки регулярных выражений кто знает как это сделать?
9. vanjushkin 21 08.04.20 06:28 Сейчас в теме
(8)можно навенное сразу через sed или perl сделать, они поддерживают вывод групп
Я на этом этапе долго не задерживался, т.к. всё равно работает быстро. Как только находил работающий вариант - двигался дальше)
Оставьте свое сообщение

См. также

Перевод кода и метаданных конфигурации на английский язык: часть 2

Инструментарий разработчика EDT Локализация решений v8 1cv8.cf Абонемент ($m)

Практический пример подготовки словаря для перевода кода и модели конфигурации УНФ 1.6 на английский язык с использованием существующих словарей и плагина EDT Language Tool. В статье приводятся готовые скрипты и алгоритмы сборки и нормализации словаря.

1 стартмани

05.04.2020    2185    vanjushkin    0