Как в общем журнале 1С 7.7 настроить отбор по контрагенту только для определенных видов документов?

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

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

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

Архитектурные особенности журналов и отборов в 1С 7.7

Для понимания логики работы фильтров проанализируем базовые правила платформы 1С 7.7:

  1. Ограничения метода УстановитьОтбор(): Синтаксис метода с двумя параметрами УстановитьОтбор(<ИмяОтбора>, <Значение>) поддерживается только в общих журналах (для которых в метаданных взведен флаг «Все документы»). В обычных и дополнительных журналах вызов метода с двумя параметрами вызывает ошибку «Неверное имя реквизита!». В них платформа позволяет использовать только однопараметрический вызов для отбора по конкретному виду документа: УстановитьОтбор(<ВидДокумента>).
  2. Отсутствие штатных множественных фильтров: В одном журнале невозможно одновременно вызвать отбор и по виду документа, и по значению реквизита. Платформа держит активным только один критерий отбора.
  3. Разница между графой журнала и графой отбора: Колонка журнала (настраиваемая в свойствах самого журнала) отвечает исключительно за визуальное отображение данных в табличной части. Механизм фильтрации базируется на отдельном объекте конфигурации — «Графы отбора» (ветка «Общие» в дереве метаданных). Платформа 7.7 регистрирует ссылки на документы в специальной системной таблице отборов (1SCRDOC / _1SCRDOC) только в том случае, если реквизит документа явно включен в состав соответствующей графы отбора.

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

Решение 1. Создание специализированной графы отбора в метаданных

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

Разберем по шагам процесс настройки конфигурации:

  1. Откроем Конфигуратор и перейдем в дерево метаданных.
  2. Раскроем ветку «Общие», найдем раздел «Графы отбора» и создадим новый объект, например, с идентификатором НужныйКонтрагент.
  3. В окне свойств созданной графы нажмем кнопку выбора состава документов. В появившемся списке отметим реквизит контрагента строго у тех 5 видов документов, которые должны отображаться в журнале. У всех остальных видов документов флажки ставить нельзя.
  4. Сохраним изменения в конфигураторе. При сохранении платформа выполнит реструктуризацию и автоматически заполнит внутренний индекс только для выбранных документов.
  5. Откроем форму общего журнала, который планируется использовать для подбора, и в модуле формы пропишем установку отбора:

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

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

Решение 2. Использование формы подбора на базе Таблицы Значений

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

Рассмотрим реализацию этого алгоритма:

  1. Создаем новую обработку подбора. На форме размещаем элемент диалога типа «ТаблицаЗначений» с идентификатором ТЗДокументов.
  2. В модуле формы настраиваем колонки и осуществляем выборку данных с помощью штатного объекта Запрос или последовательного обхода нужных видов документов:

Процедура ЗаполнитьСписок(ВыбКонтрагент)
    ТЗДокументов.Очистить();
    ТЗДокументов.НоваяКолонка("Документ", "Документ");
    ТЗДокументов.НоваяКолонка("ДатаДок", "Дата", 8);
    ТЗДокументов.НоваяКолонка("НомерДок", "Строка", 20);
    ТЗДокументов.НоваяКолонка("Вид", "Строка", 30);
    
    // Перечисляем только необходимые виды документов
    СписокВидов = СоздатьОбъект("СписокЗначений");
    СписокВидов.ДобавитьЗначение("РасходнаяНакладная");
    СписокВидов.ДобавитьЗначение("Акт");
    СписокВидов.ДобавитьЗначение("Счет");
    СписокВидов.ДобавитьЗначение("ОказаниеУслуг");
    СписокВидов.ДобавитьЗначение("РеализацияПродукции");
    
    Для Ном = 1 По СписокВидов.РазмерСписка() Цикл
        ИмяВида = СписокВидов.ПолучитьЗначение(Ном);
        Док = СоздатьОбъект("Документ." + ИмяВида);
        
        Док.ВыбратьДокументы();
        Пока Док.ПолучитьДокумент() = 1 Цикл
            Если Док.Контрагент = ВыбКонтрагент Тогда
                ТЗДокументов.НоваяСтрока();
                ТЗДокументов.Документ = Док.ТекущийДокумент();
                ТЗДокументов.ДатаДок = Док.ДатаДок;
                ТЗДокументов.НомерДок = Док.НомерДок;
                ТЗДокументов.Вид = Док.Вид();
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    ТЗДокументов.Сортировать("ДатаДок-, НомерДок");
КонецПроцедуры

Процедура ПриОткрытии()
    Если ПустоеЗначение(Форма.Параметр) = 0 Тогда
        ЗаполнитьСписок(Форма.Параметр);
    КонецЕсли;
КонецПроцедуры

Процедура ПриВыбореСтроки()
    Если ТЗДокументов.ТекущаяСтрока() > 0 Тогда
        Форма.Параметр = ТЗДокументов.ПолучитьЗначение(ТЗДокументов.ТекущаяСтрока(), "Документ");
        Форма.Закрыть();
    КонецЕсли;
КонецПроцедуры

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

Решение 3. Альтернативные методы для баз данных на MS SQL Server

Для высоконагруженных баз данных на платформе MS SQL Server разработчики часто прибегают к использованию внешних компонент:

  1. Компонента перехвата запросов (vk_hook1c): Разработка позволяет низкоуровнево перехватывать вызовы SQLPrepare от ядра 1С 7.7 при обращении к системной таблице журнала _1SJOURN. В перехваченный SQL-запрос динамически внедряется дополнительное условие фильтрации WHERE IDDOCDEF IN (...). Это позволяет использовать стандартный интерфейс журнала без создания избыточных объектов метаданных.
  2. Использование внешней компоненты 1С++: Позволяет разместить на форме элемент управления «Табличное поле» и связать его с прямым SQL-запросом. Запрос считывает данные напрямую из таблиц базы данных порциями, обеспечивая мгновенную прокрутку и наложение любых комбинаций отборов по контрагентам и видам документов.

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

← На главную