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