Как программно добавить вычисляемое поле в схему компоновки данных (СКД) и избежать ошибки «Поле не найдено»?

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

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

Различие между вычисляемыми и пользовательскими полями

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

  1. Вычисляемые поля (объект ВычисляемоеПолеКомпоновкиДанных) — добавляются непосредственно в объект СхемаКомпоновкиДанных. Они становятся частью метаданных схемы и видны в дереве доступных полей наравне с полями из запроса.
  2. Пользовательские поля — добавляются в КомпоновщикНастроек. Они позволяют пользователю (или программно) создать поле выражения или поле выбора, не затрагивая саму структуру схемы.

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

Шаг 1. Программное добавление поля в схему

Рассмотрим пример кода, в котором мы получаем макет схемы из отчета и добавляем в него новое вычисляемое поле. Важно помнить, что путь к данным должен быть уникальным и написан латиницей (или кириллицей без пробелов), чтобы СКД могла однозначно к нему обращаться.


// Получаем схему из макета отчета
СКД = Отчеты.Выработка.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

// Добавляем новое вычисляемое поле
ПолеКлиент = СКД.ВычисляемыеПоля.Добавить();
ПолеКлиент.ПутьКДанным = "PayerType"; // Уникальный идентификатор поля
ПолеКлиент.Заголовок = "Тип плательщика";
ПолеКлиент.Выражение = "ВЫБОР КОГДА ЗаказНаряд.ВидРемонта.КодВыгрузки = ""КР"" ТОГДА ""Клиент"" ИНАЧЕ ""Прочее"" КОНЕЦ";

Обратите внимание: в свойстве Выражение используется синтаксис языка выражений СКД, а не чистого SQL. Здесь можно использовать конструкции ВЫБОР, ЕСТЬNULL, а также функции общих модулей (если они удовлетворяют требованиям доступности).

Шаг 2. Критический этап — инициализация компоновщика

Выясним причину, по которой чаще всего возникает ошибка «Поле не найдено». Проблема заключается в том, что КомпоновщикНастроек инициализируется на основании схемы. Если вы сначала инициализировали компоновщик, а потом добавили поле в объект СКД, компоновщик «не узнает» о существовании нового поля.

Правильный порядок действий:

  1. Получить объект СхемаКомпоновкиДанных.
  2. Внести изменения в коллекцию ВычисляемыеПоля.
  3. Поместить измененную схему во временное хранилище.
  4. Инициализировать КомпоновщикНастроек, передав ему адрес этого хранилища.

Посмотрим на реализацию этого алгоритма:


// 1. Помещаем модифицированную схему в хранилище
АдресСхемы = ПоместитьВоВременноеХранилище(СКД, Новый УникальныйИдентификатор);

// 2. Создаем источник доступных настроек на базе новой схемы
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы);

// 3. Инициализируем компоновщик
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);

// 4. Загружаем настройки (например, настройки по умолчанию)
КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);

Шаг 3. Вывод поля в отчет (Выбранные поля)

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


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

Особенности работы с Библиотекой Стандартных Подсистем (БСП)

Если вы работаете в современной конфигурации на базе БСП (например, ERP, УТ 11, БП 3.0), платформа накладывает свои ограничения на программное изменение отчетов. При использовании стандартных форм отчетов БСП, настройки могут кэшироваться или перекрываться механизмами вариантов отчетов.

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


// Это критично для отчетов на БСП
ЭтаФорма.НастройкиОтчета.СхемаМодифицирована = Истина;

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

Использование функций общих модулей в вычисляемых полях

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

Предположим, у нас есть общий модуль РаботаСАвтомобилями с функцией ОпределитьСтатус(Параметр). Тогда в коде добавления поля выражение будет выглядеть так:


ПолеСтатус = СКД.ВычисляемыеПоля.Добавить();
ПолеСтатус.ПутьКДанным = "StatusCustom";
ПолеСтатус.Выражение = "РаботаСАвтомобилями.ОпределитьСтатус(ЗаказНаряд.Ссылка)";

Важное условие: Общий модуль должен иметь флаги «Сервер» и «Вызов сервера» (или «Внешнее соединение»), а функция должна быть помечена словом Экспорт.

Резюме и типичные ошибки

Подводя итог, кратко перечислим основные причины неудач при программной работе с полями СКД:

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

← На главную