Почему метод ИзменитьРеквизиты() выдает ошибку несоответствия типов при удалении реквизитов формы?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При динамической модификации управляемых форм в 1С часто возникает необходимость программно создать, удалить или пересоздать реквизиты (например, динамические колонки таблицы значений). Для этой цели используется метод контекста формы ИзменитьРеквизиты(). Однако разработчики нередко сталкиваются с ошибкой «Несоответствие типов» при попытке удалить существующие реквизиты. Разберем по шагам, почему возникает эта ошибка и как правильно вызывать метод.

Причина ошибки: разница параметров для добавления и удаления

Проанализируем сигнатуру и назначение параметров метода ИзменитьРеквизиты():

Синтаксис метода выглядит следующим образом: ИзменитьРеквизиты(ДобавляемыеРеквизиты, УдаляемыеРеквизиты).

  1. Первый параметр (ДобавляемыеРеквизиты): принимает Массив, элементами которого являются объекты типа РеквизитФормы.
  2. Второй параметр (УдаляемыеРеквизиты): принимает Массив, элементами которого являются строки — имена или пути к удаляемым реквизитам формы (тип Строка).

Типичная ошибка заключается в том, что разработчик получает реквизиты через функцию ПолучитьРеквизиты() и пытается передать полученные объекты РеквизитФормы напрямую во второй массив:


// ОШИБОЧНЫЙ КОД:
Рек = ПолучитьРеквизиты();
МассивУдаляемых = Новый Массив;
МассивУдаляемых.Добавить(Рек[1]); // Ошибка! Передается объект типа РеквизитФормы
ИзменитьРеквизиты(, МассивУдаляемых);

Так как платформа ожидает строковое имя реквизита, а получает объект РеквизитФормы, возникает исключение «Несоответствие типов».

Правильный способ удаления реквизитов формы

Чтобы удалить реквизит формы, необходимо во второй массив добавлять исключительно его строковое имя (свойство Имя или строковый путь к реквизиту).

Посмотрим на корректный пример удаления конкретного реквизита по имени:


// Корректное удаление по строковому имени
МассивУдаляемых = Новый Массив;
МассивУдаляемых.Добавить("СводнаяТаблица"); // Имя удаляемого реквизита строкой

ИзменитьРеквизиты(, МассивУдаляемых);

Если требуется динамически определить имя реквизита из списка реквизитов формы, обратимся к свойству Имя:


РеквизитыФормы = ПолучитьРеквизиты();
МассивУдаляемых = Новый Массив;

// Добавляем строковое имя реквизита
МассивУдаляемых.Добавить(РеквизитыФормы[1].Имя);

ИзменитьРеквизиты(, МассивУдаляемых);

Пакетное пересоздание таблицы реквизитов

Рассмотрим распространенную задачу: требуется полностью удалить динамическую таблицу значений на форме и пересоздать ее с новой структурой колонок. Для оптимальной производительности рекомендуется выполнять удаление старых и добавление новых реквизитов за один вызов метода ИзменитьРеквизиты().

Разберем готовый пример создания и пересоздания структуры реквизитов:


&НаСервере
Процедура ПересоздатьСводнуюТаблицу()

    // 1. Формируем массив на удаление старых реквизитов
    МассивУдаляемых = Новый Массив;
    МассивУдаляемых.Добавить("СводнаяТаблица");

    // 2. Формируем массив на добавление новых реквизитов
    МассивДобавляемых = Новый Массив;
    
    // Создаем саму таблицу
    МассивДобавляемых.Добавить(Новый РеквизитФормы("СводнаяТаблица", Новый ОписаниеТипов("ТаблицаЗначений")));
    
    // Добавляем колонки в создаваемую таблицу
    МассивДобавляемых.Добавить(Новый РеквизитФормы("ФИО", Новый ОписаниеТипов("СправочникСсылка.ФизическиеЛица"), "СводнаяТаблица", "ФИО"));
    МассивДобавляемых.Добавить(Новый РеквизитФормы("ФормаОбучения", Новый ОписаниеТипов("СправочникСсылка.ФормыОбучения"), "СводнаяТаблица", "ФормаОбучения"));

    КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДаты.Дата);
    Счетчик = 0;
    Для Каждого СтрДисциплина Из Объект.Дисциплины Цикл
        Счетчик = Счетчик + 1;
        МассивДобавляемых.Добавить(Новый РеквизитФормы("Отметка" + Строка(Счетчик), Новый ОписаниеТипов("СправочникСсылка.Отметки"), "СводнаяТаблица", "Отметка"));
        МассивДобавляемых.Добавить(Новый РеквизитФормы("ДатаЗанятия" + Строка(Счетчик), Новый ОписаниеТипов("Дата", , , КвалификаторыДаты), "СводнаяТаблица", "ДатаЗанятия"));
    КонецЦикла;

    // 3. Выполняем удаление и добавление за один вызов
    ИзменитьРеквизиты(МассивДобавляемых, МассивУдаляемых);

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

Важные особенности и рекомендации

  1. Удаление подчиненных колонок: При удалении составного реквизита (например, ТаблицаЗначений) достаточно передать во второй массив только имя самой таблицы ("СводнаяТаблица"). Все подчиненные колонки платформа удалит автоматически.
  2. Связанные элементы формы: Метод ИзменитьРеквизиты() изменяет только данные (реквизиты) формы. Визуальные элементы (ТаблицаФормы, ПолеФормы), связанные с удаляемыми реквизитами, не удаляются автоматически. Их необходимо удалять отдельно через коллекцию Элементы.Удалить(...) во избежание ошибок интерфейса.
  3. Обращение по индексу: Крайне не рекомендуется удалять реквизиты, обращаясь к элементам массива ПолучитьРеквизиты()[Индекс] по числовому номеру. Порядок следования реквизитов в массиве не гарантируется, поэтому следует явно передавать строковые имена или искать нужный элемент по условию Свойство.Имя = "...".
  4. Контекст выполнения: Метод ИзменитьРеквизиты() доступен только на сервере в контексте формы (директива &НаСервере). В процедурах &НаСервереБезКонтекста или на стороне клиента вызвать данный метод нельзя.
← На главную