Ошибка «Не уникальное имя!» при программном создании элементов формы в 1С: причины и решение

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

При динамическом формировании элементов управления на обычной форме в 1С разработчики иногда сталкиваются с ошибкой: «Недопустимое значение параметра (параметр номер '2') (Не уникальное имя! (СПоле1))» при вызове метода ЭлементыФормы.Добавить(). В этой статье мы подробно разберем, почему возникает данная проблема и как гарантированно обеспечить уникальность имен создаваемых элементов.

Анализ ситуации: пересечение переменных во вложенных циклах

Рассмотрим распространенную ситуацию. Разработчик обходит список данных во внешнем цикле и динамически добавляет на панель формы новую страницу и поле табличного документа. Для формирования уникального имени элемента используется переменная-счетчик Н:


ИмяСтраницы = "ГП" + Строка(Н); 
ИмяПоля = "СПоле" + Строка(Н);
НовСтраница = СтраницыПанели.Страницы.Добавить(ИмяСтраницы, Строка(ГруппаПроектов));
НовПоле = ЭлементыФормы.Добавить(Тип("ПолеТабличногоДокумента"), ИмяПоля, Истина, СтраницыПанели);

Однако в процессе выполнения кода возникает ошибка неуникального имени уже на второй итерации внешнего цикла. Проанализируем алгоритм внимательнее и посмотрим на то, что происходит внутри тела внешнего цикла:


Для каждого Сп Из СписокПроектовОтбор Цикл
    // ...
    // Очистка отбора построителя
    ОтборКоличество = Построитель.Отбор.Количество();
    Для Н = 1 По ОтборКоличество Цикл
        Построитель.Отбор.Удалить(ОтборКоличество - Н);
    КонецЦикла; 
    
    // ...
    Н = Н + 1; // Увеличение счетчика
КонецЦикла;

Выясним причину сбоя: переменная Н, которая отвечает за нумерацию создаваемых элементов во внешнем цикле, повторно используется во внутреннем цикле Для Н = 1 По ОтборКоличество Цикл. В результате значение счетчика внешнего цикла сбрасывается или искажается. На следующей итерации внешнего цикла программа снова пытается создать элемент с именем СПоле1, что и приводит к исключению.

Главное правило: никогда не используйте одну и ту же счетчиковую переменную для внешних и вложенных циклов.

Способы обеспечения уникальности имен элементов формы

Разберем по шагам несколько надежных подходов, которые помогут избежать коллизий имен при программном создании элементов управления.

1. Исправление счетчиков и разделение переменных

Если для генерации имен используется счетчик, гарантируйте уникальность имени переменной цикла на каждом уровне вложенности. Например, используйте ИндексПроекта во внешнем цикле и ИндексОтбора во внутреннем:


ИндексПроекта = 1;
Для каждого Сп Из СписокПроектовОтбор Цикл 
    ИмяСтраницы = "ГП" + Строка(ИндексПроекта); 
    ИмяПоля = "СПоле" + Строка(ИндексПроекта);

    // Вложенный цикл очистки отбора использует другую переменную
    ОтборКоличество = Построитель.Отбор.Количество();
    Для СчетчикОтбора = 1 По ОтборКоличество Цикл
        Построитель.Отбор.Удалить(ОтборКоличество - СчетчикОтбора);
    КонецЦикла; 

    // Создание элементов
    НовСтраница = СтраницыПанели.Страницы.Добавить(ИмяСтраницы, Строка(Сп.Значение));
    НовПоле = ЭлементыФормы.Добавить(Тип("ПолеТабличногоДокумента"), ИмяПоля, Истина, СтраницыПанели);

    ИндексПроекта = ИндексПроекта + 1;    
КонецЦикла;

2. Проверка существования элемента перед добавлением

В обычных формах 1С коллекция ЭлементыФормы является единой для всей формы. Если обработка может запускаться повторно без перезапуска самой формы, ранее созданные элементы остаются в памяти. В таком случае перед добавлением нового элемента необходимо проверить его наличие с помощью метода Найти():


НовПоле = ЭлементыФормы.Найти(ИмяПоля);
Если НовПоле = Неопределено Тогда
    НовПоле = ЭлементыФормы.Добавить(Тип("ПолеТабличногоДокумента"), ИмяПоля, Истина, СтраницыПанели);
КонецЕсли;

Если элемент уже существует, мы просто получаем на него ссылку и переиспользуем его вместо повторного создания.

3. Генерация уникального имени на основе UUID

Если логика работы программы не требует строго фиксированных имен вроде СПоле1, СПоле2, можно формировать имя элемента на основе уникального идентификатора УникальныйИдентификатор. Это полностью исключит вероятность дублирования имен:


УникальныйХвост = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "_");
ИмяПоля = "СПоле_" + УникальныйХвост;

НовПоле = ЭлементыФормы.Добавить(Тип("ПолеТабличногоДокумента"), ИмяПоля, Истина, СтраницыПанели);

Рекомендации по работе с динамическими элементами

  1. Следите за именами переменных: не переопределяйте счетчики внешних циклов во внутренних инструкциях и запросах.
  2. Учитывайте область видимости: в обычных формах имя элемента должно быть уникальным в пределах всей формы, а не только отдельной страницы панели.
  3. Очищайте созданные элементы: при повторном формировании интерфейса удаляйте старые динамические элементы через ЭлементыФормы.Удалить() или переиспользуйте их.
← На главную