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