Часто перед нами встает задача выгружать данные в файл, имя которого должно динамически меняться в зависимости от текущей даты или выбранного периода. Например, нам нужно создать файл в формате CSV или PDF со следующим шаблоном имени: PR_MMDDYYYY.csv, где MM — месяц, DD — день, а YYYY — год. Давайте вместе разберем по шагам, как правильно реализовать эту задачу в 1С:Предприятие, проанализируем возможные ошибки и посмотрим на оптимальные способы написания кода.
Имя файла в 1С — это обычная строка. Соответственно, чтобы добавить к нему дату, нам необходимо преобразовать значение с типом Дата в строковое представление. Для этих целей платформа предоставляет мощный глобальный метод Формат. Рассмотрим подробнее, как он работает.
В зависимости от второго параметра функции (форматной строки) мы можем преобразовать дату практически в любой удобный вид. Для нашей задачи идеально подходит форматная строка ДФ=ddMMyyyy.
// Формируем имя файла на основе текущей даты
ТекДата = ТекущаяДатаСеанса();
ИмяФайла = "PR_" + Формат(ТекДата, "ДФ=MMddyyyy") + ".csv";
Почему мы используем именно такое форматирование? Формат ДФ=MMddyyyy (или ДФ=yyyyMMdd) не содержит точек, запятых или слэшей. Если использовать стандартное приведение даты к строке без форматирования, 1С выдаст строку вида "10.06.2023", а некоторые операционные системы могут некорректно интерпретировать точки в названии, принимая часть даты за расширение файла.
Также обратите внимание, что мы используем функцию ТекущаяДатаСеанса(), а не классическую ТекущаяДата(). Проанализируем эту ситуацию: использование даты сеанса гарантирует правильное определение дня и месяца с учетом часового пояса конкретного пользователя, даже если физический сервер 1С находится в другом регионе.
Иногда требуется, чтобы к имени файла автоматически присоединялся период сформированного отчета. Например, файл должен называться так: PR_ДатаНачала-ДатаОкончания.pdf. Посмотрим на пример кода:
ИмяФайла = "PR_" + Формат(ДатаНачала, "ДФ=ddMMyyyy") + "-" + Формат(ДатаОкончания, "ДФ=ddMMyyyy") + ".pdf";
Однако при получении дат из табличного документа разработчики часто допускают логическую ошибку. Разберем типичную ситуацию, когда код выглядит так:
ДатаНачала = Результат.ПолучитьОбласть("ДатаНачала");
ДатаОкончания = Результат.ПолучитьОбласть("ДатаОкончания");
ИмяФайла = "Баланс_" + Формат(ДатаНачала, "ДФ=ddMMyyyy");
Метод ПолучитьОбласть возвращает не дату, а объект платформы ТабличныйДокумент (фрагмент макета). Если попытаться передать этот объект в функцию Формат, платформа не сможет его преобразовать. Чтобы получить саму дату, необходимо обращаться к значению ячейки:
ДатаНачала = Результат.Область("ДатаНачала").Значение;
Но давайте будем использовать более правильный подход: вообще не извлекать даты из уже сформированного печатного документа. Даты периода следует брать напрямую из реквизитов формы отчета или параметров компоновщика настроек СКД, так как там они уже имеют правильный тип Дата.
При попытке сохранить сформированный файл пользователи часто сталкиваются с ошибкой: Метод недоступен в тонком клиенте. Выясним причину этой проблемы. Ошибка возникает при использовании следующего кода:
Режим = РежимДиалогаВыбораФайла.Сохранение;
ДиалогСохраненияФайла = Новый ДиалогВыбораФайла(Режим);
// ... настройка диалога ...
Если ДиалогСохраненияФайла.Выбрать() Тогда // Ошибка здесь!
ПутьКФайлу = ДиалогСохраненияФайла.ПолноеИмяФайла;
КонецЕсли;
В современных версиях платформы (начиная с 8.3.3) синхронные вызовы на клиенте (такие как Выбрать()) по умолчанию отключены для повышения стабильности работы. Вместо них необходимо применять асинхронные методы. Перепишем наш код с использованием асинхронного подхода, доступного в новых версиях платформы (начиная с 8.3.18):
&НаКлиенте
Асинх Процедура СохранитьФайлПрограммно(Команда)
Режим = РежимДиалогаВыбораФайла.Сохранение;
Диалог = Новый ДиалогВыбораФайла(Режим);
Диалог.ПолноеИмяФайла = "Баланс_" + Формат(ТекущаяДатаСеанса(), "ДФ=ddMMyyyy");
Диалог.Фильтр = "Документ PDF (*.pdf)|*.pdf";
ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх();
Если ВыбранныеФайлы <> Неопределено Тогда
ПутьКФайлу = ВыбранныеФайлы[0];
Результат.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
КонецЕсли;
КонецПроцедуры
Использование ключевых слов Асинх и Ждать делает код чистым, понятным и избавляет от ошибки недоступности метода в тонком клиенте.
В комплексных задачах после сохранения файла часто требуется сразу же отправить его по электронной почте. Многие пытаются инициализировать объекты ИнтернетПочтовыйПрофиль и ИнтернетПочта прямо в клиентской процедуре. Проанализируем, почему это плохая практика:
Правильный подход заключается в том, чтобы выполнять всю работу с почтой в серверном контексте. Сервер 1С, как правило, имеет необходимые доступы к почтовым шлюзам организации. Рассмотрим оптимальный алгоритм действий:
Применяя эти знания на практике, вы сможете легко формировать динамические имена файлов, избегать ошибок тонкого клиента и правильно выстраивать архитектуру клиент-серверного взаимодействия при отправке отчетов по электронной почте.