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

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

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

Разбор ошибки: IDdocDef против ВидДокумента

Часто при переходе от запросов к физическим таблицам (например, RAxxxx) к виртуальным таблицам (например, $РегистрОбороты) возникает ошибка "Недопустимое имя столбца IDdocDef". Разберем причину этой ситуации.

В физических таблицах движений 1С 7.7 действительно существует поле IDDocDef, которое хранит числовой идентификатор вида документа. Однако виртуальные таблицы 1С++ являются абстракцией (подзапросом), которая переопределяет имена полей для удобства разработчика и унификации кода. Внутри виртуальной таблицы $РегистрОбороты поле, отвечающее за вид документа, называется ВидДокумента. Проанализируем пример исправленного кода:


SELECT
    RIGHT(Рег.ПозицияДокумента, 9) [Док $Документ],
    Рег.ВидДокумента AS Док_вид,
    Рег.ОстатокТовараПриход as ОстатокТовара,
    Рег.ПродСтоимостьПриход as ПродСтоимость
FROM
    $РегистрОбороты.ПартииТоваров(:ДатаНач,
                                 :ДатаКон,
                                 Документ,
                                 ,
                                 Контрагент = :ВыбКонтрагент AND Статус = :ВыбСтатус,
                                 ,
                                 (ОстатокТовара, ПродСтоимость)) as Рег

Как мы видим, замена IDdocDef на ВидДокумента полностью решает проблему доступа к идентификатору метаданных документа в контексте виртуальной таблицы.

Структура поля ПозицияДокумента

Для идентификации конкретного экземпляра документа в 1С 7.7 используется понятие позиции документа. В прямых запросах это поле имеет тип char(23) и содержит в себе три важные составляющие, склеенные в одну строку:

  1. Дата документа: первые 8 символов в формате YYYYMMDD.
  2. Время документа: следующие 6 символов в формате HHMMSS.
  3. ID документа: последние 9 символов (уникальный идентификатор IDDoc).

Чтобы получить ссылку на документ, которую 1С++ сможет типизировать (превратить в объект), мы используем конструкцию RIGHT(Рег.ПозицияДокумента, 9) и типизацию через квадратные скобки [Док $Документ]. Если нам нужно получить дату документа прямо из позиции, мы можем применить функцию LEFT(Рег.ПозицияДокумента, 8).

Параметры виртуальной таблицы оборотов

Для эффективной работы крайне важно понимать, как устроена структура параметров макроса $РегистрОбороты. Рассмотрим их по порядку, чтобы выяснить, как управлять детализацией данных:

  1. ДатаНачала и ДатаКонца: Период, за который выбираются данные.
  2. Периодичность: Здесь мы указываем уровень детализации. Если мы хотим получить данные в разрезе документов, указываем ключевое слово Документ. Также возможны варианты: Период, День, Неделя, Месяц и т.д.
  3. Условие (фильтр): SQL-условие для фильтрации записей.
  4. Список измерений: Критически важный параметр для производительности. Если он пуст, расчет идет по всем измерениям. Если указать конкретные измерения (например, Товар, Склад), SQL-сервер сгруппирует данные только по ним, что значительно ускорит выполнение запроса на больших объемах данных.
  5. Список ресурсов: Перечисление ресурсов, которые нам необходимо просуммировать.

Особенности работы с ресурсами: Приход, Расход, Оборот

В зависимости от типа регистра (регистр остатков или регистр оборотов), к именам ресурсов в виртуальной таблице добавляются суффиксы. Рассмотрим, как это работает:

Для регистров остатков (как в примере ПартииТоваров) доступны три варианта:

Для регистров оборотов доступен только один вариант:

Важный нюанс: Если в параметре "Периодичность" указано значение Документ, то виртуальная таблица автоматически включает в результат поля ПозицияДокумента и ВидДокумента. При этом происходит автоматическая группировка данных в пределах одного документа по всем измерениям, входящим в расчет.

Группировка данных и производительность

Выясним причину, по которой иногда требуется дополнительная группировка в самом SQL-запросе. По умолчанию виртуальная таблица "схлопывает" записи. Однако, если вы выбираете дополнительные поля, не входящие в стандартный набор виртуальной таблицы, вам придется использовать стандартную SQL-группировку GROUP BY.

Посмотрим на пример, когда мы хотим получить итоги по документам, но с фильтрацией по измерениям через 5-й параметр:


SELECT
    Рег.ВидДокумента [ВидДок],
    RIGHT(Рег.ПозицияДокумента, 9) [Док $Документ],
    Рег.Товар [Товар $Справочник.Номенклатура],
    SUM(Рег.КоличествоОборот) as Количество
FROM
    $РегистрОбороты.ОстаткиТоваров(:НачДата, :КонДата, Документ, , , (Товар), (Количество)) as Рег
GROUP BY
    Рег.ВидДокумента,
    Рег.ПозицияДокумента,
    Рег.Товар

В данном примере мы явно указываем измерение Товар в 5-м параметре. Это заставляет виртуальную таблицу выполнять расчет только по этому измерению, игнорируя остальные (например, Склад или Проект), что существенно экономит ресурсы сервера.

Подведем итог: использование ВидДокумента вместо IDdocDef, правильное извлечение IDDoc из ПозицияДокумента и грамотное использование списка измерений в параметрах виртуальной таблицы позволяют создавать быстрые и надежные отчеты на платформе 1С 7.7, работающие напрямую с базой данных SQL.

← На главную