К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как передать массив в форму в 1С

Как передать массив в форму 1С: параметры формы, ОткрытьФорму, ДанныеФормыВЗначение, хранилище значений. Примеры кода, типичные ошибки и ответы на вопросы.

Передача массива в форму — типичная задача при разработке на управляемых формах 1С: нужно показать список выбранных товаров, отобрать документы по списку ссылок, заполнить табличную часть заранее подготовленными данными. Главная сложность в том, что массив нельзя напрямую «прикрепить» к форме — нужно использовать один из штатных механизмов платформы.

Выбор способа зависит от контекста: открывается новая форма или массив нужно передать в уже открытую; данные нужны только при создании формы или должны остаться доступны позже; массив содержит примитивные значения или сложные объекты вроде ссылок и таблиц значений. Ниже разобраны все рабочие варианты с примерами кода.

Передача массива через параметры формы при открытии

Базовый и самый частый способ — структура параметров при вызове ОткрытьФорму. Платформа сериализует параметры и передаёт их в новую форму, где они доступны в обработчике ПриСозданииНаСервере через объект Параметры.

Пример вызывающего кода:

&НаКлиенте

Процедура ОткрытьПодбор(Команда)

МассивТоваров = Новый Массив;

Для Каждого Строка Из Объект.Товары Цикл

МассивТоваров.Добавить(Строка.Номенклатура);

КонецЦикла;

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("СписокТоваров", МассивТоваров);

ОткрытьФорму("ОбщаяФорма.ПодборТоваров", ПараметрыФормы, ЭтотОбъект);

КонецПроцедуры

В открываемой форме массив читается так:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("СписокТоваров") Тогда

Для Каждого Товар Из Параметры.СписокТоваров Цикл

НоваяСтрока = ТаблицаПодбора.Добавить();

НоваяСтрока.Номенклатура = Товар;

КонецЦикла;

КонецЕсли;

КонецПроцедуры

Ограничения параметров формы и проверка наличия значения

Через параметры можно передавать значения, которые платформа умеет сериализовать: примитивные типы, ссылки, массивы, структуры, списки значений. Нельзя передавать объекты типа ДокументОбъект, запросы, построители отчётов и другие несериализуемые данные — попытка вызовет ошибку или приведёт к потере содержимого.

Всегда проверяйте наличие параметра через Свойство() перед использованием: форму могут открыть из другого места конфигурации, и необъявленный параметр вызовет ошибку обращения к несуществующему полю структуры. Дополнительно проверяйте тип — если вместо массива пришло строковое значение, цикл Для Каждого упадёт с ошибкой.

Если Параметры.Свойство("СписокТоваров")

И ТипЗнч(Параметры.СписокТоваров) = Тип("Массив") Тогда

// работа с массивом

Иначе

// поведение по умолчанию, например пустая таблица

КонецЕсли;

Как сохранить массив в форме: реквизиты и таблицы значений

Параметры живут только на этапе создания. Чтобы массив оставался доступным всё время жизни формы, перенесите его в реквизит формы. Для массивов ссылок или примитивов подойдёт реквизит типа «СписокЗначений», для структурированных данных — таблица значений с нужными колонками.

Добавьте реквизит формы в конфигураторе (или программно через ИзменитьРеквизиты), а затем заполните его в ПриСозданииНаСервере. Таблица значений как реквизит формы дополнительно даёт готовое отображение на форме без ручного вывода данных.

Порядок действий
  1. 1
    Сформируйте массив в вызывающем коде
  2. 2
    Создайте структуру параметров и вставьте массив
  3. 3
    Откройте форму через ОткрытьФорму с параметрами
  4. 4
    В ПриСозданииНаСервере проверьте наличие и тип параметра
  5. 5
    Скопируйте данные в реквизит формы (таблицу значений или список значений)
  6. 6
    Проверьте, что данные отображаются корректно

Передача массива в уже открытую форму

Параметры работают только при создании формы. Если форма уже открыта и в неё нужно доставить массив (например, из обработки обновить список в главной форме), используйте механизм оповещений: Оповестить на клиенте и обработчик ОбработкаОповещения в принимающей форме.

&НаКлиенте

Процедура ОтправитьДанные(Команда)

Оповестить("ОбновитьСписокТоваров", МассивТоваров, ЭтотОбъект);

КонецПроцедуры

// В принимающей форме:

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ОбновитьСписокТоваров" Тогда

ОбработатьМассивНаСервере(Параметр);

КонецЕсли;

КонецПроцедуры

Проверяйте Источник, если одно и то же событие могут генерировать разные формы, — иначе форма отреагирует на чужое оповещение. Учтите ограничение: оповещение работает только между формами в пределах одного клиентского сеанса.

Передача больших массивов через временное хранилище

Когда массив большой (тысячи элементов, вложенные структуры, таблицы значений), передача через параметры увеличивает трафик между клиентом и сервером. Оптимальнее поместить данные во временное хранилище на сервере и передать в форму только адрес строкой.

&НаСервере

Функция ПодготовитьДанные()

АдресХранилища = ПоместитьВоВременноеХранилище(МассивДанных, УникальныйИдентификатор);

Возврат АдресХранилища;

КонецФункции

// В открываемой форме:

Данные = ПолучитьИзВременногоХранилища(Параметры.АдресДанных);

Если ТипЗнч(Данные) = Тип("Массив") Тогда

// обработка

КонецЕсли;

Передавайте вторым параметром УникальныйИдентификатор формы — тогда хранилище живёт, пока жива форма, и данные не удалятся преждевременно. Без привязки к форме содержимое хранилища может быть очищено между вызовами.

Сравнение способов

Параметры формы

Простой и надёжный вариант для новой формы и небольших массивов; не работает для уже открытой формы

Оповестить

Подходит для доставки данных в уже открытую форму; требует совпадения имён событий и работает только в одном сеансе

Временное хранилище

Лучший выбор для больших объёмов; требует управления временем жизни хранилища через УникальныйИдентификатор формы

Реквизит формы

Не способ передачи, а способ хранения: используется вместе с любым из вариантов, чтобы данные жили после создания формы

Типичные ошибки при передаче массива

Самая частая ошибка — обращение к Параметры.ИмяМассива без проверки Свойство(): при открытии формы из другого места код падает. Вторая по распространённости — попытка использовать параметры формы на клиенте или после создания формы, когда они уже недоступны.

Третья группа ошибок связана с типами: передача объекта ДокументОбъект вместо ссылки, передача таблицы значений через параметры (она не сериализуется — используйте хранилище), смешение контекстов сервера и клиента при работе с массивом ссылок.

Типичные ошибки
01
Обращение к параметру без проверки Свойство() — ошибка при открытии формы из другого места
02
Попытка передать таблицу значений через параметры — она не сериализуется, используйте временное хранилище
03
Использование Параметры вне ПриСозданииНаСервере — данные уже недоступны, нужен реквизит формы
04
Помещение в хранилище без УникальныйИдентификатор формы — данные удаляются до момента чтения
05
Передача ДокументОбъект вместо ссылки — ошибка сериализации, передавайте только ссылку

Как проверить, что массив дошёл до формы

Быстрая проверка — временный вывод в ПриСозданииНаСервере: Сообщить(Параметры.СписокТоваров.Количество()). Если количество совпадает с ожидаемым, передача работает, и проблему стоит искать в дальнейшей обработке. Если параметр отсутствует — проверяйте имя ключа в структуре параметров: опечатка в строковом ключе не вызывает ошибки на этапе компиляции.

Для таблицы значений в реквизите формы проверьте, что таблица выведена на форму (элемент формы связан с реквизитом) и что заполнение происходит на сервере до возврата управления клиенту. Для оповещений убедитесь, что принимающая форма открыта в момент вызова Оповестить — закрытая форма событие не получит.

Контрольные точки

Как проверить результат

Количество элементов в форме
Норма

Совпадает с количеством в исходном массиве

Тревожный признак

Ноль или меньше — проверяйте имя параметра и заполнение массива

Тип полученного значения
Норма

ТипЗнч возвращает Массив

Тревожный признак

Неопределено или строка — параметр не передан или испорчен

Данные после перезахода в обработчик
Норма

Реквизит формы сохраняет данные

Тревожный признак

Данные пропадают — массив не скопирован из Параметры в реквизит

Частые вопросы

Можно ли передать массив в форму записи регистра или документа?

Да, механизм одинаков для любых форм: ОткрытьФорму с параметрами работает и для форм объектов. Но учтите, что у формы документа часть параметров зарезервирована платформой (Ключ, ЗначенияЗаполнения и др.), поэтому давайте своим параметрам уникальные имена, например с префиксом.

Почему массив ссылок в форме отображается пустым?

Чаще всего массив заполнялся на клиенте значениями, полученными позже, или данные не скопированы из Параметры в реквизит формы. Проверьте, что перенос в реквизит выполняется в ПриСозданииНаСервере, а сам реквизит имеет подходящий тип (СписокЗначений или таблица значений).

Как передать массив структур в форму?

Массив структур с примитивными полями и ссылками сериализуется и передаётся через параметры так же, как обычный массив. Если структуры содержат таблицы значений или другие несериализуемые данные, помещайте весь массив во временное хранилище и передавайте адрес.

Чем отличается передача массива в управляемой и обычной форме?

В обычных формах массив можно передать через конструктор формы, экспортные переменные модуля формы или метод УстановитьПараметр — ограничений на сериализацию практически нет, так как всё выполняется в одном процессе. В управляемых формах действуют ограничения клиент-серверного взаимодействия, описанные в статье.

Как вернуть массив из открытой формы обратно в вызывающую?

Используйте ОткрытьФорму в режиме ожидания: ОткрытьФорму(..., Параметры, Владелец, , , , ОписаниеОповещения, РежимОткрытияОкна.БлокироватьОкноВладельца). В дочерней форме вызовите Закрыть(МассивРезультатов) — массив придёт в обработчик оповещения вызывающей формы как результат закрытия.

Итог

Что важно запомнить

Для новой формы массив передаётся через структуру параметров в ОткрытьФорму и читается в ПриСозданииНаСервере. Для уже открытой формы — через Оповестить, для больших объёмов — через временное хранилище с адресом. Всегда проверяйте наличие и тип параметра и копируйте данные в реквизит формы, если они нужны дольше этапа создания.