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