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