Почему возникает ошибка «Недопустимое значение параметров» при программном добавлении кнопки на форму 1С?

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

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

Причина ошибки: правила именования элементов формы

Выясним причину падения кода. Обратимся к первому параметру метода Элементы.Добавить(Имя, ТипЭлемента, Родитель). Первый параметр принимает уникальное строковое имя создаваемого элемента управления. В платформе 1С:Предприятие к имени любого элемента интерфейса предъявляются строгие требования формирования системных идентификаторов:

  1. Имя элемента не должно содержать пробелов и знаков препинания (скобок, кавычек, дефисов, точек и т.д.).
  2. Имя не может начинаться с цифры.
  3. Имя должно состоять только из букв, цифр и знака подчеркивания.
  4. Имя элемента должно быть уникальным в пределах коллекции Элементы текущей формы.

Частая ошибка заключается в попытке передать в качестве системного имени пользовательский текст кнопки, содержащий пробелы (например, "Все оставшееся в ЗБ" или "Произвольный"). Для отображения читаемого текста пользователю предназначено отдельное свойство — Заголовок, тогда как свойство Имя отвечает исключительно за идентификацию объекта в коде.

Пошаговое решение: разделение системного имени и заголовка кнопки

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

Посмотрим на пример правильного обхода и создания кнопок в подменю:


&НаСервере
Процедура СоздатьКнопкиВПодменюНаСервере()

    МассивЗаголовков = Новый Массив;
    МассивЗаголовков.Добавить("Все оставшееся в ЗБ");
    МассивЗаголовков.Добавить("Все из остатка на заданную сумму реализации");
    МассивЗаголовков.Добавить("Все из остатка по виду залога");
    МассивЗаголовков.Добавить("Все из остатка");
    МассивЗаголовков.Добавить("На основании документа (без проверки наличия)");
    МассивЗаголовков.Добавить("Произвольный");

    Счетчик = 0;
    Для Каждого ТекЗаголовок Из МассивЗаголовков Цикл
        Счетчик = Счетчик + 1;
        
        // Формируем корректный идентификатор без пробелов и спецсимволов
        ИмяЭлемента = "КнопкаПодбора_" + Формат(Счетчик, "ЧЦ=3; ЧВН=; ЧГ=0");
        
        // Создаем кнопку внутри группы или подменю (Элементы.Подбор)
        НоваяКнопка = Элементы.Добавить(ИмяЭлемента, Тип("КнопкаФормы"), Элементы.Подбор);
        НоваяКнопка.Заголовок = ТекЗаголовок;
    КонецЦикла;

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

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

Рассмотрим важную особенность платформы: сама по себе КнопкаФормы является лишь визуальным представлением. Если нажать на кнопку, у которой не определена команда, ничего не произойдет. Для того чтобы кнопка выполняла код, ее необходимо связать с командой формы через свойство ИмяКоманды.

Разберем полный алгоритм программного создания связки «Команда + Кнопка»:

  1. Создание команды формы в коллекции Команды с валидным системным именем (без пробелов).
  2. Назначение обработчика в свойство команды Действие. Платформа требует передать строку с точным именем экспортной процедуры модуля формы. Обратите внимание: динамически сгенерировать тело исполняемого алгоритма нельзя, процедура-обработчик должна быть заранее написана разработчиком в модуле формы.
  3. Создание кнопки в коллекции Элементы с указанием родительского контейнера (например, подменю или командной панели).
  4. Связывание кнопки и команды путем заполнения свойства кнопки ИмяКоманды.

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


&НаСервере
Процедура ДобавитьКомандыИКнопкиНаСервере()

    МассивВариантов = Новый Массив;
    МассивВариантов.Добавить("ВсеОставшееся");
    МассивВариантов.Добавить("ВсеИзОстатка");

    Для Каждого Вариант Из МассивВариантов Цикл
        ИмяКоманды = "Команда_" + Вариант;
        ИмяКнопки  = "Кнопка_" + Вариант;

        // 1. Проверяем уникальность и создаем команду
        Если Команды.Найти(ИмяКоманды) = Неопределено Тогда
            НоваяКоманда = Команды.Добавить(ИмяКоманды);
            НоваяКоманда.Заголовок = "Выполнить " + Вариант;
            НоваяКоманда.Действие  = "ОбработчикНажатияДинамическойКнопки";
        КонецЕсли;

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

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

&НаКлиенте
Процедура ОбработчикНажатияДинамическойКнопки(Команда)
    // Обработка нажатия динамической кнопки
    ПоказатьОповещениеПользователя("Нажата команда: " + Команда.Имя);
КонецПроцедуры

Технические правила и ограничения платформы

При работе с динамическими элементами управляемых форм необходимо учитывать следующие правила платформы 1С:

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

Альтернативное решение: выпадающее меню на клиенте

Если цель состоит лишь в том, чтобы предоставить пользователю список для выбора нужного действия, не обязательно изменять структуру формы на сервере. Рассмотрим более легковесный подход с использованием метода ПоказатьВыборИзМеню().

На форме создается одна статическая кнопка, а в ее клиентском обработчике отображается динамический список значений:


&НаКлиенте
Процедура КнопкаПодборНажатие(Элемент)

    СписокВыбора = Новый СписокЗначений;
    СписокВыбора.Добавить("ОстатокЗБ", "Все оставшееся в ЗБ");
    СписокВыбора.Добавить("ОстатокСумма", "Все из остатка на заданную сумму реализации");
    СписокВыбора.Добавить("ОстатокВидЗалога", "Все из остатка по виду залога");
    СписокВыбора.Добавить("ОстатокВсе", "Все из остатка");

    Оповещение = Новый ОписаниеОповещения("ПослеВыбораВарианта", ЭтотОбъект);
    ПоказатьВыборИзМеню(Оповещение, СписокВыбора, Элемент);

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

&НаКлиенте
Процедура ПослеВыбораВарианта(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    Если ВыбранныйЭлемент = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Выполняем требуемый алгоритм в зависимости от ВыбранныйЭлемент.Значение
    Сообщить("Выбран пункт: " + ВыбранныйЭлемент.Представление);
КонецПроцедуры

Такой подход избавляет от лишних серверных вызовов для перерисовки формы и полностью исключает ошибки валидации имен элементов.

← На главную