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