Иногда бывает необходимо быстро "перевести" ряд отчетов системы на иностранный язык.
Например, для клиентов или для сотрудников-экспатов.
Классический пример - перевод ОСВ или отчета о финансовых результатах.
Можно пойти по пути добавления в основные справочники конфигурации дополнительных реквизитов, создания дублей макетов с шапками на иностранном языке и т.п.
Далеко не все специалисты 1С знают, что если для конфигурации указано несколько языков, то макеты можно делать мультиязычными, выбирая текст и формат ячейки для каждого языка - свой. При формировании отчета достаточно указать код языка для выводимой области - и отчет сформируется на нужном языке.
В 8.3 можно переопределить представление справочников и документов, этим тоже можно пользоваться.
Я предлагаю еще один простой метод - перевод готовых табличных документов с использованием словаря.
Добавляем в конфигурацию регистр сведений Словарь с измерением Термин и ресурсом Перевод и пишем процедуру общего модуля, обрабатывающую любой табличный документ. Теперь нам достаточно лишь вставить в модуль отчета вызов процедуры. Причем можно даже не менять форму отчета - достаточно сделать отдельный параметр сеанса, форму для его изменения и анализ этого параметра в процедуре перевода.
В моем примере предполагается, что в один из справочников НСИ (Контрагенты) все-таки добавили реквизит НаименованиеИностранное, остальной перевод идет по Словарю. Можно доработать процедуру для рекурсивного или циклического перевода сложных строк, пока проверка выполняется один раз. Для каждой строки из областей табличного документа в словаре ищется подходящая подстрока максимальной длины и осуществляется замена.
Пример написан для толстого клиента. В нем вызывается форма индикатора из конфигурации (замените на свою, если необходимо). Код написан неоптимально, но думаю, понятно.
Вот код:
// Транслирует табличный документ на другой язык при помощи словаря
Процедура ПеревестиТабличныйДокумент(ТД) Экспорт
кс=ТД.ВысотаТаблицы;
кк=ТД.ШиринаТаблицы;
/// вызовем индикатор
ФИ=ПолучитьОбщуюФорму("ФормаИндикатора");
ФИ.МаксимальноеЗначение=кс*кк;
ФИ.НадписьСостоянияИндикатораОбщая="Перевод отчета на английский язык";
Фи.Открыть();
ФИ.НадписьСостоянияИндикатораТекущая="Выбираю иностранные наименования контрагентов...";
ЗапросИностранныхНаименований=Новый Запрос("ВЫБРАТЬ
| Контрагенты.Наименование КАК Наименование,
| 0 КАК ДлинаТекста,
| Контрагенты.НаименованиеИностранное,
| Контрагенты.НаименованиеПолное КАК НаименованиеПолное
|ПОМЕСТИТЬ ИностранныеНаименования
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.НаименованиеИностранное ПОДОБНО ""%[0-z]%""
|
|ИНДЕКСИРОВАТЬ ПО
| Наименование,
| НаименованиеПолное");
МВТ=Новый МенеджерВременныхТаблиц;
ЗапросИностранныхНаименований.МенеджерВременныхТаблиц=МВТ;
ЗапросИностранныхНаименований.Выполнить();
Запрос=Новый Запрос("ВЫБРАТЬ
| Словарь.Перевод,
| Словарь.Термин КАК Термин
|ПОМЕСТИТЬ ВесьСловарь
|ИЗ
| РегистрСведений.Словарь КАК Словарь
|
|ИНДЕКСИРОВАТЬ ПО
| Термин");
Запрос.МенеджерВременныхТаблиц=МВТ;
Запрос.Выполнить();
Запрос.Текст="ВЫБРАТЬ
| Словарь.Перевод,
| 0 КАК ДлинаТекста,
| Словарь.Термин
|ИЗ
| ВесьСловарь КАК Словарь
|ГДЕ
| &Термин ПОДОБНО ""%"" + Словарь.Термин + ""%""";
ЗапросСинонима=Новый Запрос("
|ВЫБРАТЬ
| Словарь.НаименованиеИностранное как Перевод,
| 0 КАК ДлинаТекста,
| Словарь.НаименованиеПолное как Термин
|ИЗ
| ИностранныеНаименования КАК Словарь
|ГДЕ
| &Термин ПОДОБНО ""%"" + Словарь.НаименованиеПолное + ""%""
| И Словарь.НаименованиеПолное ПОДОБНО ""%[0-я]%""
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ
| Словарь.НаименованиеИностранное как Перевод,
| 0 КАК ДлинаТекста,
| Словарь.Наименование как Термин
|ИЗ
| ИностранныеНаименования КАК Словарь
|ГДЕ
| &Термин ПОДОБНО ""%"" + Словарь.Наименование + ""%""");
ЗапросСинонима.МенеджерВременныхТаблиц=МВТ;
ФИ.НадписьСостоянияИндикатораТекущая="";
Для ы=1 По кс Цикл
Для к=1 По кк Цикл
//проверим на объединение
Область = ТД.Область(ы, к);
Если Область.Право > Область.Лево ИЛИ Область.Низ > Область.Верх Тогда
Обл=ТД.Область(ы,к,Область.Низ,Область.Право);
Иначе
Обл=ТД.Область(ы,к,ы,к);
КонецЕсли;
Термин=СокрЛП(Обл.Текст);
мСодержитсяЗначение=Ложь;
Если Обл.СодержитЗначение И ТипЗнч(Обл.Значение)=Тип("Строка")
И ЗначениеЗаполнено(Обл.Значение) Тогда
мСодержитсяЗначение=Истина;
Термин= СокрЛП(Обл.Значение) ;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Термин) ИЛИ (Обл.СодержитЗначение И НЕ мСодержитсяЗначение) Тогда
Продолжить;
КонецЕсли;
ФИ.ЗначениеИндикатора=((ы-1)*кк)+к;
Если ЗначениеЗаполнено(Термин) Тогда
// пример замены отчетной даты в отчетности РСБУ:
Если Найти(Термин,"На ")>0 ИЛИ Найти(Термин,"на ")>0 Тогда
Для ю=-25 По 12 Цикл
ОтчетнаяДата=КонецМесяца(ДобавитьМесяц(НачалоГода(ТекущаяДата()),ю));
СтрокаОтчетнойДаты=Формат(ОтчетнаяДата,"ДЛФ=DD");
СтрокаОтчетнойДаты=СтрЗаменить(СтрокаОтчетнойДаты,Символы.НПП," ");
Если Найти(Термин2,СтрокаОтчетнойДаты )>0 Тогда
Если НЕ мСодержитсяЗначение Тогда
Обл.Текст=СтрЗаменить(Термин2, "На ", "As at ");
Обл.Текст=СтрЗаменить(Обл.Текст, "на ", "as at ");
Обл.Текст=СтрЗаменить(Обл.Текст, СтрокаОтчетнойДаты ,Формат(ОтчетнаяДата,"Л=en; ДЛФ=DD")); Иначе Обл.Значение=СтрЗаменить(Термин2, "На ", "As at "); Обл.Значение=СтрЗаменить(Обл.Значение, "на ", "as at "); Обл.Значение=СтрЗаменить(Обл.Значение, СтрокаОтчетнойДаты,Формат(ОтчетнаяДата,"Л=en; ДЛФ=DD"));
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Проверим по таблице иностранных наименований
ЗапросСинонима.УстановитьПараметр("Термин",Термин);
Результаты=ЗапросСинонима.Выполнить().Выгрузить();
Для Каждого р ИЗ Результаты Цикл
р.ДлинаТекста=СтрДлина(СокрЛП(р.Перевод));
КонецЦикла;
Результаты.Сортировать("ДлинаТекста Убыв");
Если Результаты.Количество()>0 Тогда
Перевод=СокрЛП(Результаты[0].Перевод);
ФИ.НадписьСостоянияИндикатораТекущая=Термин+"->"+Перевод;
Если НЕ мСодержитсяЗначение Тогда
Обл.Текст=СтрЗаменить(Обл.Текст,Результаты[0].Термин,Перевод);
Иначе
Обл.Значение=СтрЗаменить(Обл.Значение,Результаты[0].Термин,Перевод);
КонецЕсли;
КонецЕсли;
Термин=СокрЛП(Обл.Текст);
// Проверим по СЛОВАРЮ
Запрос.УстановитьПараметр("Термин",Термин);
Результаты=Запрос.Выполнить().Выгрузить();
Для Каждого р ИЗ Результаты Цикл
р.ДлинаТекста=СтрДлина(СокрЛП(р.Перевод));
КонецЦикла;
Результаты.Сортировать("ДлинаТекста Убыв");
Если Результаты.Количество()>0 Тогда
Перевод=СокрЛП(Результаты[0].Перевод);
ФИ.НадписьСостоянияИндикатораТекущая=Термин+"->"+Перевод;
Если НЕ мСодержитсяЗначение Тогда
Обл.Текст=СтрЗаменить(Обл.Текст,Результаты[0].Термин,Перевод);
Иначе
Обл.Значение=СтрЗаменить(Обл.Значение,Результаты[0].Термин,Перевод);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Фи.Обновить();
КонецЦикла;
КонецЦикла;
ФИ.Закрыть();
МВТ.Закрыть();
КонецПроцедуры