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

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

При работе с прямыми запросами к базе данных 1С 7.7 (в частности, при использовании ВК 1SQLite или прямых SQL-запросов к MS SQL Server) разработчики часто сталкиваются с необходимостью получить сумму документа-основания. В отличие от стандартного языка запросов платформы 1С 8.x, архитектура реляционных таблиц 1С 7.7 имеет специфические особенности, которые вызывают затруднения при попытке объединить данные нескольких видов документов.

Рассмотри подробно, как устроено хранение данных в 1С 7.7, почему нельзя обойтись простым соединением журнала с одной таблицей и какие способы оптимизации запросов существуют.

Архитектурные ограничения и устройство таблиц в 1С 7.7

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

  1. Таблица общего журнала (_1SJOURN) содержит только общие системные реквизиты: дату, номер, идентификатор документа IDDOC, код вида документа IDDOCDEF, а также флаги проведения и удаления. Суммы документов в общей таблице журнала не хранятся.
  2. Таблицы шапок документов (DH<ID>) содержат реквизиты шапки конкретного вида документа (включая итоговые суммы). Для каждого вида документа создается отдельная физическая таблица.
  3. Таблицы табличных частей (DT<ID>) хранят строки табличных частей документов каждого вида.
  4. Реквизиты неопределенного типа: если реквизит основания имеет тип «Документ» (без указания конкретного вида), в базе данных 1С 7.7 он сохраняется как составная строка из 23 символов. Чтобы выделить IDDOC документа-основания в SQL, приходится использовать функции работы со строками, такие как SUBSTR.

Таким образом, если документ-основание может относиться к нескольким различным видам (например, ПоступлениеТМЦ, ВозвратОтПокупателя, ПоступлениеПрочее), реквизит суммы каждого из этих документов физически находится в разных SQL-таблицах шапок (DH...).

Решение проблемы: соединение таблиц документов-оснований

Сформулируем классический подход к получению суммы документа-основания через прямой запрос. Для извлечения сумм нам потребуется последовательно соединить основные таблицы шапок предполагаемых видов документов через LEFT JOIN и применить функцию COALESCE для выбора первого непустого значения.

Разберем пример построения такого запроса на языке SQL (1SQLite / T-SQL):


SELECT 
    Жур.IdDoc as [Докум $Документ.СчетФактураПолученный],
    COALESCE(DH_Пост.SP123, DH_Возвр.SP456, DH_Проч.SP789, 0) AS СуммаОснования
FROM 
    [Журнал] AS Жур
INNER JOIN 
    [Документ.СчетФактураПолученный] AS СФ ON СФ.IdDoc = Жур.IdDoc
LEFT JOIN 
    [Документ.ПоступлениеТМЦ] AS DH_Пост ON DH_Пост.IdDoc = SUBSTR(СФ.ДокументОснование, 10, 9)
LEFT JOIN 
    [Документ.ВозвратОтПокупателя] AS DH_Возвр ON DH_Возвр.IdDoc = SUBSTR(СФ.ДокументОснование, 10, 9)
LEFT JOIN 
    [Документ.ПоступлениеПрочее] AS DH_Проч ON DH_Проч.IdDoc = SUBSTR(СФ.ДокументОснование, 10, 9)
WHERE 
    Жур.date BETWEEN :ДатаС AND :ДатаПо
    AND (Жур.Closed & 1 = 1)

В приведенном примере мы задействуем LEFT JOIN для каждого возможного вида документа-основания, после чего с помощью COALESCE получаем правильную сумму. Однако при большом количестве видов документов такое количество соединений может снизить скорость выполнения запроса.

Оптимизация прямых SQL-запросов

Проанализируем практические способы ускорения выборки данных в 1С 7.7 при использовании библиотеки 1SQLite и прямых запросов.

  1. Использование индекса и усечение лишних соединений в основной выборке:

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

    
    SELECT
        Жур.IdDoc as [Докум $Документ.СчетФактураПолученный]
    FROM
        [Журнал] as Жур
    WHERE
        (Жур.IdDocDef = :ВидДокумента.СчетФактураПолученный)
        and (Жур.date between :ДатаС and :ДатаПо)
        and (Жур.Closed & 1 = 1)
    
  2. Динамическое формирование текста запроса:

    В коде 1С с помощью метаданных можно перед выполнением запроса проанализировать, какие именно виды документов могут являться основаниями в заданном периоде. Это позволяет подставлять в LEFT JOIN только 2–3 реально используемые таблицы вместо десятков возможных.

  3. Использование временных таблиц и UNION ALL:

    Вместо множественных LEFT JOIN к каждой таблице шапки можно собрать временную таблицу с суммами всех нужных документов через UNION ALL, а затем выполнить один единый JOIN с получившейся выборкой.

  4. Перенос реквизита в журнал на уровне Конфигуратора:

    Если конфигурация подлежит доработке, реквизит суммы можно сделать Общим реквизитом со свойством «Переносить в журнал». В этом случае платформа создаст соответствующее поле непосредственно в таблице _1SJOURN, что позволит получать сумму любого документа напрямую из журнала без соединения с таблицами DH....

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

← На главную