Как изменить сортировку в типовой Оборотно-сальдовой ведомости (ОСВ) в 1С?

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

Часто перед разработчиками встает задача немного модифицировать вывод данных в типовых отчетах 1С, например, в Оборотно-сальдовой ведомости. Рассмотрим конкретную ситуацию: необходимо изменить сортировку по третьему субконто в 1С:Бухгалтерия 3.0 таким образом, чтобы документы КорректировкаДолга всегда выводились в самом низу группировки, после всех остальных документов.

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

Почему не работает стандартная сортировка в запросе?

Первое, что приходит на ум разработчику — добавить служебное поле прямо в текст запроса и использовать конструкцию УПОРЯДОЧИТЬ ПО. Посмотрим на пример кода, который часто пытаются использовать:


ВЫБРАТЬ 
    ХозрасчетныйОстаткиИОбороты.Счет КАК Счет, 
    ХозрасчетныйОстаткиИОбороты.Период КАК Период, 
    ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Субконто1, 
    ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Субконто2, 
    ХозрасчетныйОстаткиИОбороты.Субконто3 КАК Субконто3, 
    ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(ХозрасчетныйОстаткиИОбороты.Субконто3) = ТИП(Документ.КорректировкаДолга) 
        ТОГДА 12 
        ИНАЧЕ 2 
    КОНЕЦ КАК Сорт
ИЗ РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты КАК ХозрасчетныйОстаткиИОбороты
УПОРЯДОЧИТЬ ПО 
    Сорт, 
    Период

Поле Сорт корректно вычисляется (документам корректировки присваивается значение 12, остальным — 2), однако сортировка в итоговом отчете не меняется. Выясним причину.

В типовых бухгалтерских отчетах Система компоновки данных (СКД) автоматически игнорирует конструкцию УПОРЯДОЧИТЬ ПО внутри самого набора данных (запроса). СКД самостоятельно строит итоговый запрос к базе данных на основе выбранных пользователем группировок, и жестко заданная сортировка в исходном запросе просто отбрасывается.

Попытка настройки сортировки на уровне отчета

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

Дело в том, что при формировании отчета запускаются алгоритмы общих серверных модулей, таких как БухгалтерскиеОтчеты и БухгалтерскиеОтчетыВызовСервера. Эти модули программно очищают или жестко переопределяют пользовательские и корневые настройки компоновщика перед самым выводом данных. Они навязывают стандартную сортировку по периоду, регистратору и строковому представлению субконто. В результате любые ваши визуальные настройки в корне отчета затираются типовым кодом 1С.

Разберем правильный подход: программное вмешательство в СКД

Чтобы обойти типовые ограничения, нам необходимо вмешаться в настройки СКД программно, непосредственно в процессе выполнения отчета. Рассмотрим подробнее алгоритм действий.

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

Пример концептуального кода для модификации порядка в нужной группировке:


// В процедуре ПриКомпоновкеРезультата
// Находим нужную группировку в структуре настроек компоновщика
Для Каждого ЭлементСтруктуры Из КомпоновщикНастроек.Настройки.Структура Цикл
    // Проверяем, что это группировка по Субконто3
    // (Условия зависят от конкретной структуры ОСВ)
    Если ТипЗнч(ЭлементСтруктуры) = Тип("ГруппировкаКомпоновкиДанных") Тогда
        
        // Добавляем программно поле сортировки
        НовоеПолеПорядка = ЭлементСтруктуры.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
        НовоеПолеПорядка.Поле = Новый ПолеКомпоновкиДанных("Сорт");
        НовоеПолеПорядка.ТипУпорядочивания = ТипУпорядочиванияКомпоновкиДанных.Возр;
        НовоеПолеПорядка.Использование = Истина;
        
    КонецЕсли;
КонецЦикла;

Использование механизма расширений

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

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

Важный нюанс: ограничения полей в схеме компоновки данных

Рассмотрим еще одну частую ошибку. Вычисляемое поле может игнорироваться Системой компоновки данных даже при программном добавлении. Выясним причину.

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

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

← На главную