При разработке отчетов и обработок в 1С часто возникает ситуация: на форму выводится поле табличного документа, а на командную панель добавляется стандартная кнопка Сохранить из состава команд табличного документа. При первом нажатии открывается стандартный диалог выбора пути и формата файла, и документ успешно записывается на диск. Однако при повторном клике по кнопке диалоговое окно не появляется, из-за чего создается впечатление, что кнопка перестала реагировать на действия пользователя.
Разберем подробнее, почему платформа 1С ведет себя именно так, и рассмотрим все варианты реализации удобного сохранения для пользователей.
Поведение команды Сохранить в 1С полностью повторяет логику работы большинства офисных пакетов (например, текстовых и табличных редакторов):
Модифицированность равно Ложь), платформа может вовсе пропустить повторную физическую запись на диск. Для пользователя это выглядит как полное отсутствие реакции интерфейса.Проанализируем доступные способы решения данной задачи в зависимости от требований к интерфейсу.
Если требуется, чтобы при каждом нажатии кнопки пользователь обязательно выбирал каталог, имя файла или расширение, стандартная кнопка Сохранить не подходит по своей концепции.
Вместо нее выведем на командную панель стандартную команду Сохранить как… (Save As):
ТабличныйДокумент и перетащим на панель команду Сохранить как....В этом случае диалоговое окно сохранения будет открываться при каждом вызове команды без необходимости доработки программного кода.
Если по логике интерфейса требуется оставить стандартную кнопку Сохранить, но принудительно заставить ее снова запрашивать путь без закрытия формы, сбросим внутреннюю привязку к сохраненному файлу. Поскольку прямого метода очистки пути у объекта ТабличныйДокумент нет, создадим новый экземпляр документа и скопируем в него сформированные данные.
Посмотрим на пример процедуры обновления данных на форме:
&НаСервере
Процедура СброситьПривязкуТабличногоДокументаНаСервере()
// Создаем чистый экземпляр без сохраненного пути
НовыйТабДок = Новый ТабличныйДокумент;
// Копируем данные из текущего реквизита формы
НовыйТабДок.Вывести(ОтчетТабличныйДокумент);
// Переопределяем реквизит формы новым объектом
ОтчетТабличныйДокумент = НовыйТабДок;
КонецПроцедуры
После такой подмены внутренняя связь с предыдущим файлом на диске разрывается, и очередное нажатие стандартной кнопки Сохранить снова откроет диалоговое окно.
Наиболее гибким и понятным для пользователя решением является замена стандартной команды на собственную клиентскую команду. Это позволит не только гарантированно управлять выбором формата, но и отображать всплывающее уведомление об успешном завершении операции.
Разберем по шагам реализацию команды для тонкого клиента:
СохранитьТабличныйДокумент и назначим ей действие на клиенте.ДиалогВыбораФайла в режиме сохранения.Записать у табличного документа и покажем всплывающее оповещение с помощью ПоказатьОповещениеПользователя.Рассмотрим пример кода обработчика команды на клиенте:
&НаКлиенте
Процедура СохранитьТабличныйДокумент(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Заголовок = "Выберите путь для сохранения отчета";
Диалог.ПолноеИмяФайла = "Отчет.xlsx";
Диалог.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx|Документ PDF (*.pdf)|*.pdf|Табличный документ (*.mxl)|*.mxl";
ОповещениеЗавершения = Новый ОписаниеОповещения("ПослеВыбораФайлаДляСохранения", ЭтотОбъект);
Диалог.Показать(ОповещениеЗавершения);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораФайлаДляСохранения(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Или ВыбранныеФайлы.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ПутьКФайлу = ВыбранныеФайлы[0];
// Определяем тип файла по расширению
Расширение = ВРег(Сред(ПутьКФайлу, СтрНайти(ПутьКФайлу, ".", НаправлениеПоиска.СКонца) + 1));
ТипФайла = ТипФайлаТабличногоДокумента.XLSX;
Если Расширение = "PDF" Тогда
ТипФайла = ТипФайлаТабличногоДокумента.PDF;
ИначеЕсли Расширение = "MXL" Тогда
ТипФайла = ТипФайлаТабличногоДокумента.MXL;
КонецЕсли;
Попытка
ОтчетТабличныйДокумент.Записать(ПутьКФайлу, ТипФайла);
ПоказатьОповещениеПользователя("Успешно", , "Файл сохранен: " + ПутьКФайлу, КартинкаОповещенияПользователя.Информация);
Исключение
ВызватьИсключение "Не удалось сохранить файл: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Для работы в веб-клиенте прямая запись файла на диск может блокироваться политиками браузера. В этом случае сохранение организуется через временное хранилище на сервере с последующей передачей файла на клиент с помощью метода НачатьПолучениеФайлаССервера.