При работе с системой 1С часто возникает необходимость автоматизировать процессы, связанные с файловой системой. Одна из таких задач – сохранение табличных документов в файлы Excel с использованием динамических имен, например, включающих дату. При этом также может потребоваться создавать отдельные каталоги для таких файлов, чтобы обеспечить порядок и удобство хранения. В данном материале мы подробно разберем, как эффективно решить обе эти задачи, избегая распространенных ошибок, связанных с недопустимыми символами в именах файлов и путях к каталогам.
Предположим, мы хотим сохранить табличный документ, который сформирован в 1С, в файл формата XLSX на диск D:/. Имя файла должно содержать дату, например, дату из выборки данных, и иметь расширение .xlsx. Изначальная попытка может выглядеть так:
ТабДок.Записать("D:\" + Выборка.Дата + ".xlsx", ТипФайлаТабличногоДокумента.XLSX);
При таком подходе мы сталкиваемся с двумя потенциальными проблемами: файл может сохраняться без расширения или с некорректным именем, и при этом он не будет помещен в новый, специально созданный каталог с именем, основанным на дате.
Первая проблема заключается в том, что стандартное представление даты и времени в 1С (например, `02.02.2021 14:30:00`) содержит символы, которые являются недопустимыми для использования в именах файлов и каталогов в операционных системах, в частности в Windows. К таким символам относятся двоеточие (`:`), обратная косая черта (`\`), прямая косая черта (`/`), звездочка (`*`), вопросительный знак (`?`), кавычки (`"`), знаки меньше (`<`) и больше (`>`), а также вертикальная черта (`|`). Пробелы и точки также не допускаются в конце имени файла.
Когда операционная система встречает такой недопустимый символ в имени файла, она может либо выдать ошибку, либо, что чаще, обрезать имя файла до этого символа. Именно поэтому в примере из обсуждения файл мог сохраняться как `02.02.2021`, без расширения и без части, следующей за временем (если время присутствовало в строке даты). Наличие пробела перед нулем (как в `02.02.2021 0`) также может привести к усечению имени.
Для корректного использования даты в именах файлов и каталогов в 1С необходимо применять функцию Формат(). Эта функция позволяет нам задать произвольный формат даты и времени, исключая все запрещенные символы и приводя дату к виду, безопасному для файловой системы. Мы можем выбрать такой формат, который будет удобен для сортировки и чтения.
Формат()Рассмотрим, как использовать функцию Формат(). Она принимает два основных параметра: значение, которое нужно форматировать (в нашем случае это дата из Выборка.Дата), и строку формата.
Например, если мы хотим получить дату в формате "ГГГГММДД" (год, месяц, день без разделителей), мы можем использовать следующий код:
ФорматированнаяДата = Формат(Выборка.Дата, "ДФ=yyyyMMdd");
// Пример: если Выборка.Дата = 02.02.2021 14:30:00, то ФорматированнаяДата будет "20210202"
Или, если предпочтительнее использовать разделители, но безопасные для файловой системы, например, нижнее подчеркивание:
ФорматированнаяДата = Формат(Выборка.Дата, "ДФ=dd_MM_yyyy");
// Пример: если Выборка.Дата = 02.02.2021 14:30:00, то ФорматированнаяДата будет "02_02_2021"
Выбор формата "ГГГГММДД" ("ДФ=yyyyMMdd") является наиболее предпочтительным, поскольку он обеспечивает удобную сортировку файлов или каталогов по дате создания в любом файловом менеджере. При таком формате файлы, созданные в разные даты, будут автоматически выстраиваться в хронологическом порядке при стандартной сортировке по имени.
Если нам необходимо также включить время, но без запрещенных символов, мы можем использовать, например, `"_чч_мм_сс"`:
ФорматированнаяДатаВремя = Формат(Выборка.Дата, "ДФ=yyyyMMdd_HH_mm_ss");
// Пример: если Выборка.Дата = 02.02.2021 14:30:00, то ФорматированнаяДатаВремя будет "20210202_14_30_00"
Для нашей задачи, где время не обязательно, достаточно использовать только дату.
Теперь, когда мы имеем корректную строковую переменную с датой без запрещенных символов, мы можем использовать ее для формирования полного имени файла. Таким образом, строка записи файла примет следующий вид:
ФорматированнаяДата = Формат(Выборка.Дата, "ДФ=yyyyMMdd");
ПолноеИмяФайла = "D:\" + ФорматированнаяДата + ".xlsx";
ТабДок.Записать(ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Этот подход гарантирует, что файл будет сохранен с правильным именем (например, `20210202.xlsx`) и необходимым расширением.
Теперь давайте разберем вторую часть задачи: как создать каталог на диске D: с именем, основанным на дате, и затем сохранить наш файл в этот новый каталог.
Изначальная попытка создать каталог и сохранить в него файл может быть такой, как в обсуждении:
// Это не создаст каталог, только попытается записать файл
// в несуществующий каталог, что приведет к ошибке
ТабДок.Записать("D:\" + Выборка.Дата + "\" + "МойФайл.xlsx", ТипФайлаТабличногоДокумента.XLSX);
Такая строка только формирует путь, но не выполняет создание каталога. Для создания каталога в 1С существует специальная функция.
СоздатьКаталог()В системе 1С для программного создания нового каталога используется функция СоздатьКаталог(). Ей необходимо передать полный путь к каталогу, который мы хотим создать.
Как и в случае с именем файла, имя каталога также должно быть сформировано без запрещенных символов, поэтому здесь также пригодится функция Формат().
ФорматированнаяДатаДляКаталога = Формат(Выборка.Дата, "ДФ=yyyyMMdd"); // Например, "20210202"
ПутьККаталогу = "D:\" + ФорматированнаяДатаДляКаталога;
СоздатьКаталог(ПутьККаталогу); // Создаем каталог
Важный момент: Как было отмечено в обсуждении, при использовании СоздатьКаталог() критически важно указывать полный путь к каталогу, включая корневой диск. Ошибка, когда забыли прописать "D:\" перед именем каталога, приведет к тому, что 1С будет пытаться создать каталог относительно текущего рабочего каталога, что может быть непредсказуемо или вызвать ошибку доступа.
Функция СоздатьКаталог() обладает полезным свойством: если в указанном пути присутствует несколько несуществующих подкаталогов (например, `D:\Отчеты\2023\Январь`), функция автоматически создаст всю необходимую вложенную структуру. То есть, не нужно проверять и создавать каждый уровень каталога по отдельности. Например, СоздатьКаталог("D:\Temp\1\2\3") создаст каталоги "1", "2" и "3", если они не существуют, при условии, что `D:\Temp` уже есть.
Также важно отметить, что если каталог по указанному пути уже существует, вызов СоздатьКаталог() не приведет к ошибке. Это упрощает логику, так как не требуется предварительная проверка существования каталога перед его созданием, если мы просто хотим убедиться, что он есть.
Хотя СоздатьКаталог() не выдает ошибку, если каталог уже есть, в некоторых случаях может быть полезно явно проверить его существование перед попыткой создания или перед началом работы с файлами в нем. Для этого в 1С можно использовать метод Существует() объекта Файл.
ПутьККаталогу = "D:\" + Формат(Выборка.Дата, "ДФ=yyyyMMdd");
Если Не Новый Файл(ПутьККаталогу).Существует() Тогда
Попытка
СоздатьКаталог(ПутьККаталогу);
Исключение
Сообщить("Не удалось создать каталог: " + ОписаниеОшибки());
Возврат; // Выходим из процедуры, если каталог не удалось создать
КонецПопытки;
КонецЕсли;
Такая проверка повышает надежность кода, особенно если есть вероятность проблем с правами доступа или некорректно сформированным путем.
После того как каталог гарантированно создан, мы можем сформировать полный путь к файлу, включающий этот каталог, и использовать его в функции ТабДок.Записать().
ФорматированнаяДатаДляКаталога = Формат(Выборка.Дата, "ДФ=yyyyMMdd");
ПутьККаталогу = "D:\" + ФорматированнаяДатаДляКаталога;
// Проверяем и создаем каталог
Если Не Новый Файл(ПутьККаталогу).Существует() Тогда
Попытка
СоздатьКаталог(ПутьККаталогу);
Исключение
Сообщить("Не удалось создать каталог: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецЕсли;
// Формируем имя файла
ИмяФайла = "МойФайл.xlsx"; // Или "МойФайл_" + Формат(Выборка.Дата, "ДФ=yyyyMMdd") + ".xlsx";
// Формируем полный путь к файлу внутри каталога
ПолныйПутьКФайлу = ПутьККаталогу + "\" + ИмяФайла;
// Сохраняем табличный документ
ТабДок.Записать(ПолныйПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
В более новых версиях 1С (начиная с 8.3.11) при использовании недопустимых символов в имени каталога функция СоздатьКаталог() будет генерировать исключение. Это позволяет нам перехватить и обработать такую ситуацию программно, информируя пользователя о проблеме или предпринимая альтернативные действия. Поэтому всегда полезно оборачивать вызовы файловых операций в блок Попытка...Исключение...КонецПопытки.
Если вам необходимо создать каталог для временного хранения файлов, который должен быть удален после завершения работы, в 1С существует специальная функция СоздатьВременныйКаталог(). Она создает уникальный временный каталог, и вы можете указать необходимость его удаления после завершения работы сеанса 1С или по другим условиям. Это удобно для обработки файлов, которые не предназначены для постоянного хранения.
// Создание временного каталога
ВременныйКаталог = СоздатьВременныйКаталог(); // Возвращает полный путь к новому временному каталогу
// Пример использования:
// ТабДок.Записать(ВременныйКаталог + "\ВременныйФайл.xlsx", ТипФайлаТабличногоДокумента.XLSX);
// ... дальнейшая работа с файлом ...
// Файл(ВременныйКаталог).Удалить(); // Удаление временного каталога (если требуется вручную)
Мы рассмотрели два ключевых аспекта работы с файловой системой в 1С: формирование безопасных имен файлов с датой и программное создание каталогов. Использование функции Формат() для преобразования даты и времени в строку без запрещенных символов является критически важным для корректной работы с именами файлов и каталогов. Функция СоздатьКаталог(), в свою очередь, позволяет гибко управлять структурой каталогов, обеспечивая автоматическое создание вложенных директорий и отсутствие ошибок при попытке создания уже существующего каталога. Комбинируя эти подходы, мы можем эффективно автоматизировать процесс сохранения документов, делая наши решения более надежными и функциональными.