При формировании печатных форм для иностранных контрагентов в платформе 1С:Предприятие 7.7 часто возникает задача вывести период (месяц, квартал, полугодие или год) на английском языке. Разработчики сталкиваются с тем, что стандартная функция ПериодСтр() продолжает выводить названия на русском языке (например, «2 Квартал 2017 г.» вместо «2 Quarter 2017»), даже если в коде вызывалась процедура Пропись().
Разберем причины такого поведения платформы и подробно рассмотрим несколько способов решения этой задачи: от правильной настройки файлов прописи и передачи СпискаЗначений до написания собственной гибкой функции форматирования.
Функция ПериодСтр(Дата1, Дата2) использует системный шаблон прописи, установленный процедурой Пропись(). Если после вызова Пропись("eng.spl") период выводится по-русски, это происходит по одной из следующих причин:
.spl: В файлах прописи 1С 7.7 строго фиксирован порядок строк. Для дат предусмотрены блоки месяцев в именительном и родительном падежах, а также обозначения года, квартала и секция DateRange (полугодия, месяцы). Если удалить «лишние» строки или элементы из кавычек, платформа не сможет корректно прочитать структуру и переключится на системный русский шаблон по умолчанию.BIN\. Если по указанному пути файл отсутствует, вызов игнорируется.Чтобы не зависеть от наличия внешних файлов .spl на клиентских машинах и гарантировать правильность структуры, можно сформировать шаблон дат динамически в коде с помощью объекта СписокЗначений.
Посмотрим на пример процедуры формирования прописи дат:
Процедура СформироватьИнтервалНаАнглийском()
Перем СписокПрописи, СписокДат;
// Формируем список с названиями месяцев, года и квартала
СписокДат = СоздатьОбъект("СписокЗначений");
// Месяцы в именительном падеже
СписокДат.ДобавитьЗначение("January");
СписокДат.ДобавитьЗначение("February");
СписокДат.ДобавитьЗначение("March");
СписокДат.ДобавитьЗначение("April");
СписокДат.ДобавитьЗначение("May");
СписокДат.ДобавитьЗначение("June");
СписокДат.ДобавитьЗначение("July");
СписокДат.ДобавитьЗначение("August");
СписокДат.ДобавитьЗначение("September");
СписокДат.ДобавитьЗначение("October");
СписокДат.ДобавитьЗначение("November");
СписокДат.ДобавитьЗначение("December");
// Месяцы в родительном падеже (для английского языка дублируются)
СписокДат.ДобавитьЗначение("January");
СписокДат.ДобавитьЗначение("February");
СписокДат.ДобавитьЗначение("March");
СписокДат.ДобавитьЗначение("April");
СписокДат.ДобавитьЗначение("May");
СписокДат.ДобавитьЗначение("June");
СписокДат.ДобавитьЗначение("July");
СписокДат.ДобавитьЗначение("August");
СписокДат.ДобавитьЗначение("September");
СписокДат.ДобавитьЗначение("October");
СписокДат.ДобавитьЗначение("November");
СписокДат.ДобавитьЗначение("December");
// Обозначения года и квартала
СписокДат.ДобавитьЗначение(""); // суффикс года (например, "г.") оставляем пустым
СписокДат.ДобавитьЗначение("Quarter"); // замена слова "Квартал"
// Оборачиваем в общий список параметров прописи с ключом "Date"
СписокПрописи = СоздатьОбъект("СписокЗначений");
СписокПрописи.ДобавитьЗначение(СписокДат, "Date");
// Применяем шаблон
Пропись(СписокПрописи);
// Теперь функция вернет строку вида "2 Quarter 2017"
Сообщить(ПериодСтр(НачДата, КонДата));
// Сбрасываем пропись обратно к системным настройкам
Пропись("");
КонецПроцедуры
Важно: Установка шаблона через Пропись(...) действует глобально в рамках сеанса. После вывода печатной формы обязательно сбрасывайте пропись вызовом Пропись(""), чтобы в других отчетах и документах даты и суммы не выводились на английском языке.
Если требуется быстро перевести уже сформированную стандартную строку периода без изменения глобальных настроек прописи, воспользуемся функцией СтрЗаменить().
Разберем реализацию такой вспомогательной функции:
Функция ПолучитьПериодEng(Дата1, Дата2)
Перем СтрПериода;
СтрПериода = ПериодСтр(Дата1, Дата2);
// Замена месяцев
СтрПериода = СтрЗаменить(СтрПериода, "Январь", "January");
СтрПериода = СтрЗаменить(СтрПериода, "Февраль", "February");
СтрПериода = СтрЗаменить(СтрПериода, "Март", "March");
СтрПериода = СтрЗаменить(СтрПериода, "Апрель", "April");
СтрПериода = СтрЗаменить(СтрПериода, "Май", "May");
СтрПериода = СтрЗаменить(СтрПериода, "Июнь", "June");
СтрПериода = СтрЗаменить(СтрПериода, "Июль", "July");
СтрПериода = СтрЗаменить(СтрПериода, "Август", "August");
СтрПериода = СтрЗаменить(СтрПериода, "Сентябрь", "September");
СтрПериода = СтрЗаменить(СтрПериода, "Октябрь", "October");
СтрПериода = СтрЗаменить(СтрПериода, "Ноябрь", "November");
СтрПериода = СтрЗаменить(СтрПериода, "Декабрь", "December");
// Замена периодов и суффиксов
СтрПериода = СтрЗаменить(СтрПериода, "Квартал", "Quarter");
СтрПериода = СтрЗаменить(СтрПериода, "Полугодие", "Half-year");
СтрПериода = СтрЗаменить(СтрПериода, "месяцев", "months");
СтрПериода = СтрЗаменить(СтрПериода, " г.", "");
Возврат СтрПериода;
КонецФункции
Функция ПериодСтр() имеет жестко зашитый порядок слов: [Номер] [Квартал] [Год]. Для делового английского языка приняты другие стандарты оформления, например, краткие обозначения кварталов (Q2 2017) или американский формат дат (Month DD, YYYY).
Для таких случаев оптимальным решением является собственная функция, анализирующая границы переданного интервала:
Функция СформироватьИнтервалEng(Дата1, Дата2)
Перем СписокМесяцев, ТекМесяц, НомерКвартала;
СписокМесяцев = СоздатьОбъект("СписокЗначений");
СписокМесяцев.ИзСтрокиСРазделителями("""January"",""February"",""March"",""April"",""May"",""June"",""July"",""August"",""September"",""October"",""November"",""December""");
// Проверка на точный месяц
Если (НачМесяца(Дата1) = Дата1) И (КонМесяца(Дата2) = Дата2) И (ДатаМесяц(Дата1) = ДатаМесяц(Дата2)) И (ДатаГод(Дата1) = ДатаГод(Дата2)) Тогда
ТекМесяц = СписокМесяцев.ПолучитьЗначение(ДатаМесяц(Дата1));
Возврат ТекМесяц + " " + Строка(ДатаГод(Дата1));
КонецЕсли;
// Проверка на точный квартал
Если (НачКвартала(Дата1) = Дата1) И (КонКвартала(Дата2) = Дата2) И (ДатаГод(Дата1) = ДатаГод(Дата2)) Тогда
НомерКвартала = (ДатаМесяц(Дата1) + 2) / 3;
Возврат "Q" + Строка(НомерКвартала) + " " + Строка(ДатаГод(Дата1));
КонецЕсли;
// Проверка на полный год
Если (НачГода(Дата1) = Дата1) И (КонГода(Дата2) = Дата2) И (ДатаГод(Дата1) = ДатаГод(Дата2)) Тогда
Возврат Строка(ДатаГод(Дата1)) + " Year";
КонецЕсли;
// Произвольный интервал дат
Возврат Формат(Дата1, "ДДММГГГГ") + " - " + Формат(Дата2, "ДДММГГГГ");
КонецФункции
При тонкой настройке локализации в 1С 7.7 полезно учитывать следующие системные ограничения:
Формат() платформа автоматически приводит буквы в нижний регистр, оставляя заглавной только первую. Однако для секции дат (Date) регистр символов сохраняется в исходном виде, как он был задан в СписокЗначений или файле .spl.