Как добавить вычисляемую колонку в табличную часть или динамический список на управляемых формах 1С 8.3?

Программист 1С v8.3 (Управляемые формы)
← К списку

В процессе работы с управляемыми формами 1С 8.3, мы часто сталкиваемся с задачей отображения данных, которых нет напрямую в источнике, но которые можно получить путем расчета или анализа других полей. Одним из таких типовых сценариев является создание "вычисляемых" колонок, например, булева поля, значение которого зависит от условия, или колонки "Сумма", которая пересчитывается "на лету" при изменении цены и количества. Давайте вместе разберем, как эффективно решать эту задачу, используя различные подходы в зависимости от контекста – будь то динамический список или обычная табличная часть формы. Мы рассмотрим подробнее каждый из вариантов, выясним их особенности и предоставим примеры кода.

Вычисляемые поля в динамическом списке

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

  1. Использование произвольного запроса. Самый распространенный способ – это модификация текста запроса динамического списка. Мы можем добавить в него любое выражение SQL, которое будет рассчитывать необходимое значение. Рассмотрим пример, где нам нужно булево поле, показывающее, является ли источник 'Нашим'.

    Предположим, у нас есть поле Конт.ВидИсточника, и мы хотим создать булеву колонку ЭтоНашИсточник.

    
    ВЫБРАТЬ
        Конт.Ссылка КАК Ссылка,
        Конт.Наименование КАК Наименование,
        ВЫБОР КОГДА Конт.ВидИсточника = &ВидИсточникаНаш ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ КАК ЭтоНашИсточник
    ИЗ
        Справочник.Контрагенты КАК Конт
    

    После модификации запроса, нам останется добавить новое поле в список полей динамического списка и разместить его на форме как обычную колонку. Убедитесь, что добавляемое поле (в нашем случае ЭтоНашИсточник) существует в запросе, используемом для заполнения динамического списка.

  2. Программное добавление колонок и изменение запроса. В более сложных сценариях, когда требуется динамически изменять запрос или добавлять колонки, мы можем использовать объект СхемаЗапроса. Этот подход обеспечивает гибкость, позволяя адаптировать запрос и состав полей в зависимости от условий или настроек пользователя.

    Для отображения булевых значений на форме, мы используем элемент Поле флажка. Мы можем настроить его вид (Флажок или Тумблер) и даже задать отображаемые названия для значений Истина и Ложь.

Работа с реквизитами формы в табличных частях

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

  1. Добавление реквизита формы в табличную часть. Прежде всего, нам необходимо добавить новый реквизит в саму форму. Этот реквизит будет иметь тип данных, соответствующий нашим вычислениям (например, Булево для флажка или Число для суммы). Затем, в свойствах элемента формы 'Таблица', мы добавляем новую колонку и указываем для нее Путь к данным, который будет ссылаться на созданный нами реквизит формы. Например, если мы добавили реквизит формы с именем ЭтоНашИсточник и типом Булево, то путь к данным для колонки будет ТабличнаяЧасть.<ИмяКолонкиРеквизитаФормы>, где <ИмяКолонкиРеквизитаФормы> – это имя нашего реквизита формы в контексте табличной части.

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

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

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

"На лету" пересчеты в табличных частях

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

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

    Рассмотрим пример пересчета суммы строки в табличной части:

    
    // В модуле формы
    &НаСервере
    Процедура ТоварыКоличествоПриИзмененииНаСервере(Элемент)
        ПересчитатьСуммуСтрокиТабличнойЧасти(Элемент.ТекущиеДанные);
    КонецПроцедуры
    
    &НаСервере
    Процедура ТоварыЦенаПриИзмененииНаСервере(Элемент)
        ПересчитатьСуммуСтрокиТабличнойЧасти(Элемент.ТекущиеДанные);
    КонецПроцедуры
    
    &НаСервере
    Процедура ПересчитатьСуммуСтрокиТабличнойЧасти(СтрокаТабличнойЧасти)
        СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
    КонецПроцедуры
    

    В этом примере ТоварыКоличествоПриИзмененииНаСервере и ТоварыЦенаПриИзмененииНаСервере – это обработчики, которые вызываются при изменении соответствующих полей. Функция ПересчитатьСуммуСтрокиТабличнойЧасти выполняет сам расчет. Обратите внимание, что мы выносим логику пересчета в отдельную процедуру для удобства и повторного использования.

  2. Производительность при больших объемах данных. При работе с табличными частями, содержащими большое количество строк или использующими сложные вычисления, следует быть внимательными к производительности. Событие ПриВыводеСтроки (если оно используется для каких-либо вычислений, хотя в управляемых формах для ТаблицаЗначений оно отсутствует, но аналогичная логика может быть реализована в других местах) или частые обращения к серверу могут замедлить интерфейс.

    Мы рекомендуем следующие подходы для оптимизации:

    • Кэширование результатов. Если какие-либо данные используются многократно для вычислений, кэшируйте их на клиенте или сервере, чтобы избежать повторных запросов к базе данных.
    • Один большой запрос вместо множества мелких. Если есть необходимость получить данные для всех строк табличной части, старайтесь выполнить один запрос, который вернет все необходимые данные, а не множество запросов для каждой строки.
    • Отключение видимости ненужных колонок. Если какая-то вычисляемая колонка не нужна постоянно, управляйте ее видимостью, чтобы не выполнять лишние расчеты и не тратить ресурсы на ее отображение.

Общие рекомендации и особенности управляемых форм

Мы выяснили, что управляемые формы имеют свои особенности, которые отличают их от обычных форм.

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

  2. Типы связи элемента "Таблица". Элемент управляемой формы "Таблица" может быть связан с различными типами данных, включая ДинамическийСписок, ТабличнаяЧасть, СписокЗначений, ДеревоЗначений. Полный набор свойств и методов доступен, когда таблица связана именно с ДинамическимСписком. При работе с другими типами, функционал может быть более ограничен, и придется прибегать к созданию реквизитов формы и программному управлению.

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

  4. Модульность кода. Для обеспечения лучшей организации и повторного использования кода, мы настоятельно рекомендуем выносить логику пересчета и заполнения вычисляемых полей в общие модули. Это позволит использовать одни и те же функции в разных формах и обработчиках, упрощая поддержку и разработку.

Надеемся, что этот подробный разбор поможет вам эффективно создавать и управлять вычисляемыми колонками в управляемых формах 1С 8.3. Мы рассмотрели различные подходы, и теперь вы сможете выбрать наиболее подходящий для вашей конкретной задачи.

← К списку