Наверняка многие разработчики и администраторы систем 1С сталкивались с настойчивой просьбой пользователей: «Нам нужно распечатать документ (например, заказ клиента или реализацию), но мы не хотим или не можем его сейчас провести!». По умолчанию современные типовые конфигурации 1С (такие как УТ 11, ERP 2, КА 2), построенные на Библиотеке стандартных подсистем (БСП), жестко блокируют эту возможность.
В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько эффективных способов обойти это ограничение как с помощью расширений, так и через внешние печатные формы.
Прежде чем переходить к коду, выясним причину такого поведения системы. Разработчики фирмы «1С» закладывают в логику решений простое правило: печатная форма — это официальный документ, подтверждающий совершение хозяйственной операции. Если документ не проведен, значит, операция не отражена в учете, движения по регистрам не сформированы, а данные внутри документа могут быть неполными или ошибочными. Чтобы уберечь бизнес от отправки клиентам некорректных бланков, БСП принудительно блокирует печать черновиков.
Разберем популярное заблуждение. В старых конфигурациях на обычных формах (например, УПП 1.3 или УТ 10.3) существовала стандартная настройка: достаточно было зайти в дополнительные права пользователя и установить галочку Печать непроведенных документов. В современных управляемых формах этой настройки больше нет. Механизмы БСП управляют печатью централизованно, поэтому нам придется прибегнуть к программным методам.
Рассмотрим самый изящный и современный способ, который не требует изменения типовой конфигурации и позволяет легко переносить изменения при обновлениях системы. За вывод кнопок печати в БСП отвечает механизм регистрации команд печати. В модуле менеджера каждого документа есть процедура ДобавитьКомандыПечати(КомандыПечати).
Каждая команда в этой таблице — это структура, у которой есть свойство ПроверкаПроведенияПередПечатью (тип Булево). По умолчанию оно принимает значение Истина. Наша задача — перехватить эту процедуру в расширении и принудительно установить свойство в значение Ложь.
Разберем по шагам, как это реализовать:
РеализацияТоваровУслуг).ДобавитьКомандыПечати с помощью аннотации &После.Напишем следующий код:
&После("ДобавитьКомандыПечати")
Процедура Расш1_ДобавитьКомандыПечати(КомандыПечати)
Для Каждого КомандаПечати Из КомандыПечати Цикл
// Отключаем проверку проведения для конкретной команды по её идентификатору
Если КомандаПечати.Идентификатор = "Накладная" Тогда
КомандаПечати.ПроверкаПроведенияПередПечатью = Ложь;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот способ безопасен и позволяет точечно управлять доступностью печати для конкретных форм документов, не затрагивая остальные механизмы системы. При необходимости можно использовать готовое расширение для печати непроведенных документов в 1С:КА, УТ 11 и ERP.
Проанализируем другой вариант, когда нам требуется быстро переопределить логику вызова стандартной команды печати. В форме команды печати конкретного документа (например, Документы.ЗаказКлиента.Команды.ПечатьЗаказКлиента) содержится процедура-обработчик ОбработкаКоманды.
Посмотрим на пример кода, который позволяет обойти проверку проведения для пользователей с административными правами:
&НаСервере
Функция РольДоступнаНаСервере(ИмяРоли)
Возврат РольДоступна(ИмяРоли);
КонецФункции
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// Проверяем, есть ли у пользователя ПолныеПрава.
// Если есть — сразу запускаем печать, минуя стандартную проверку проведения.
Если РольДоступнаНаСервере("ПолныеПрава") Или УправлениеПечатьюКлиент.ПроверитьДокументыПроведены(ПараметрКоманды, ПараметрыВыполненияКоманды.Источник) Тогда
УправлениеПечатьюКлиент.HighПоказатьИлиПечатать(
"Документ.ЗаказКлиента",
"ЗаказКлиента",
ПараметрКоманды,
Неопределено,
Неопределено
);
КонецЕсли;
КонецПроцедуры
Этот метод эффективно решает задачу непосредственно «в лоб», однако требует вмешательства в программный код команд формы, поэтому его также рекомендуется выносить в расширение.
Многие компании предпочитают использовать внешние печатные формы (ВПФ), чтобы не вносить изменения в основную конфигурацию. Но здесь разработчики сталкиваются с тем, что БСП автоматически блокирует вывод на печать непроведенного документа даже при вызове внешней обработки. Выясним, как обойти это поведение.
Вариант А. Переопределение поведения через модуль БСП
В БСП предусмотрен общий модуль ДополнительныеОтчетыИОбработкиКлиентПереопределяемый, в котором содержится процедура ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы. По умолчанию она пустая и создана специально для переопределения логики разработчиками. Мы можем добавить туда проверку типа документа и отключить стандартную обработку:
Процедура ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы(ПечатаемыеОбъекты, СтандартнаяОбработка)
Если ТипЗнч(ПечатаемыеОбъекты) = Тип("Массив") И ПечатаемыеОбъекты.Количество() > 0 Тогда
// Разрешаем печать без проведения для внешних форм Заказа Клиента
Если ТипЗнч(ПечатаемыеОбъекты[0]) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратите внимание: если просто написать СтандартнаяОбработка = Ложь; без проверки типов, система разрешит печать непроведенных документов абсолютно для всех ВПФ, что крайне нежелательно с точки зрения контроля учета.
Вариант Б. Обход проверки через клиентский метод в самой ВПФ
Существует еще более изящный способ, который вообще не требует создания расширений. Мы можем модифицировать структуру самой внешней обработки. Для этого в модуле объекта ВПФ в функции СведенияОВнешнейОбработке() настроим команду так, чтобы она использовала клиентский метод.
Вместо типа команды ВызовСерверногоМетода укажем вызов клиентского метода:
НоваяСтрока = ТаблицаКоманд.Добавить();
НоваяСтрока.Представление = "Печать без проведения";
НоваяСтрока.Идентификатор = "ПечатьБезПроведения";
НоваяСтрока.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
Затем в модуле формы внешней печатной формы создадим клиентскую процедуру Печать(), которая напрямую откроет стандартную форму вывода документов БСП:
&НаКлиенте
Процедура Печать(ИмяКоманды, МассивОбъектов, ПараметрыПечати = Неопределено, КоллекцияПечатныхФорм = Неопределено, ОбъектыПечати = Неопределено, ПараметрыВывода = Неопределено) Экспорт
ВыполняемаяКоманда = Параметры;
ПараметрыОткрытия = Новый Структура("ИсточникДанных, ПараметрыИсточника, КоллекцияПечатныхФорм");
ПараметрыОткрытия.ИсточникДанных = ВыполняемаяКоманда.ДополнительнаяОбработкаСсылка;
ПараметрыОткрытия.ПараметрыИсточника = Новый Структура("ИдентификаторКоманды, ОбъектыНазначения");
ПараметрыОткрытия.ПараметрыИсточника.ИдентификаторКоманды = ВыполняемаяКоманда.ИдентификаторКоманды;
ПараметрыОткрытия.ПараметрыИсточника.ОбъектыНазначения = ВыполняемаяКоманда.ОбъектыНазначения;
ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);
КонецПроцедуры
Поскольку вызов формы печати БСП происходит напрямую на стороне клиента, контролирующие механизмы проведения просто не успевают сработать и заблокировать операцию. Для реализации товаров также можно применить внешнюю печатную форму для печати непроведенных накладных.
Даже если вы успешно обошли программный запрет на печать непроведенного документа, вас может ожидать неприятный сюрприз. Например, при попытке распечатать форму ТОРГ-12 или УПД из непроведенного документа «Реализация товаров и услуг» на экран выводится абсолютно пустой бланк без товаров, либо система сообщает об ошибке «В документе отсутствуют товары».
Выясним причину этого поведения. В современных ERP-системах (ERP, КА, УТ) алгоритмы печати многих документов оптимизированы ради быстродействия. Они берут данные не напрямую из табличной части Товары самого документа, а из специализированных регистров накопления или служебных таблиц (например, табличной части ВидыЗапасов). Эти таблицы заполняются и движения по регистрам формируются исключительно в момент проведения документа. У непроведенного документа они абсолютно пусты, поэтому печатная форма не видит никаких данных.
Как решить эту проблему?
Если вам жизненно необходимо печатать такие сложные документы до проведения, стандартный механизм формирования макета не подойдет. Вам придется переписать логику получения данных для печати (лучше всего во внешней печатной форме):
Документ.РеализацияТоваровУслуг.Товары).Предоставление возможности печатать документы до проведения — это всегда риск для бизнеса. Менеджеры могут распечатать накладную, отдать её на склад, товар уедет, а документ так и останется непроведенным «черновиком», искажая складские остатки и финансовую отчетность. Поэтому такую возможность нужно строго регламентировать.
Поскольку стандартной галочки в пользовательских настройках больше нет, мы можем легко воссоздать её через расширение конфигурации:
РазрешитьПечатьНепроведенныхДокументов.
&После("ДобавитьКомандыПечати")
Процедура Расш1_ДобавитьКомандыПечати(КомандыПечати)
// Проверяем, есть ли у пользователя специальное разрешение
ЕстьДоступ = РольДоступна("РазрешитьПечатьНепроведенныхДокументов") Или РольДоступна("ПолныеПрава");
Если ЕстьДоступ Тогда
Для Каждого КомандаПечати Из КомандыПечати Цикл
Если КомандаПечати.Идентификатор = "Накладная" Тогда
КомандаПечати.ПроверкаПроведенияПередПечатью = Ложь;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
После этого администратору системы останется лишь создать соответствующий Профиль групп доступа, включить туда созданную роль и назначить этот профиль тем сотрудникам, которым действительно разрешено печатать черновики документов.
Мы подробно разобрали, как устроены механизмы контроля печати в современных конфигурациях 1С и какими способами можно обойти запрет на печать непроведенных документов. Наиболее гибким и безопасным решением является использование расширений конфигурации в сочетании с разграничением прав доступа пользователей. При реализации таких доработок всегда помните о контроле данных и не допускайте бесконтрольной печати документов, которые еще не отражены в учете.