Как заполнить добавленные колонки в списке справочника в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Особенности архитектуры списка справочника в платформе 7.7

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

По этой причине понятие программного «заполнения строк по циклу» для формы списка справочника отсутствует: нельзя просто присвоить значение ячейке конкретной строки. Для решения задачи используется встроенный механизм динамического вычисления через текстовые колонки.

Пошаговая настройка текстовой колонки с формулой

Разберем классический способ добавления расчетного поля, применяемый в типовых конфигурациях (таких как «Торговля и Склад 9.2» или «Бухгалтерский учет»):

  1. Откроем форму списка справочника в конфигураторе.
  2. В табличную часть формы добавим новую колонку.
  3. В свойствах созданной колонки укажем тип данных Текст.
  4. В поле Формула пропишем вызов пользовательской функции модуля формы, например: ПолучитьЗначениеКолонки().
  5. В модуле формы опишем соответствующую контекстную функцию, возвращающую строковое или числовое значение для текущей отрисовываемой строки.

Посмотрим на базовый пример реализации такой функции:


Функция ПолучитьЗначениеКолонки()
    Перем Результат;
    
    // ТекущийЭлемент указывает на объект справочника в отображаемой строке
    Если ТекущийЭлемент().ЭтоГруппа() = 1 Тогда
        Возврат "";
    КонецЕсли;
    
    // Получаем необходимые данные из текущего элемента
    Результат = "Арт: " + СокрЛП(ТекущийЭлемент().Артикул);
    
    Возврат Результат;
КонецФункции

Проблема производительности при многократных вызовах

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

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

Оптимизация: предварительное кэширование данных

Если требуется выводить остатки или цены, наилучшим решением без использования внешних компонент является предварительный расчет данных в память при открытии формы с последующим быстрым чтением через объект ТаблицаЗначений.

Разберем этот алгоритм на практике:


// В модуле формы списка справочника
Перем глТаблицаОстатков;

Процедура ПриОткрытии()
    // Создаем структуру для быстрого поиска
    глТаблицаОстатков = СоздатьОбъект("ТаблицаЗначений");
    глТаблицаОстатков.НоваяКолонка("Товар", "Справочник.Номенклатура");
    глТаблицаОстатков.НоваяКолонка("Остаток", "Число", 12, 2);
    
    // Формируем один сводный запрос по регистрам
    // и заполняем подготовленную таблицу остатков
    СформироватьОстатки();
    
    // Индексируем колонку для ускорения НайтиЗначение
    глТаблицаОстатков.ВидимостьКолонки("Товар", 1);
КонецПроцедуры

Функция ПолучитьОстатокТовара()
    Перем ТекТовар, СтрНом, ЗначОстатка;
    
    ТекТовар = ТекущийЭлемент();
    
    Если ТекТовар.ЭтоГруппа() = 1 Тогда
        Возврат "";
    КонецЕсли;
    
    // Используем мгновенный поиск по уже рассчитанной таблице
    Если глТаблицаОстатков.НайтиЗначение(ТекТовар, СтрНом, "Товар") = 1 Тогда
        ЗначОстатка = глТаблицаОстатков.ПолучитьЗначение(СтрНом, "Остаток");
        Возврат Формат(ЗначОстатка, "Ч12.2");
    КонецЕсли;
    
    Возврат "0.00";
КонецФункции

Ограничения механизма и альтернативные решения

Проанализируем ограничения использования расчетных колонок в 1С 7.7, о которых важно помнить разработчику:

  1. Невозможность стандартной сортировки и отбора: по колонкам с формулами нельзя кликнуть для сортировки, по ним не работает встроенный быстрый поиск с клавиатуры и не накладываются стандартные отборы. Платформа 7.7 умеет сортировать только по реквизитам, для которых в метаданных установлен признак сортировки или отбора.
  2. Альтернатива на ТаблицеЗначений: если сортировка и фильтрация по расчетным показателям обязательны, форму списка строят на элементе диалога типа ТаблицаЗначений. Вся информация заполняется запросом, а стандартные функции выбора и открытия карточки реализуются через перехват событий клика.
  3. Использование внешней компоненты 1С++: для высоконагруженных списков стандартом является замена штатного списка на объект ТабличноеПоле из компоненты 1С++ с прямым получением данных из базы через ODBCRecordset. Это снимает любые ограничения на расчетные колонки и сохраняет максимальную скорость скроллинга.
← На главную