В процессе разработки в среде 1С:Предприятие 8.3 программисты часто сталкиваются с задачами по выгрузке отчетов, обработке внешних данных и сохранению результатов во внешние файлы. При этом у начинающих разработчиков нередко возникает терминологическая путаница. Что значит "сохранить файл" и чем это действие отличается от понятия "записать файл в 1С"?
В рамках этой статьи мы подробно проанализируем обе задачи, разберем разницу в подходах, изучим необходимые системные объекты и методы, а также рассмотрим готовые практические примеры кода для работы в управляемом приложении 1С 8.3.
Прежде чем перейти к написанию программного кода, выясним принципиальное различие между двумя процессами, которые часто называют одинаково, но реализуют совершенно разными методами:
.xlsx, .txt, .xml и т. д.). Данные покидают контур 1С и становятся доступны другим программам на ПК.ХранилищеЗначения. После этого исходный файл на компьютере пользователя можно безболезненно удалить — все данные теперь хранятся внутри информационной базы 1С.Рассмотрим подробно реализацию обоих механизмов на конкретных примерах.
Для программного формирования таблиц и их последующего экспорта в форматы Microsoft Excel в платформе 1С:Предприятие используется универсальный объект ТабличныйДокумент. Он обладает мощным встроенным методом Записать(), который берет на себя всю работу по конвертации внутренней разметки 1С в целевой формат.
Разберем по шагам пример создания простого отчета и его записи на диск в формате .xlsx:
&НаКлиенте
Процедура СоздатьИСохранитьExcel(Команда)
// Шаг 1. Инициализируем табличный документ (наш будущий лист Excel)
ТабДок = Новый ТабличныйДокумент;
// Шаг 2. Заполняем ячейки данными программно
// Запишем заголовок в первую строку первой колонки
ОбластьЗаголовок = ТабДок.Область("R1C1");
ОбластьЗаголовок.Текст = "Отчет по продажам (тестовый)";
ОбластьЗаголовок.Шрифт = Новый Шрифт(ТабДок.Область("R1C1").Шрифт, , , Истина); // Выделяем жирным
// Заполняем небольшую таблицу данных
Для Строка = 3 По 10 Цикл
// Заполняем колонку с наименованием
ТабДок.Область("R" + Строка + "C1").Текст = "Товар № " + (Строка - 2);
// Заполняем колонку с количеством
ТабДок.Область("R" + Строка + "C2").Текст = Формат((Строка * 5), "ЧГ=0");
КонецЦикла;
// Шаг 3. Задаем путь для сохранения файла на диске компьютера
ПутьКФайлу = "C:\temp\ВыгрузкаПродаж.xlsx";
// Шаг 4. Оборачиваем попытку сохранения в блок исключения, так как у пользователя может не быть прав на запись в каталог
Попытка
// Используем системный перечислитель ТипФайлаТабличногоДокумента для указания формата XLSX
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
ПоказатьПредупреждение(, "Файл успешно сохранен на диск по пути: " + ПутьКФайлу);
Исключение
ВызватьИсключение "Не удалось сохранить файл. Ошибка: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Обратите внимание на метод Записать(). Его первый параметр принимает строку с полным путем к создаваемому файлу, а второй определяет формат. Платформа 1С 8.3 поддерживает сохранение во множество типов файлов, среди которых:
ТипФайлаТабличногоДокумента.XLSX — современный формат Excel (рекомендуется);ТипФайлаТабличногоДокумента.XLS — устаревший формат Excel 97-2003;ТипФайлаТабличногоДокумента.PDF — документ в формате PDF;ТипФайлаТабличногоДокумента.MXL — собственный формат таблиц 1С.Если вам требуется создать не сложную таблицу Excel, а простой текстовый файл (например, лог-файл работы обработки или файл выгрузки данных), то для этого применяется специализированный объект ЗаписьТекста. Посмотрим на практический пример создания текстового файла:
&НаКлиенте
Процедура ЗаписатьПростойТекст(Команда)
ПутьКФайлу = "C:\temp\ПростойЛог.txt";
// Создаем объект ЗаписьТекста.
// Параметры: Путь к файлу, Кодировка, Разделитель строк, Режим перезаписи (Ложь - перезаписать файл)
Запись = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8, Символы.ПС, Ложь);
// Записываем необходимые строки программно
Запись.ЗаписатьСтроку("--- Старт логирования процесса ---");
Запись.ЗаписатьСтроку("Операция выполнена успешно в: " + ТекущаяДата());
Запись.ЗаписатьСтроку("--- Конец логирования ---");
// КРИТИЧЕСКИ ВАЖНО: Обязательно закрываем объект, чтобы освободить файл в ОС и физически сбросить буфер на диск
Запись.Закрыть();
ПоказатьПредупреждение(, "Текстовый файл успешно записан!");
КонецПроцедуры
Перейдем ко второй части нашего разбора: как загрузить внешний файл с компьютера пользователя и сохранить его непосредственно внутри базы данных 1С 8.3. Этот процесс кардинально отличается от сохранения на диск.
В управляемом приложении работа с файлами строится на строгом разделении контекста клиента и сервера. Напрямую прочитать файл с диска пользователя на сервере невозможно. Процесс состоит из трех последовательных шагов:
ХранилищеЗначения.Рассмотрим современный асинхронный код для реализации этой логики:
// Шаг 1. Инициируем выбор файла на клиенте
&НаКлиенте
Процедура ЗагрузитьФайлВБазу1С(Команда)
// Настраиваем параметры диалога выбора файла
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов("Выберите файл для загрузки в 1С");
ПараметрыДиалога.Фильтр = "Документы Excel (*.xlsx)|*.xlsx|Все файлы (*.*)|*.*";
// Описываем обработчик оповещения, который сработает после того, как пользователь выберет файл
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораФайлаЗавершение", ЭтотОбъект);
// Интерактивно открываем диалог и автоматически отправляем файл во временное хранилище
НачатьПомещениеФайлаНаСервер(ОписаниеОповещения, , , , ПараметрыДиалога, УникальныйИдентификатор);
КонецПроцедуры
// Шаг 2. Принимаем результат выбора файла на клиенте
&НаКлиенте
Процедура ПослеВыбораФайлаЗавершение(РезультатПомещения, ДополнительныеПараметры) Экспорт
// Если пользователь отменил выбор в диалоговом окне
Если РезультатПомещения = Неопределено Или РезультатПомещения.ПомещениеФайлаОтменено Тогда
Возврат;
КонецЕсли;
// Извлекаем адрес временного хранилища, куда платформа временно загрузила файл
АдресВременногоХранилища = РезультатПомещения.Адрес;
ИмяФайла = РезультатПомещения.СсылкаНаФайл.Имя;
// Передаем управление на сервер для окончательной записи в СУБД
ЗаписатьДанныеВБазуНаСервере(АдресВременногоХранилища, ИмяФайла);
ПоказатьПредупреждение(, "Файл '" + ИмяФайла + "' успешно загружен и записан в базу данных 1С!");
КонецПроцедуры
// Шаг 3. Записываем файл в базу данных (на сервере)
&НаСервереБезКонтекста
Процедура ЗаписатьДанныеВБазуНаСервере(АдресХранилища, ИмяФайла)
// Представим, что у нас есть справочник "ДоговорыКонтрагентов".
// Создадим в нем новый элемент программно для демонстрации.
// В реальной задаче вы, скорее всего, будете записывать файл в существующий документ или карточку контрагента.
НовыйДоговор = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
НовыйДоговор.Наименование = "Договор (присоединенный файл: " + ИмяФайла + ")";
// Получаем двоичные данные файла из временного хранилища по переданному адресу
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
// Записываем данные в реквизит объекта.
// Реквизит "ФайлХранилище" в метаданных справочника должен иметь тип "ХранилищеЗначения"
// Используем сжатие данных (степень сжатия от 0 до 9, где 9 - максимальное сжатие) для экономии места в СУБД
НовыйДоговор.ФайлХранилище = Новый ХранилищеЗначения(ДвоичныеДанныеФайла, Новый СжатиеДанных(9));
// Физически записываем созданный элемент справочника в СУБД
НовыйДоговор.Записать();
КонецПроцедуры
В современных конфигурациях 1С, разработанных на базе БСП (Библиотеки Стандартных Подсистем), ручное программирование записи файлов в базу данных практически не требуется. Для этих целей предназначена стандартная подсистема "Работа с файлами".
В БСП этот процесс устроен следующим образом:
Контрагенты) создается подчиненный справочник (например, КонтрагентыПрисоединенныеФайлы).РаботаСФайламиКлиент.ДобавитьФайлы().Поэтому при работе в типовых конфигурациях всегда анализируйте возможности БСП перед тем, как приступать к написанию собственного велосипеда для загрузки внешних файлов.
Мы подробно разобрали оба ключевых сценария работы с файлами в 1С 8.3. Теперь вы точно знаете разницу между локальным сохранением табличных документов с помощью ТабличныйДокумент.Записать() и помещением двоичных файлов внутрь СУБД через ХранилищеЗначения, и сможете легко использовать данные примеры в своих внешних обработках.