При разработке регламентных заданий и механизмов автоматической рассылки отчетов часто возникает задача отправки данных иностранным партнерам или сотрудникам филиалов в других странах. Например, требуется сформировать один и тот же отчет на немецком, английском или русском языке в зависимости от настроек контрагента или получателя. Разберем особенности работы механизма компоновки данных с многоязычными строками и выясним, как программно перевести отчет на нужный язык.
Проанализируем базовый механизм работы системы компоновки данных. В конфигураторе 1С предусмотрена возможность задавать заголовки полей, параметров и ресурсов в виде строк на разных языках. Однако во время выполнения отчета объект КомпоновщикМакетаКомпоновкиДанных формирует результирующий макет, опираясь исключительно на код языка текущего сеанса пользователя или фонового задания.
У схемы компоновки данных и процессоров вывода нет встроенного свойства или параметра вроде КодЯзыка, который мог бы переключить локализацию макета на лету. Если регламентное задание выполняется в русскоязычном сеансе, СКД по умолчанию подставит русские заголовки, даже если в схеме заполнены переводы на немецкий или английский языки.
Рассмотрим наиболее надежный и гибкий способ перевода отчета без прямого вмешательства в скомпилированный макет. До вызова компоновщика макета мы можем загрузить исходную схему в память и программно переопределить заголовки полей и параметров на нужный язык с помощью функции НСтр().
Разберем по шагам, как модифицировать схему компоновки данных перед формированием:
НСтр() для требуемого кода языка (например, "de") и переопределяем свойство Заголовок.Посмотрим на пример программного кода для адаптации схемы перед компоновкой:
СхемаКД = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
КодЯзыкаПолучателя = "de";
// Обходим наборы данных и переопределяем заголовки полей
Для Каждого НаборДанных Из СхемаКД.НаборыДанных Цикл
Для Каждого ПолеНабора Из НаборДанных.Поля Цикл
Если ЗначениеЗаполнено(ПолеНабора.Заголовок) Тогда
ПолеНабора.Заголовок = НСтр(ПолеНабора.Заголовок, КодЯзыкаПолучателя);
КонецЕсли;
КонецЦикла;
КонецЦикла;
// Обходим вычисляемые поля
Для Каждого ВычисляемоеПоле Из СхемаКД.ВычисляемыеПоля Цикл
Если ЗначениеЗаполнено(ВычисляемоеПоле.Заголовок) Тогда
ВычисляемоеПоле.Заголовок = НСтр(ВычисляемоеПоле.Заголовок, КодЯзыкаПолучателя);
КонецЕсли;
КонецЦикла;
// Устанавливаем заголовок самого отчета в настройках
Настройки = СхемаКД.НастройкиПоУмолчанию;
ПараметрЗаголовок = Настройки.ПараметрыВывода.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Title"));
Если ПараметрЗаголовок <> Неопределено Тогда
ПараметрЗаголовок.Значение = НСтр("ru='Отчет по продажам'; de='Verkaufsbericht'", КодЯзыкаПолучателя);
ПараметрЗаголовок.Использование = Истина;
КонецЕсли;
Рассмотрим альтернативный способ, который часто применяется в типовых локализованных решениях. В этом подходе отчет компилируется стандартным образом, после чего выполняется обход сгенерированного объекта МакетКомпоновкиДанных и замена текстовых выражений в ячейках на основе регистра сведений или функции перевода.
Посмотрим на пример процедуры обработки скомпилированного макета:
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
// Локализуем элементы скомпилированного макета
Для Каждого ОписаниеОбласти Из МакетКомпоновки.Макеты Цикл
Для Каждого СтрокаТаблицы Из ОписаниеОбласти.Макет Цикл
Для Каждого ЯчейкаТаблицы Из СтрокаТаблицы.Ячейки Цикл
Для Каждого ЭлементЯчейки Из ЯчейкаТаблицы.Элементы Цикл
Если ТипЗнч(ЭлементЯчейки) = Тип("ЗначениеПараметраМакетаКомпоновкиДанных") Тогда
// Выполняем поиск перевода для значения ячейки
ЭлементЯчейки.Значение = ПолучитьПеревод(ЭлементЯчейки.Значение, "de");
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
При использовании этого подхода важно учитывать структуру макета: ячейки могут содержать как статичный текст, так и параметры макета, формируемые динамически.
Проанализируем еще один системный вариант. Если в конфигурации настроена полноценная мультиязычность и для каждого языка создан соответствующий объект метаданных Язык, мы можем формировать отчеты через отдельное фоновое задание под служебным пользователем информационной базы.
Для этого в свойствах пользователя 1С задается основной язык интерфейса (например, немецкий). При старте фонового задания от имени такого пользователя платформа автоматически применит все локализованные строки метаданных и схемы компоновки данных без необходимости ручной модификации объектов.
Выясним дополнительные нюансы, которые необходимо учесть при выводе отчетов для иностранных пользователей:
L=de_DE или L=en_US, чтобы десятичные разделители и названия месяцев соответствовали стандартам страны получателя.&КодЯзыка.