При проектировании систем на платформе 1С:Предприятие 8 разработчики часто сталкиваются с архитектурным ограничением стандартного объекта метаданных Журнал документов. На этапе конфигурирования мы можем жестко задать список входящих в него документов, но платформа не позволяет выполнять условную регистрацию «на лету». Иными словами, если документ определенного типа включен в журнал, СУБД запишет туда абсолютно все его экземпляры, независимо от реквизитов (например, от «Вида операции»).
В этой статье мы подробно разберем, как обойти это ограничение, проанализируем различные подходы — от простых интерфейсных решений до серьезной перестройки архитектуры базы данных, используемой в промышленных конфигурациях (ЕРП, КА, УТ).
Стандартный Журнал документов — это физическая таблица в базе данных СУБД. Когда документ записывается или проводится, платформа автоматически делает запись в таблицу журнала. Попытка отфильтровать эти данные на уровне СУБД по конкретному реквизиту (например, ВидОперации) штатными средствами метаданных журнала невозможна. Нам приходится выбирать один из альтернативных вариантов решения этой задачи.
Этот подход упоминается в сообщении (1) форума («перейти на принцип типовых»). В современных конфигурациях фирмы 1С, использующих Библиотеку стандартных подсистем (БСП), для подобных задач применяется именно этот паттерн. Вместо реального журнала документов мы создаем вспомогательный регистр сведений, который и будет выполнять роль нашего «журнала».
Разберем реализацию этого механизма по шагам:
ЖурналОпределенныхДокументов). В качестве измерения укажем Документ (тип — ссылка на наш документ). В ресурсы или реквизиты вынесем поля, которые нужно отображать в списке (Дата, Номер, Контрагент, Сумма и т. д.).ПриЗаписи (или ОбработкаПроведения) для нашего документа.
Процедура ПриЗаписиДокументаРегистрацияВЖурнале(Источник, Отказ) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Проверяем, соответствует ли документ нашему виду операции
Если Источник.ВидОперации = Перечисления.ВидыОпераций.НужныйВид Тогда
// Создаем и заполняем запись в регистре сведений
МенеджерЗаписи = РегистрыСведений.ЖурналОпределенныхДокументов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Документ = Источник.Ссылка;
МенеджерЗаписи.Дата = Источник.Дата;
МенеджерЗаписи.Номер = Источник.Номер;
МенеджерЗаписи.Контрагент = Источник.Контрагент;
МенеджерЗаписи.Сумма = Источник.СуммаДокумента;
МенеджерЗаписи.Записать(Истина);
Иначе
// Если вид операции изменился на другой, удаляем старую запись из регистра
НаборЗаписей = РегистрыСведений.ЖурналОпределенныхДокументов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Документ.Установить(Источник.Ссылка);
НаборЗаписей.Записать(Истина);
КонецЕсли;
КонецПроцедуры
Для вывода информации пользователю мы создаем форму списка (например, в составе обработки или общей формы) и размещаем на ней Динамический список, основной таблицей которого будет являться наш регистр сведений РегистрСведений.ЖурналОпределенныхДокументов. При двойном клике на строку списка будет открываться сам документ из измерения Документ.
Преимущества: Высокая скорость работы. В базе данных хранятся и индексируются только те документы, которые удовлетворяют нашему условию. Мы можем выводить в такой виртуальный журнал любые дополнительные данные, которых изначально нет в шапках документов.
В ходе обсуждения на форуме в сообщении (20) прозвучала важная мысль: часто необходимость «вырезать» часть документов из общего списка говорит о методологической ошибке на этапе проектирования метаданных. Если у вас один документ выполняет слишком разные бизнес-роли (разные проводки, разные печатные формы, разные права доступа), правильнее разделить его на несколько отдельных документов конфигурации.
Чтобы такое разделение прошло безболезненно для разработчика и пользователей, задействуем следующие платформенные механизмы:
Организация, Контрагент, Договор) и включим их для новых документов. Это позволит писать универсальные запросы к разным таблицам и упростит поддержку кода.Нумератор. Платформа сама будет следить за уникальностью номеров в рамках этой группы.После разделения документов мы сможем без проблем включить в стандартный Журнал документов только тот вид документа, который соответствует нужной нам хозяйственной операции.
Если вносить изменения в структуру базы данных (создавать новые регистры или разделять документы) запрещено требованиями проекта, мы можем решить задачу на уровне интерфейса конкретной формы списка существующего журнала документов.
Рассмотрим, как правильно настроить отбор, чтобы форма не зависала на больших объемах данных:
ПроизвольныйЗапрос.ВидОперации (поскольку в самом журнале этого реквизита обычно нет).Критически важный момент оптимизации: Избегайте жесткого прописывания фильтра в секции ГДЕ текста запроса динамического списка (например, ГДЕ Ссылка.ВидОперации = &НужныйВид). При таком подходе СУБД будет вынуждена сканировать таблицы, что приведет к сильным задержкам при росте базы данных. Вместо этого настроим отбор через систему компоновки данных (СКД) динамического списка:
// В модуле формы при создании на сервере
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем элемент отбора динамического списка
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ВидОперации");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Перечисления.ВидыОпераций.НужныйВид;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецПроцедуры
Платформа 1С оптимизирует такие отборы на уровне генерации SQL-запроса, что позволяет использовать индексы таблиц и обеспечивает быстрый отклик интерфейса.
В случае, если выделяемая группа документов определяется не перечислением «Вид операции», а конкретным ссылочным реквизитом (например, документы по конкретному Проекту, Складу или Договору), идеальным решением будет использование стандартного объекта метаданных Критерии отбора.
Этот объект автоматически собирает в единый список документы разных типов, у которых заполнен указанный реквизит связи. Платформа 1С самостоятельно создает индексы под этот механизм, поэтому такой «виртуальный журнал» работает крайне быстро из коробки и не требует написания сложного кода поддержки.
Выберем наиболее подходящий вариант в зависимости от условий вашей задачи: