При работе с высоконагруженными базами данных на платформе 1С 7.7 стандартные средства получения подчиненных документов, такие как объект ВыбратьПодчиненныеДокументы, могут работать медленно, особенно если дерево связей очень разветвленное. В таких случаях программисты прибегают к использованию прямых SQL-запросов (обычно через библиотеку 1CPP). Однако новички часто совершают ошибку, пытаясь найти связи в таблице журнала документов или через конкретные реквизиты шапки. Разберем, как это сделать правильно и эффективно.
Проанализируем типичную ошибку: попытку связать документы через реквизиты, хранящиеся в таблице журнала _1SJOURN или физических таблицах документов (например, $Документ.Договор). В 1С 7.7 связь "Основание — Подчиненный" не всегда хранится в явном виде в колонках таблиц документов. Даже если вы создали реквизит "ДокументОснование", стандартное системное дерево подчиненности строится по иному принципу.
Для корректного решения задачи нам необходимо обратиться к системной таблице _1SCRDOC. Именно в ней платформа регистрирует абсолютно все связи между объектами, которые отображаются в интерфейсе при нажатии кнопки "Дерево подчиненных документов".
Прежде чем писать запрос, рассмотрим структуру этой таблицы, так как она является ключом к решению:
Выясним причину, по которой простые сравнения часто не срабатывают. Поле ParentVal в SQL-базе имеет длину 23 символа. Чтобы не формировать эту строку вручную (что чревато ошибками с типами данных), в библиотеке 1CPP предусмотрен специальный типизатор. Рассмотрим пример передачи параметра:
ODBCRecordSet.УстановитьТекстовыйПараметр("Родитель", ДокументСсылка);
В самом SQL-тексте мы будем использовать конструкцию :Родитель* (со звездочкой), что заставит компоненту развернуть ссылку в полный формат, понятный таблице _1SCRDOC.
Рассмотрим правильный пример запроса, который выберет все помеченные и не помеченные на удаление подчиненные документы для конкретного родителя. Мы объединим таблицу связей с журналом документов, чтобы получить вид документа и его номер.
SELECT
Журнал.IDDOC [Документ $Документ],
Журнал.IDDOCDEF Документ_вид,
Журнал.DOCNO as НомерДокумента,
CAST(LEFT(Журнал.DATE_TIME_IDDOC, 8) as DateTime) as ДатаДокумента
FROM
_1SCRDOC as Ссылки WITH (NOLOCK)
INNER JOIN
_1SJOURN as Журнал WITH (NOLOCK) ON Ссылки.CHILDID = Журнал.IDDOC
WHERE
Ссылки.PARENTVAL = :Родитель*
AND Ссылки.MDID = 0
AND Журнал.ISMARK = 0
ORDER BY
Журнал.DATE_TIME_IDDOC
Важные моменты в этом коде:
INNER JOIN с таблицей _1SJOURN. Это гарантирует, что мы не получим "битые" ссылки (записи в _1SCRDOC, для которых сам документ был удален физически).MDID = 0 позволяет нам видеть именно те документы, которые входят в стандартное дерево подчиненности 1С.WITH (NOLOCK) — хорошая практика для 1С 7.7, позволяющая избежать блокировок таблиц при чтении данных.Проанализируем ситуацию, когда нам нужно проверить документ на пустое значение. В 1С 7.7 ссылки в SQL хранятся как строки. Сравнение с пустой строкой '' — это ошибка, так как идентификатор документа в SQL всегда имеет фиксированную длину (9 символов). Профессиональнее использовать макрос $ПустойИД.
Рассмотрим, как изменить условие в основном запросе автора, чтобы корректно проверять заполненность реквизитов:
| WHERE $ДокументДоговор.Контрагент <> $ПустойИД
Если ваш сложный запрос (как в примере из Сообщения 0) по-прежнему не возвращает данные, разберем методику пошаговой проверки:
_1SCRDOC для одного конкретного IDDOC, в подчиненности которого вы уверены.:Родитель* передается корректно. Посмотрите в профайлере SQL (SQL Profiler), во что превращается этот параметр. Он должен выглядеть как строка вида 'O1' + IDDOCDEF_BASE36 + IDDOC.ДатаНачала <= :ДатаДокум), убедитесь, что подчиненные документы попадают в этот интервал.Использование прямой таблицы связей _1SCRDOC — это единственный надежный и быстрый способ получения дерева подчиненности в 1С 7.7 через SQL. Попытки связать таблицы через sp... поля (как делал автор темы в sp1351) могут работать только для частных случаев, когда в конфигураторе явно указан тип реквизита "Документ.НужныйВид", но они бесполезны для общих связей. Используйте предложенный шаблон с INNER JOIN к журналу, и ваши отчеты будут работать мгновенно.