Переход с обычных форм на управляемые в платформе 1С:Предприятие 8.3 — это не просто смена интерфейса, но и глубокое изменение архитектуры работы с данными. Одной из самых частых проблем, с которой сталкиваются разработчики, является ошибка Ссылка не определено или Объект не определен при попытке выполнить код, который раньше успешно работал в обычных формах. Рассмотрим подробнее, почему это происходит и как правильно адаптировать логику печати под современные стандарты.
Проанализируем ситуацию, описанную автором темы. В старых конфигурациях (на обычных формах) код формирования печатных форм чаще всего располагался в модуле объекта документа. В этом модуле разработчику доступны все реквизиты объекта напрямую (например, Дата, Номер) или через ключевые слова ЭтотОбъект и Ссылка. Платформа автоматически подтягивает данные текущего документа в память.
В современных конфигурациях на управляемых формах (особенно использующих БСП — Библиотеку стандартных подсистем) логика формирования печатных форм выносится в модуль менеджера. Это делается из соображений производительности:
Основная проблема заключается в том, что в модуле менеджера отсутствует контекст конкретного экземпляра объекта. Там нет ни ЭтотОбъект, ни предопределенной переменной Ссылка. Менеджер — это набор общих инструментов для всех документов данного типа, и он "не знает", какой именно документ вы хотите напечатать, пока вы явно не передадите ему ссылку на него.
Если бы ваш код действительно находился в модуле объекта, то обращение Ссылка.ДатаСФ было бы избыточным, но допустимым. Однако правильнее было бы обращаться напрямую к реквизиту. Посмотрим на правильный пример для модуля объекта:
Если Не ЗначениеЗаполнено(ДатаСФ) Тогда
ДП = "''___''________________20__г";
Иначе
ДП = Формат(ДатаСФ, "ДФ=dd.MM.yyyy");
КонецЕсли;
Здесь ДатаСФ доступна напрямую, так как модуль объекта уже содержит в себе данные реквизитов. Но, как выяснилось в обсуждении, код автора находился в модуле менеджера, где такой подход работать не будет.
Рассмотрим, как правильно реализовать ту же логику в модуле менеджера. Обычно процедура печати в управляемом приложении выглядит так:
Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Логика подготовки данных
КонецПроцедуры
В данном контексте у нас есть МассивОбъектов, содержащий ссылки на документы. Чтобы получить значение ДатаСФ, мы должны либо обратиться к базе данных через запрос (рекомендуемый способ), либо получить данные напрямую от ссылки (допустимо для простых задач, но медленнее).
Выясним, как интегрировать вашу проверку в стандартный цикл печати. Мы создаем запрос, выбираем нужные поля и в цикле обхода выборки формируем строку даты.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДокументТаблица.ДатаСФ КАК ДатаСФ,
| ДокументТаблица.Ссылка КАК Ссылка
|ИЗ
| Документ.НашДокумент КАК ДокументТаблица
|ГДЕ
| ДокументТаблица.Ссылка В(&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Не ЗначениеЗаполнено(Выборка.ДатаСФ) Тогда
ДП = "''___''________________20__г";
Иначе
ДП = Формат(Выборка.ДатаСФ, "ДФ=dd.MM.yyyy");
КонецЕсли;
// Далее код заполнения параметров макета...
КонецЦикла;
Если структура печатной формы простая и вы не хотите переписывать запросы, можно обратиться к реквизиту через ссылку. Однако помните, что каждое такое обращение вызывает неявный запрос к базе данных, что существенно замедляет печать большого количества документов.
// Предположим, мы перебираем МассивОбъектов
Для Каждого ТекущаяСсылка Из МассивОбъектов Цикл
Если Не ЗначениеЗаполнено(ТекущаяСсылка.ДатаСФ) Тогда
ДП = "''___''________________20__г";
Иначе
ДП = Формат(ТекущаяСсылка.ДатаСФ, "ДФ=dd.MM.yyyy");
КонецЕсли;
КонецЦикла;
Проанализируем функцию ЗначениеЗаполнено. В 1С пустая дата — это 01.01.0001 00:00:00. Ваша проверка корректно отсекает это значение. Однако при работе в управляемом интерфейсе стоит помнить о нескольких правилах:
Ссылка.ДатаСФ в коде модуля управляемой формы (в процедуре &НаКлиенте), вы бы получили ошибку еще раньше, так как на клиенте данные базы недоступны напрямую.Формат(Дата, "ДФ=dd.MM.yyyy") является стандартным и правильным способом. Альтернативно, формат можно задать в свойствах ячейки самого макета (Табличного документа), тогда код в модуле станет чище.Мы выяснили, что причина ошибки в управляемой форме кроется в смене контекста выполнения. Чтобы ваш код заработал:
Ссылка как контекстной переменной. Используйте ссылки, переданные в параметрах процедур.Соблюдение этих архитектурных принципов позволит вам избежать множества ошибок при разработке под управляемый интерфейс и обеспечит стабильную работу ваших печатных форм.