Как открыть документ по двойному клику на итоговую сумму в отчете?

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

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

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

Способ 1: Получение регистратора в основном запросе (с ограничениями)

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

Суть метода:

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

Проблема этого подхода:

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

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

Способ 2: Динамический запрос при двойном клике (рекомендуемый)

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

Разберем реализацию по шагам.

Шаг 1. Создание обработчика события

Для нашего ТабличногоПоля на форме необходимо создать обработчик события Выбор. Это событие срабатывает, когда пользователь делает двойной щелчок мыши по строке или нажимает Enter.

Шаг 2. Получение данных из текущей строки

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


Процедура ТабличноеПолеВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
    // Запрещаем стандартное поведение, мы сами все обработаем
    СтандартнаяОбработка = Ложь;

    // Получаем данные текущей строки
    ДанныеСтроки = Элемент.ТекущиеДанные;

    Если ДанныеСтроки = Неопределено Тогда
        // На всякий случай, если кликнули не по строке с данными
        Возврат;
    КонецЕсли;
    
    // Далее будем использовать ДанныеСтроки для отборов
КонецПроцедуры

Шаг 3. Формирование и выполнение запроса

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

Посмотрим на пример кода. Предположим, наш отчет строится по регистру Продажи с измерениями Номенклатура и Склад.


Процедура ТабличноеПолеВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ДанныеСтроки = Элемент.ТекущиеДанные;

    Если ДанныеСтроки = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Создаем новый запрос
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ РАЗЛИЧНЫЕ
        |   ПродажиОбороты.Регистратор
        |ИЗ
        |   РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Регистратор, ) КАК ПродажиОбороты
        |ГДЕ
        |   ПродажиОбороты.Номенклатура = &Номенклатура
        |   И ПродажиОбороты.Склад = &Склад";

    // Устанавливаем параметры запроса
    // Предполагается, что НачалоПериода и КонецПериода - реквизиты формы отчета
    Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
    Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
    Запрос.УстановитьПараметр("Номенклатура", ДанныеСтроки.Номенклатура);
    Запрос.УстановитьПараметр("Склад", ДанныеСтроки.Склад);

    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
        Предупреждение("Не удалось найти документы, сформировавшие движение.");
        Возврат;
    КонецЕсли;
    
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    
    // Получаем регистратор из первой строки результата
    НайденныйРегистратор = Выборка.Регистратор;
    
    // Открываем форму документа
    Если ЗначениеЗаполнено(НайденныйРегистратор) Тогда
        ОткрытьФорму(НайденныйРегистратор.ПолучитьФорму());
    КонецЕсли;

КонецПроцедуры

Шаг 4. Обработка результата запроса

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

Использование ключевого слова РАЗЛИЧНЫЕ в запросе поможет избежать дублирования ссылок на один и тот же документ, если он делал несколько движений в рамках одной проводки.

Таким образом, второй способ позволяет сохранить логику основного отчета с агрегированными данными и при этом обеспечить удобную и быструю расшифровку, выполняя "легкий" запрос для получения деталей только по требованию.

← На главную