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

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

При разработке внешних печатных форм (ВПФ) в среде 1С:Предприятие 8.3 часто возникает бизнес-задача: запретить пользователям выводить на печать документы, которые еще не были проведены. Это критически важно для соблюдения регламентов учета, так как печатная форма непроведенного документа может содержать неактуальные или неподтвержденные данные.

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

Способ 1: Использование штатного параметра БСП «ПроверкаПроведенияПередПечатью»

Современные версии БСП (начиная с 3.0 и выше) предоставляют встроенный механизм проверки статуса документа перед выполнением команды печати. Для этого при регистрации внешней обработки необходимо правильно описать таблицу команд. Рассмотрим, как это сделать в модуле объекта вашей внешней печатной формы.

Проанализируем структуру функции СведенияОВнешнейОбработке. Нам необходимо добавить в таблицу команд колонку ПроверкаПроведенияПередПечатью и установить ее значение в Истина.


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

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

Способ 2: Использование методов программного интерфейса БСП

Существует более «современный» способ формирования структуры регистрации, который минимизирует вероятность ошибок в именах колонок. Рассмотрим пример использования общего модуля ДополнительныеОтчетыИОбработки.


Функция СведенияОВнешнейОбработке() Экспорт
    
    // Получаем стандартную структуру регистрации для версии БСП 3.0
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("3.0.2.1");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.2";
    ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Проверенная печатная форма";
    НоваяКоманда.Идентификатор = "ПФ_MXL_Проверка";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
    НоваяКоманда.Модификатор = "ПечатьMXL";
    
    // Если в вашей версии БСП свойство ПроверкаПроведенияПередПечатью доступно в объекте Команда, 
    // устанавливаем его напрямую:
    Если ПараметрыРегистрации.Команды.Колонки.Найти("ПроверкаПроведенияПередПечатью") <> Неопределено Тогда
        НоваяКоманда.ПроверкаПроведенияПередПечатью = Истина;
    КонецЕсли;
    
    Возврат ПараметрыРегистрации;
    
КонецФункции

Этот метод хорош тем, что он более устойчив к обновлениям платформы и конфигурации, так как опирается на штатные конструкторы объектов БСП.

Способ 3: Программная проверка внутри процедуры «Печать»

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

Обычно в модуле объекта ВПФ процедура печати выглядит следующим образом:


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    // Пройдемся по массиву объектов и проверим их статус
    Для Каждого СсылкаНаДокумент Из МассивОбъектов Цикл
        
        // Проверяем, проведен ли документ
        Если НЕ СсылкаНаДокумент.Проведен Тогда
            
            // Вариант 1: Жесткое прерывание через исключение
            // Не самый лучший вариант, так как прерывает печать всей пачки документов
            // ВызватьИсключение "Документ " + СсылкаНаДокумент + " не проведен!";
            
            // Вариант 2: Заполнение текста ошибки в ПараметрыВывода (рекомендуется)
            ТекстСообщения = СтрШаблон("Документ %1 не проведен и не может быть распечатан.", СсылкаНаДокумент);
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
            
            // Если мы хотим вывести общее системное предупреждение через БСП:
            ПараметрыВывода.ТекстОшибки = "Среди выбранных документов есть непроведенные. Печать отменена.";
            Продолжить; 
            
        КонецЕсли;
        
        // Логика формирования табличного документа...
        // СформироватьПечатнуюФорму(СсылкаНаДокумент);
        
    КонецЦикла;

КонецПроцедуры

Сравнение подходов и рекомендации

Выясним, какой из методов лучше использовать в различных ситуациях:

  1. Декларативный метод (параметр регистрации): Лучший выбор для стандартных конфигураций. БСП сама заблокирует кнопку печати или предложит провести документ еще на этапе нажатия кнопки в интерфейсе. Это наиболее дружелюбный интерфейс для пользователя (UX).
  2. Программный метод (в процедуре Печать): Необходим, когда логика проверки сложнее, чем просто «проведен/не проведен». Например, если вы хотите разрешить печать непроведенных документов для определенной роли пользователей или при наличии определенного флага в документе.
  3. Использование исключений: Рассмотрим ситуацию с ВызватьИсключение. Это самый быстрый способ «заткнуть дыру», но он выглядит как системная ошибка. Пользователь увидит красное окно, что может его напугать. Используйте этот метод только в крайнем случае.

Разберем по шагам реализацию через «ПараметрыВывода»

Когда мы работаем внутри механизма печати БСП, у нас есть доступ к структуре ПараметрыВывода. Это специальный контейнер, который возвращает информацию вызывающей форме. Если мы заполним в нем поле ТекстОшибки, платформа сама обработает это сообщение и выведет его пользователю в стандартном диалоговом окне.

Посмотрим на пример кода, который корректно обрабатывает массовую печать:


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

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

Резюмируя: для реализации жесткого запрета лучше всего комбинировать установку флага ПроверкаПроведенияПередПечатью = Истина в сведениях о внешней обработке и дополнительную проверку в коде процедуры Печать для гарантии стабильности работы механизма.

← На главную