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