В процессе разработки на платформе 1С:Предприятие 8.3 часто возникают задачи, когда необходимо модифицировать отчет «на лету», не изменяя основную схему компоновки данных (СКД) в конфигураторе. Одной из таких задач является программное добавление вычисляемого поля. Рассмотрим подробно, как это реализовать правильно, какие подводные камни могут встретиться и почему стандартный подход иногда выдает ошибку «Поле не найдено».
Для начала проанализируем ситуацию: часто разработчики путают вычисляемые поля схемы и пользовательские поля настроек. Несмотря на схожий результат (появление нового столбца с расчетами), технически это разные механизмы:
ВычисляемоеПолеКомпоновкиДанных) — добавляются непосредственно в объект СхемаКомпоновкиДанных. Они становятся частью метаданных схемы и видны в дереве доступных полей наравне с полями из запроса.КомпоновщикНастроек. Они позволяют пользователю (или программно) создать поле выражения или поле выбора, не затрагивая саму структуру схемы.Если ваша цель — жестко задать алгоритм расчета поля в коде и сделать его доступным для выбора в настройках, правильнее использовать именно вычисляемые поля схемы.
Рассмотрим пример кода, в котором мы получаем макет схемы из отчета и добавляем в него новое вычисляемое поле. Важно помнить, что путь к данным должен быть уникальным и написан латиницей (или кириллицей без пробелов), чтобы СКД могла однозначно к нему обращаться.
// Получаем схему из макета отчета
СКД = Отчеты.Выработка.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// Добавляем новое вычисляемое поле
ПолеКлиент = СКД.ВычисляемыеПоля.Добавить();
ПолеКлиент.ПутьКДанным = "PayerType"; // Уникальный идентификатор поля
ПолеКлиент.Заголовок = "Тип плательщика";
ПолеКлиент.Выражение = "ВЫБОР КОГДА ЗаказНаряд.ВидРемонта.КодВыгрузки = ""КР"" ТОГДА ""Клиент"" ИНАЧЕ ""Прочее"" КОНЕЦ";
Обратите внимание: в свойстве Выражение используется синтаксис языка выражений СКД, а не чистого SQL. Здесь можно использовать конструкции ВЫБОР, ЕСТЬNULL, а также функции общих модулей (если они удовлетворяют требованиям доступности).
Выясним причину, по которой чаще всего возникает ошибка «Поле не найдено». Проблема заключается в том, что КомпоновщикНастроек инициализируется на основании схемы. Если вы сначала инициализировали компоновщик, а потом добавили поле в объект СКД, компоновщик «не узнает» о существовании нового поля.
Правильный порядок действий:
СхемаКомпоновкиДанных.ВычисляемыеПоля.КомпоновщикНастроек, передав ему адрес этого хранилища.Посмотрим на реализацию этого алгоритма:
// 1. Помещаем модифицированную схему в хранилище
АдресСхемы = ПоместитьВоВременноеХранилище(СКД, Новый УникальныйИдентификатор);
// 2. Создаем источник доступных настроек на базе новой схемы
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы);
// 3. Инициализируем компоновщик
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
// 4. Загружаем настройки (например, настройки по умолчанию)
КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);
После того как поле добавлено в схему и компоновщик обновлен, нам нужно программно «поставить галочку» напротив этого поля, чтобы оно попало в результат отчета. Проанализируем, как добавить поле в выбранные поля конкретной группировки или всего отчета.
Настройки = КомпоновщикНастроек.Настройки;
// Добавляем поле в общие выбранные поля отчета
ВыбранноеПоле = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных("PayerType"); // Должно совпадать с ПутьКДанным
ВыбранноеПоле.Использование = Истина;
ВыбранноеПоле.Заголовок = "Тип плательщика";
Если вы работаете в современной конфигурации на базе БСП (например, ERP, УТ 11, БП 3.0), платформа накладывает свои ограничения на программное изменение отчетов. При использовании стандартных форм отчетов БСП, настройки могут кэшироваться или перекрываться механизмами вариантов отчетов.
Важный нюанс: если вы правите схему в модуле формы (например, в процедуре ПриСозданииНаСервере), необходимо явно указать системе, что схема была изменена. Для этого используется специальное свойство формы:
// Это критично для отчетов на БСП
ЭтаФорма.НастройкиОтчета.СхемаМодифицирована = Истина;
Без этой строки система может проигнорировать ваши программные изменения и использовать стандартную схему из макета при окончательной генерации отчета.
Иногда логика вычисления настолько сложна, что её невозможно описать конструкцией ВЫБОР КОГДА. В этом случае мы можем вызвать экспортную функцию общего модуля. Рассмотрим пример:
Предположим, у нас есть общий модуль РаботаСАвтомобилями с функцией ОпределитьСтатус(Параметр). Тогда в коде добавления поля выражение будет выглядеть так:
ПолеСтатус = СКД.ВычисляемыеПоля.Добавить();
ПолеСтатус.ПутьКДанным = "StatusCustom";
ПолеСтатус.Выражение = "РаботаСАвтомобилями.ОпределитьСтатус(ЗаказНаряд.Ссылка)";
Важное условие: Общий модуль должен иметь флаги «Сервер» и «Вызов сервера» (или «Внешнее соединение»), а функция должна быть помечена словом Экспорт.
Подводя итог, кратко перечислим основные причины неудач при программной работе с полями СКД:
Отчеты.Имя.ПолучитьМакет(...), ваши изменения пропадут. Всегда используйте переменную с модифицированным объектом.Инициализировать() у компоновщика настроек.СКД.ПоляИтога.Следуя этим правилам и соблюдая структуру инициализации объектов СКД, вы сможете гибко управлять составом полей в отчетах любой сложности.