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

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

При работе с прямыми запросами в 1С:Предприятие 7.7 (с использованием библиотеки 1С++ или класса Класс.ПрямойЗапрос) периодически возникает необходимость извлечь реквизиты подчиненного или связанного документа. В идеальной структуре метаданных реквизит основания является ссылкой на документ и хранит уникальный девятисимвольный идентификатор IDDOC. Однако на практике встречаются конфигурации, где реквизит «Основание» задан строковым типом и хранит лишь текстовый номер документа.

Рассмотрим, как правильно составить прямой SQL-запрос, чтобы связать таблицу документа с системным журналом и получить дату документа-основания по его номеру.

Структурные особенности системного журнала документов

В физической структуре базы данных 1С 7.7 сведения о датах, номерах и статусах всех документов содержатся в единой системной таблице журнала (в запросах 1С++ к ней обращаются по псевдониму Журнал). Таблица содержит следующие ключевые поля:

  1. IDDOC — уникальный идентификатор документа (9 символов).
  2. DOCNO — номер документа в текстовом формате.
  3. DATE — дата документа.
  4. IDDOCDEF — идентификатор вида документа.
  5. ISMARK — пометка на удаление (1 — помечен, 0 — не помечен).

Если в таблице документа строковое поле з.Основание содержит номер документа-основания, то связь необходимо строить с системной таблицей Журнал по полю DOCNO.

Решение 1. Связывание таблиц через LEFT JOIN по номеру документа

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

Проанализируем базовый пример запроса:


ТекстЗапроса = "
|select 
|    з.iddoc      as [Номер :Документ.Заявка], 
|    ж.DATE       as [Дата :Дата],
|    з.Клиент     as [Клиент :Справочник.Клиенты], 
|    з.Машина     as [Машина :Справочник.Машины], 
|    з.Прицеп     as [Прицеп :Справочник.Прицепы],
|    з.Фирма2     as [Фирма :Справочник.Фирма],
|    з.Основание,
|    з.Автор      as [Автор :Справочник.Сотрудники],
|    ж1.DATE      as [ДатаОснования :Дата]
|from Документ_Заявка as з 
|INNER JOIN Журнал as ж ON з.iddoc = ж.iddoc
|LEFT JOIN Журнал as ж1 ON з.Основание = ж1.DOCNO
|where ж.DATE BETWEEN :ДатаНач AND :ДатаКон
";

Обратим внимание на выбор типа соединения: рекомендуем использовать LEFT JOIN вместо INNER JOIN. Если для какого-то документа поле з.Основание окажется пустым или номер не будет найден в журнале, при использовании INNER JOIN вся строка полностью выпадет из итоговой выборки. Использование LEFT JOIN сохраняет исходные документы в результате, а для ненайденных оснований вернет значение NULL.

Решение 2. Уточнение вида документа в условии соединения

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

Разберем пример с указанием конкретного вида документа-основания:


ТекстЗапроса = "
|select 
|    з.iddoc      as [Документ :Документ.Заявка], 
|    ж.DATE       as [Дата :Дата],
|    з.Основание,
|    ж1.DATE      as [ДатаОснования :Дата]
|from Документ_Заявка as з 
|INNER JOIN Журнал as ж ON з.iddoc = ж.iddoc
|LEFT JOIN Журнал as ж1 ON з.Основание = ж1.DOCNO 
|                       AND ж1.IDDOCDEF = $ВидДокумента.Реализация
|where ж.DATE BETWEEN :ДатаНач AND :ДатаКон
";

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

Важные технические нюансы и оптимизация

При использовании текстового поиска по номерам документов важно учитывать следующие факторы:

  1. Форматирование номеров: В базе данных 1С 7.7 номера документов в поле DOCNO имеют фиксированную длину и дополняются ведущими нулями или пробелами (например, "0000000123"). Если строка в реквизите з.Основание записана без выравнивания по длине номера, прямое равенство в SQL-запросе не сработает. В таком случае номер перед передачей в запрос необходимо отформатировать средствами встроенного языка 1С.
  2. Производительность: Применение строковых функций T-SQL (таких как RTRIM, LTRIM, RIGHT) непосредственно в условии соединения ON отключает использование индексов по полю DOCNO, что приводит к сканированию всей таблицы журнала (Table Scan) и существенному замедлению работы.
  3. Изменение метаданных как лучшая практика: Если есть возможность доработки конфигурации, наиболее правильным решением является изменение типа реквизита «Основание» с текстовой строки на ссылку (тип «Документ»). В таком случае связь в прямом запросе будет выстраиваться по уникальному индексированному полю IDDOC, что обеспечит максимальную скорость выполнения.
← На главную