Как сохранить табличный документ в 1С с определенным именем файла и без ошибок кодировки

1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке печатных форм в среде «1С:Предприятие» программисты часто сталкиваются с задачей автоматизации рутинных действий пользователя. Одно из таких действий — сохранение сформированного отчета или печатной формы в файл (например, в формате Excel или PDF). По умолчанию платформа предлагает сохранить документ с пустым именем файла или использует стандартный заголовок формы. Это заставляет пользователя вручную копировать название документа (например, «Заказ клиента №15 от 10.10.2023»), что замедляет работу и приводит к ошибкам.

Попытка решить эту задачу «в лоб» через свойство ИспользуемоеИмяФайла у объекта ТабличныйДокумент часто заканчивается неудачей. В этой статье мы подробно разберем, почему штатные механизмы могут не срабатывать, как реализовать программное сохранение с нужным именем файла на обычных формах, как избежать проблемы с «кракозябрами» в Excel и как эта задача элегантно решается в современных конфигурациях на базе Библиотеки стандартных подсистем (БСП).

Почему стандартное свойство ИспользуемоеИмяФайла не работает?

Рассмотрим ситуацию, с которой столкнулся автор темы. В коде прописывается вполне логичная строка:

ТабДокумент.ИспользуемоеИмяФайла = Строка(СсылкаНаОбъект);

Однако при выводе формы печати и нажатии на стандартную кнопку сохранения имя файла в диалоговом окне все равно остается пустым. Почему так происходит?

Дело в том, что в большинстве типовых конфигураций (особенно прошлых поколений, таких как УПП 1.2, УТ 10.3, БП 1.6) вывод документов на печать осуществляется не напрямую, а через вспомогательные общие формы. Функция УниверсальныеМеханизмы.НапечататьДокумент() создает форму-обертку, в которую помещается поле табличного документа. Когда пользователь нажимает кнопку сохранения на панели этой общей формы, управление берет на себя код самой формы, а не системная команда табличного документа. Общая форма «не знает» о том, что вы записали в свойство ИспользуемоеИмяФайла исходного табличного документа, и открывает стандартный пустой диалог.

Интересная особенность: если вывести документ на экран напрямую методом ТабДокумент.Показать(), то свойство ИспользуемоеИмяФайла отработает корректно, и платформа автоматически подставит нужное значение в имя файла. Но такой подход лишает пользователя сервисных функций общей формы печати (отправка по почте, выбор количества копий, двухсторонняя печать и т.д.).

Решение для обычных форм: добавление собственной кнопки сохранения

Если мы работаем в конфигурациях на обычных формах (например, УПП) и хотим дать пользователю возможность сохранять документ в один клик с правильным именем, лучшим решением будет добавление на форму печати отдельной команды (кнопки) «Сохранить». В обработчике этой кнопки мы программно инициализируем диалог выбора файла.

Давайте разберем по шагам, как должен выглядеть правильный код этой процедуры:


Процедура КоманднаяПанельФормыСохранитьПоЗаголовку(Кнопка)
    
    ТабДок = ПечатныйДокумент; // Получаем наш табличный документ
    
    // Инициализируем диалог выбора файла в режиме сохранения
    Режим = РежимДиалогаВыбораФайла.Сохранение; 
    Диалог = Новый ДиалогВыбораФайла(Режим); 
    
    Диалог.Заголовок = "Выбор файла для сохранения"; 
    Диалог.Фильтр = "Файл Excel (*.xls)|*.xls|Документ PDF (*.pdf)|*.pdf";
    Диалог.Расширение = "xls";
    
    // Формируем имя файла на основе объекта печати
    ИмяФайлаПоУмолчанию = Строка(ОбъектПечати);
    Диалог.ПолноеИмяФайла = СокрЛП(ИмяФайлаПоУмолчанию);
    
    Если Не Диалог.Выбрать() Тогда
        Возврат; // Пользователь отказался от сохранения
    КонецЕсли;
    
    // Определяем формат сохранения на основе выбранного расширения
    РасширениеФайла = ВРег(Прав(Диалог.ПолноеИмяФайла, 3));
    
    Если РасширениеФайла = "XLS" Тогда
        ТабДок.Записать(Диалог.ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLS); 
    ИначеЕсли РасширениеФайла = "PDF" Тогда
        ТабДок.Записать(Диалог.ПолноеИмяФайла, ТипФайлаТабличногоДокумента.PDF);
    Иначе
        // По умолчанию сохраняем в родном формате MXL
        ТабДок.Записать(Диалог.ПолноеИмяФайла, ТипФайлаТабличногоДокумента.MXL);
    КонецЕсли;
    
    Предупреждение("Документ успешно сохранен!");
    
КонецПроцедуры

Разбор критической ошибки: Почему появляются «кракозябры» при открытии файла?

Обратите внимание на ключевой момент в коде выше. Первоначальный вариант автора темы содержал ошибку:

ТабДок.Записать(Диалог.ПолноеИмяФайла);

При таком вызове файл записывался на диск с расширением .xls, но при открытии его в Microsoft Excel программа выдавала предупреждение о несовпадении формата, а внутри таблицы отображались нечитаемые символы («кракозябры»).

Причина проблемы: Метод Записать() объекта ТабличныйДокумент принимает два параметра. Первый параметр — имя файла, второй (необязательный) — формат сохранения (тип ТипФайлаТабличногоДокумента). Если второй параметр не указан, платформа 1С по умолчанию сохраняет файл в своем внутреннем бинарном формате MXL, независимо от того, какое расширение (например, .xls или .doc) вы прописали в первом параметре. В итоге на диске оказывается файл MXL, переименованный в XLS, который Excel, естественно, не может корректно прочесть.

Решение: Всегда явно указывайте тип файла вторым параметром при вызове метода Записать(). Для сохранения в старый формат Excel 97-2003 используйте ТипФайлаТабличногоДокумента.XLS. Для современных версий настоятельно рекомендуется использовать формат ТипФайлаТабличногоДокумента.XLSX.

Современный подход в управляемых формах (на базе БСП)

Если вы работаете в современных конфигурациях 1С (таких как ERP 2, УТ 11, БП 3.0, ЗУП 3.1), разработанных с использованием Библиотеки стандартных подсистем (БСП), вам вообще не потребуется вручную переопределять диалоги выбора файлов или писать сложные обработчики.

В БСП вывод на печать стандартизирован. Имя файла, подставляемое при сохранении печатной формы на диск или при отправке по электронной почте, настраивается на этапе формирования коллекции печатных форм в модуле менеджера объекта.

Рассмотрим, как это реализовать в процедуре Печать модуля менеджера документа:


Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    // Проверяем наличие нашей печатной формы в коллекции
    ПечатнаяФорма = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "ИмяВашейПечатнойФормы");
    Если ПечатнаяФорма <> Неопределено Тогда
        
        ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
        ПечатнаяФорма.ТабличныйДокумент = ТабличныйДокумент;
        
        // Задаем индивидуальные имена файлов для сохранения каждого документа
        ИменаФайлов = Новый Соответствие;
        Для Каждого СсылкаНаДокумент Из МассивОбъектов Цикл
            // Формируем красивое представление, например: "Заказ клиента №15 от 10.10.2023"
            ПредставлениеДокумента = Строка(СсылкаНаДокумент);
            
            // Обязательно очищаем имя от символов, запрещенных операционной системой
            ОчищенноеИмяФайла = ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыВИмениФайла(ПредставлениеДокумента, "-");
            
            ИменаФайлов.Вставить(СсылкаНаДокумент, ОчищенноеИмяФайла);
        КонецЦикла;
        
        // Передаем соответствие имен в специальное свойство БСП
        ПечатнаяФорма.ИмяФайлаПечатнойФормы = ИменаФайлов;
        
    КонецЕсли;
    
КонецПроцедуры

При использовании этого механизма БСП самостоятельно сделает следующее:

  1. При нажатии пользователем кнопки «Сохранить» в форме печати предложит именно то имя файла, которое привязано к конкретному документу в соответствии.
  2. При отправке печатной формы по электронной почте файл вложения будет автоматически переименован согласно заданному шаблону.
  3. При сохранении пачки документов в один архив файлы будут разложены с понятными человекочитаемыми именами.

Важность очистки имен файлов от недопустимых символов

При динамическом формировании имен файлов на основе реквизитов документов (например, номеров с косой чертой вроде "Акт № 123/П-4") велика вероятность столкнуться с системной ошибкой записи. Операционные системы Windows и Linux накладывают жесткие ограничения на использование спецсимволов в путях файлов.

К числу запрещенных символов относятся: / \ : * ? " < > |. Если попытаться передать строку с этими знаками в диалог или метод Записать(), программа выдаст исключение или проигнорирует команду.

Если вы разрабатываете решение на БСП, всегда используйте готовую функцию очистки: ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыВИмениФайла(). Если же вы пишете решение для старой конфигурации с нуля, напишите простую вспомогательную функцию для удаления или замены недопустимых знаков:


Функция ОчиститьИмяФайла(Знач ИсходноеИмя) Экспорт
    
    ЗапрещенныеСимволы = "/\:*?""<>|";
    Результат = ИсходноеИмя;
    
    Для Индекс = 1 По СтрДлина(ЗапрещенныеСимволы) Цикл
        СимволЗамены = Сред(ЗапрещенныеСимволы, Индекс, 1);
        Результат = СтрЗаменить(Результат, СимволЗамены, "-");
    КонецЦикла;
    
    Возврат СокрЛП(Результат);
    
КонецФункции

Подведем итоги

Мы проанализировали особенности работы с сохранением табличных документов в 1С. Для успешного решения задачи автоподстановки имени файла помните следующие правила:

← На главную