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