Как запретить печать непроведенных документов в 1С:УНФ

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

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

Способ 1. Использование стандартного свойства команды печати

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

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


&После("ДобавитьКомандыПечати")
Процедура _ДобавитьКомандыПечати(КомандыПечати)
    Для Каждого Команда Из КомандыПечати Цикл
        Команда.ПроверкаПроведенияПередПечатью = Истина;
    КонецЦикла;
КонецПроцедуры

Разберем, что происходит в этом фрагменте. Мы используем аннотацию &После, чтобы дополнить список команд. Цикл проходит по всем добавленным командам печати конкретного документа и устанавливает флаг проверки проведения. При таком подходе платформа сама, перед вызовом кода печати, проверит статус документа и выдаст пользователю стандартное предупреждение, если документ не проведен.

Способ 2. Глобальный перехват через «УправлениеПечатью»

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

Этот метод более радикальный, так как он срабатывает непосредственно в момент формирования макета. Проанализируем пример кода для расширения:


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

    Возврат ПродолжитьВызов(ИмяМенеджераПечати, ИменаМакетов, МассивТолькоПроведенных, ПараметрыПечати, ДопустимыеТипыОбъектовПечати);
    
КонецФункции

В данном примере мы используем аннотацию &Вместо. Мы создаем фильтр, который проверяет каждый документ из МассивОбъектов. Если документ не проведен, мы исключаем его из печати и выводим информационное сообщение. Это гарантирует, что даже при групповой печати в очередь попадут только корректные данные.

Важные нюансы реализации

При выборе метода реализации стоит обратить внимание на несколько критических моментов, с которыми мы можем столкнуться:

  1. Объекты без проведения. В 1С:УНФ есть объекты, которые не имеют статуса проведения (например, справочники или некоторые виды событий). Если применить универсальный код без проверки наличия реквизита Проведен, система вызовет исключение и аварийно завершит работу.
  2. Информирование пользователя. Если мы просто «молча» удалим документы из массива печати, пользователь может подумать, что программа зависла или сломалась. Обязательно используйте методы ОбщегоНазначенияКлиентСервер.СообщитьПользователю или стандартный Сообщить.
  3. Внешние печатные формы. Помните, что дополнительные отчеты и обработки, подключенные через справочник «Дополнительные отчеты и обработки», могут работать в обход стандартных механизмов БСП. Для них проверку проведения часто приходится прописывать внутри самой обработки в функции Печать().
  4. Групповая печать. Рассмотрим ситуацию, когда пользователь выделяет 50 документов в списке. Если часть из них не проведена, правильнее будет собрать список «проблемных» документов в одну строку и выдать одно общее предупреждение, вместо того чтобы спамить сообщениями о каждом документе по отдельности.

Использование переопределяемого модуля

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

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

← На главную