При разработке отчетов на базе СхемыКомпоновкиДанных (СКД) в управляемом приложении часто возникает ситуация, когда отчет корректно работает в толстом клиенте, но выдает ошибку при запуске в тонком клиенте. Давайте разберемся, почему это происходит и как правильно организовать архитектуру кода, чтобы избежать подобных инцидентов.
Основная причина кроется в архитектурных особенностях платформы 1С. Объект КонструкторСхемыКомпоновкиДанных является серверным инструментом. Он предназначен для динамического конструирования схемы и требует доступа к объектам метаданных, которые доступны исключительно на стороне сервера. Тонкий клиент по своей сути ограничен: он не обладает полным функционалом для работы с конфигурацией и серверными объектами.
Если в вашем коде, который выполняется на клиенте (в модуле формы с директивой &НаКлиенте), происходит вызов конструктора СКД, система выдает ошибку, так как на клиентской стороне этот тип данных попросту отсутствует.
Если вы столкнулись с этой ошибкой в нетиповой конфигурации при открытии отчета, наиболее элегантным решением будет использование встроенных механизмов платформы для настройки формы. Вместо попыток инициализации объектов СКД «на лету» в процедурах, вызываемых на клиенте, используйте серверные процедуры настройки.
Рассмотрим пример кода, который позволяет инициализировать параметры отчета на сервере, не вызывая ошибку на клиенте:
Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт
Настройки.ФормироватьСразу = Истина;
Настройки.События.ПриСозданииНаСервере = Истина;
КонецПроцедуры
Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт
ОбъектыНазначения = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Форма.Параметры, "ОбъектыНазначения");
Если ОбъектыНазначения <> Неопределено Тогда
Форма.ФормаПараметры.УстановитьЗначениеПараметра("Регистратор", ОбъектыНазначения);
КонецЕсли;
КонецПроцедуры
Использование процедуры ОпределитьНастройкиФормы позволяет системе правильно распределить контексты выполнения, перенося логику инициализации на сервер, где КонструкторСхемыКомпоновкиДанных доступен и корректно работает.
Если вы анализируете чужой код в общей форме отчета и обнаружили строку, вызывающую ошибку, можно прибегнуть к приему с функцией Вычислить. Это позволяет скрыть от компилятора проверку типа на этапе проверки модуля.
Вместо прямого вызова:
Новый КонструкторСхемыКомпоновкиДанных()
Можно использовать:
Вычислить("Новый КонструкторСхемыКомпоновкиДанных()")
Внимание: данный метод является «костыльным». Он поможет избежать ошибки при компиляции, но если этот код будет реально вызван на стороне клиента, ошибка возникнет снова. Используйте его только в том случае, если вы уверены, что данный участок кода будет исполнен в серверном контексте, но платформа ошибочно выполняет предварительную проверку типа.
Чтобы избежать подобных ошибок в будущем, придерживайтесь следующих правил:
&НаКлиенте, &НаСервере). Весь код, работающий с метаданными и СКД, должен находиться в процедурах &НаСервере.ФормаОтчета, откройте эту форму в конфигураторе, найдите проблемную строку (согласно сообщению об ошибке) и проанализируйте, почему код пытается исполниться на клиенте. Возможно, достаточно просто добавить директиву &НаСервере к функции или процедуре, содержащей проблемный вызов.Работа с СКД требует четкого понимания того, где исполняется каждый фрагмент вашего кода. Соблюдая правила взаимодействия клиентской и серверной частей, вы навсегда забудете о проблемах с типами данных и сделаете ваши отчеты надежными и стабильными во всех режимах работы системы.