Как проверить, существует ли параметр в макете 1С перед его заполнением?

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

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

В этой статье мы подробно разберем, как обойти это ограничение, рассмотрим несколько эффективных способов проверки существования параметров и выясним, какой из них является наиболее производительным в различных ситуациях.

Метод 1. Безопасное заполнение через метод «Заполнить»

Рассмотрим самый элегантный и рекомендуемый способ, который позволяет вообще избежать явной проверки на существование. Метод Заполнить() коллекции параметров работает по принципу соответствия: он берет данные из источника (например, структуры или строки выборки запроса) и копирует их только в те параметры макета, имена которых совпадают с ключами источника.

Проанализируем пример, когда нам нужно заполнить параметры в шапке документа:


// Создаем структуру с данными, которые хотим передать в макет
ДанныеДляЗаполнения = Новый Структура;
ДанныеДляЗаполнения.Вставить("НомерДокумента", Объект.Номер);
ДанныеДляЗаполнения.Вставить("ДатаДокумента", Объект.Дата);
ДанныеДляЗаполнения.Вставить("СпецПоле", "Дополнительная информация");

// Даже если в макете нет параметра "СпецПоле", ошибки не будет
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Заполнить(ДанныеДляЗаполнения);

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

Метод 2. Использование блока «Попытка — Исключение»

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


Функция ПараметрОбластиСуществует(ИмяПараметра, ОбластьМакета)
    Попытка
        ТестовоеЗначение = ОбластьМакета.Параметры[ИмяПараметра];
        Возврат Истина;
    Исключение
        Возврат Ложь;
    КонецПопытки;
КонецФункции

Разберем ситуацию: этот метод прост в реализации, однако его не рекомендуется использовать внутри больших циклов (например, при выводе тысяч строк в отчет). Порождение исключения в 1С — ресурсоемкая операция, которая может значительно замедлить формирование печатной формы.

Метод 3. Проверка через вспомогательную структуру (Универсальный способ)

Существует оригинальный способ проверки, основанный на механизме ЗаполнитьЗначенияСвойств. Идея заключается в том, чтобы попытаться перенести значение из коллекции параметров в структуру, где заранее подготовлено поле с уникальным идентификатором. Посмотрим на реализацию:


Функция ЕстьВОбластиПараметр(Область, ИмяПараметра)
    УникальныйИД = Новый УникальныйИдентификатор;
    // Создаем структуру, где ключ — имя искомого параметра
    СтруктураПроверки = Новый Структура(ИмяПараметра, УникальныйИД);
    
    // Пытаемся заполнить структуру из параметров области
    ЗаполнитьЗначенияСвойств(СтруктураПроверки, Область.Параметры);
    
    // Если значение изменилось, значит параметр в макете существует
    Если УникальныйИД <> СтруктураПроверки[ИмяПараметра] Тогда
        Возврат Истина;
    Иначе
        Возврат Ложь;
    КонецЕсли;
КонецФункции

Этот метод работает быстрее, чем «Попытка — Исключение», так как не вызывает системных прерываний при отсутствии свойства.

Метод 4. Полный анализ состава параметров области

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


// Пример перебора ячеек в области для поиска параметров
Для НомерСтроки = Область.Верх По Область.Низ Цикл
    Для НомерКолонки = Область.Лево По Область.Право Цикл
        ТекущаяЯчейка = Область.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
        Если ТекущаяЯчейка.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Параметр Тогда
            Сообщить("Найден параметр: " + ТекущаяЯчейка.Параметр);
        ИначеЕсли ТекущаяЯчейка.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Шаблон Тогда
            // В шаблонах может быть несколько параметров в одной ячейке
            Сообщить("Найдена ячейка-шаблон: " + ТекущаяЯчейка.Текст);
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

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

Метод 5. Использование Библиотеки стандартных подсистем (БСП)

Если ваша конфигурация построена на базе БСП, то в вашем распоряжении есть готовые инструменты. В модуле ОбщегоНазначенияКлиентСервер существует функция ЕстьРеквизитИлиСвойствоОбъекта. Несмотря на то, что она чаще применяется к структурам и объектам данных, в некоторых версиях платформы и БСП она корректно отрабатывает и для коллекций параметров.


Если ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Область.Параметры, "МойПараметр") Тогда
    Область.Параметры.МойПараметр = "Значение";
КонецЕсли;

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

Рекомендации по выбору решения

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

  1. Если нужно просто заполнить макет данными: Всегда используйте Параметры.Заполнить(). Это самый быстрый и безопасный способ, встроенный в платформу.
  2. Если нужно заполнять параметры выборочно в цикле: Предварительно соберите данные в Структуру, а затем вызовите Заполнить() один раз в конце цикла для всей области.
  3. Если требуется логика «Если параметр есть, то...»: Используйте вспомогательную функцию с Попытка — Исключение, если это происходит редко, или метод со Структурой и ЗаполнитьЗначенияСвойств, если важна скорость.
  4. Если вы создаете универсальный редактор макетов: Используйте перебор ячеек области для получения точного списка имен всех параметров.

Помните, что хорошей практикой в 1С считается проектирование макета таким образом, чтобы программный код «знал» о его составе. Если макет часто меняется пользователем, старайтесь использовать тип заполнения «Шаблон» — он более лоялен к отсутствующим данным в тексте и не вызывает критических ошибок при выводе области.

← На главную