При программном создании элементов управляемой формы в 1С можно столкнуться с ситуацией, когда выполнение кода неожиданно прерывается без видимых сообщений об ошибке. Особенно часто это происходит при работе в серверных процедурах, например, в обработчике события ПриСозданииНаСервере. Разберем типичный случай: код успешно создает команду формы, но "падает" на строке добавления самого элемента (кнопки, поля и т.д.).
Проанализируем ситуацию, когда при попытке выполнить следующий код, происходит сбой:
// Команда создается успешно
НоваяКоманда = Форма.Команды.Добавить("ЗаСчетКредита");
НоваяКоманда.Заголовок = "За счет кредита";
НоваяКоманда.Действие = "ЗаСчетКредита";
// На этой строке выполнение кода прекращается
НовыйЭлемент = Форма.Элементы.Вставить("ЗаСчетКредита", Тип("КнопкаФормы"), ГруппаПраваяКнопки);
НовыйЭлемент.Заголовок = "За счет кредита";
НовыйЭлемент.ИмяКоманды = "ЗаСчетКредита";
Выясним, как правильно диагностировать и устранить эту проблему.
Первая сложность заключается в том, что ошибка возникает в серверной процедуре, и стандартные сообщения пользователю не выводятся. Конструкция Попытка...Исключение, без дополнительной обработки, просто "проглотит" ошибку, и мы не узнаем причину сбоя.
Часто начинающие разработчики пытаются использовать Сообщить(ИнформацияОбОшибке()), но это неверный подход, так как он вернет не описание ошибки, а строковое представление структуры ИнформацияОбОшибке.
Правильный способ — использовать функцию ОписаниеОшибки() внутри блока Исключение. Она возвращает подробный текст последней возникшей ошибки.
Модифицируем код для отладки:
Попытка
НовыйЭлемент = Форма.Элементы.Добавить("ЗаСчетКредита", Тип("КнопкаФормы"), ГруппаПраваяКнопки);
Исключение
// Получаем полное описание ошибки
ТекстОшибки = ОписаниеОшибки();
// В серверном коде надежнее использовать запись в журнал регистрации
ЗаписьЖурналаРегистрации("МояПодсистема.ОшибкаСозданияЭлемента",
УровеньЖурналаРегистрации.Ошибка, , ,
ТекстОшибки);
// Или можно просто вывести сообщение, если это допустимо в вашем контексте
// Сообщить(ТекстОшибки);
КонецПопытки;
После применения этого подхода мы получаем конкретное сообщение: "Ошибка при вызове метода контекста (Добавить): Недопустимое значение параметров". Теперь у нас есть отправная точка для дальнейшего анализа.
Это сообщение прямо указывает на то, что один из аргументов, переданных в метод Элементы.Добавить() (или Элементы.Вставить()), является неверным. Рассмотрим синтаксис метода:
Элементы.Добавить(Имя, Тип, [Родитель])
Имя (Строка): Уникальный идентификатор нового элемента в пределах формы.Тип (Тип): Тип создаваемого элемента, например, Тип("КнопкаФормы").Родитель (ГруппаФормы, необязательный): Группа, в которую будет помещен элемент.В 99% случаев ошибка "Недопустимое значение параметров" при вызове этого метода связана с первым параметром — Имя. Платформа "1С:Предприятие" требует, чтобы имена всех элементов на форме были строго уникальными. Если вы пытаетесь добавить элемент с именем, которое уже используется другим элементом, вы получите именно эту ошибку.
Чтобы избежать ошибки, необходимо перед созданием нового элемента убедиться, что элемента с таким именем на форме еще нет. Для этого идеально подходит метод коллекции элементов формы Найти(). Он возвращает найденный элемент или Неопределено, если элемент с указанным именем отсутствует.
Вот как выглядит надежный код, который сначала проверяет уникальность имени, а затем создает элемент:
ИмяНовогоЭлемента = "ЗаСчетКредита";
// Проверяем, нет ли уже элемента с таким именем
Если Форма.Элементы.Найти(ИмяНовогоЭлемента) = Неопределено Тогда
// Элемента нет, можно безопасно создавать команду и кнопку
// Создаем команду
НоваяКоманда = Форма.Команды.Добавить(ИмяНовогоЭлемента);
НоваяКоманда.Заголовок = "За счет кредита";
НоваяКоманда.Действие = ИмяНовогоЭлемента; // Имя процедуры-обработчика на клиенте
// Создаем элемент-кнопку
НовыйЭлемент = Форма.Элементы.Добавить(ИмяНовогоЭлемента, Тип("КнопкаФормы"), ГруппаПраваяКнопки);
НовыйЭлемент.Заголовок = "За счет кредита";
НовыйЭлемент.ИмяКоманды = ИмяНовогоЭлемента; // Связываем кнопку с командой
Иначе
// Элемент уже существует. Ничего не делаем или выводим отладочное сообщение.
ЗаписьЖурналаРегистрации("МояПодсистема.СозданиеЭлемента",
УровеньЖурналаРегистрации.Предупреждение, , ,
"Попытка повторного создания элемента формы '" + ИмяНовогоЭлемента + "'.");
КонецЕсли;
Важный момент: имя элемента и имя связанной с ним команды часто делают одинаковыми для удобства, как в примере. Важно помнить, что это две разные сущности в двух разных коллекциях: Форма.Элементы и Форма.Команды. Ошибка возникает именно при дублировании имени в коллекции Форма.Элементы.
Таким образом, "молчаливое" падение кода при программном добавлении элемента формы почти всегда вызвано попыткой создать элемент с неуникальным именем. Алгоритм решения проблемы прост:
Попытка...Исключение.ОписаниеОшибки() для получения точного текста ошибки и запишите его в журнал регистрации.Форма.Элементы.Найти() перед вызовом методов Добавить() или Вставить().Также не забывайте о следующих моментах:
ПриСозданииНаСервере.Добавить() vs Вставить(): Метод Добавить() помещает элемент в конец дочерних элементов родителя. Метод Вставить() позволяет указать конкретный элемент, перед которым нужно разместить новый, давая больше контроля над порядком. Оба метода вызовут ошибку при неуникальном имени.