При работе с 1С:ERP Программисты часто сталкиваются с ситуацией, когда стандартные механизмы поиска связанных документов не дают быстрого результата. Типичный пример — поиск документа РасходныйОрдерНаТовары, привязанного к ЗаказКлиента. Сложность заключается в том, что в ERP связь между этими объектами реализована не через привычный реквизит ДокументОснование в шапке, а через механизмы складского учета. В этой статье мы подробно разберем, как эффективно решать эту задачу различными способами: от использования критериев отбора до прямых SQL-запросов.
Для начала проанализируем структуру хранения данных в 1С:ERP. В отличие от более простых конфигураций, здесь реализована концепция разделения финансового и складского учета. Расходный ордер на товары является складским документом, который может создаваться на основании нескольких распоряжений сразу. Именно поэтому в его «шапке» отсутствует единая ссылка на документ-основание. Информация о заказе-распоряжении хранится в табличной части Товары в поле Распоряжение. Это ключевой момент, который мы будем использовать в наших запросах. Для удобного контроля заказов и оформления расходных ордеров в пользовательском режиме подойдёт рабочее место кладовщика для отгрузки ордерного склада.
Самый очевидный путь — использование встроенного в платформу механизма критериев отбора. Этот метод позволяет получить список всех документов, которые так или иначе ссылаются на наш объект. Рассмотрим, как написать такой запрос:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
СвязанныеДокументы.Ссылка КАК Ссылка
ИЗ
КритерийОтбора.СвязанныеДокументы(&ЗначениеКритерияОтбора) КАК СвязанныеДокументы
ГДЕ
СвязанныеДокументы.Ссылка.ПометкаУдаления = ЛОЖЬ
И СвязанныеДокументы.Ссылка.Проведен = ИСТИНА
Однако при использовании этого метода мы столкнемся с важным ограничением платформы: параметр критерия отбора не может быть массивом. Если нам нужно получить данные сразу по списку заказов, этот метод потребует выполнения запроса в цикле, что крайне негативно скажется на производительности системы. Кроме того, на уровне SQL 1С преобразует этот запрос в огромное количество объединений (UNION ALL) по всем таблицам, входящим в состав критерия, что может замедлить работу системы на несколько секунд.
Разберем более производительный и надежный метод. Поскольку мы знаем, что связь хранится в табличной части Товары, мы можем обратиться к ней напрямую. Это позволит нам передавать массив заказов и получать результат одним быстрым запросом.
Рассмотрим пример кода:
ВЫБРАТЬ РАЗЛИЧНЫЕ
ТаблицаТовары.Ссылка КАК Ордер
ИЗ
Документ.РасходныйОрдерНаТовары.Товары КАК ТаблицаТовары
ГДЕ
ТаблицаТовары.Распоряжение В (&МассивЗаказов)
И ТаблицаТовары.Ссылка.Проведен = ИСТИНА
В этом примере мы используем ключевое слово РАЗЛИЧНЫЕ, так как в одном ордере может быть много строк, ссылающихся на один и тот же заказ. Данный подход работает значительно быстрее, чем критерий отбора, так как поиск идет по конкретной индексированной таблице.
Для максимально быстрой работы, особенно в высоконагруженных системах, рекомендуется анализировать движения по регистрам. В ERP за отгрузку отвечает регистр накопления ТоварыКОтгрузке. Проанализируем ситуацию: когда ордер создается, он делает движения по этому регистру, указывая в качестве измерения ДокументОтгрузки (наш Заказ).
Пример запроса к регистру:
ВЫБРАТЬ РАЗЛИЧНЫЕ
Регистр.Регистратор КАК Ордер
ИЗ
РегистрНакопления.ТоварыКОтгрузке КАК Регистр
ГДЕ
Регистр.ДокументОтгрузки В (&МассивЗаказов)
И Регистр.Регистратор ССЫЛКА Документ.РасходныйОрдерНаТовары
Этот способ позволяет избежать сканирования табличных частей документов и является наиболее «архитектурно верным» для 1С:ERP.
Рассмотрим ситуацию, когда у нас нет доступа к конфигуратору и мы работаем с базой данных напрямую через SQL. Выясним причину, почему поиск «Заказов без поступлений» или «Заказов без ордеров» вызывает сложности. В SQL нет виртуальной таблицы СвязанныеДокументы.
Чтобы найти нужные данные, выполним следующие шаги:
ВЫБРАТЬ Ссылка ИЗ Документ.РасходныйОрдерНаТовары, чтобы узнать имя таблицы в SQL (например, _Document250).ЗаказыПоставщикам._Totals или расчет итогов по основной таблице _AccumReg...) сумма прихода меньше суммы заказа, значит документ не выполнен полностью.Пример логики SQL-запроса для поиска невыполненных заказов:
SELECT
OrderTable._Number as НомерЗаказа,
OrderTable._Date_Time as Дата
FROM
_Document240 OrderTable -- Таблица Заказов
WHERE
OrderTable._IDRRef NOT IN (
SELECT DISTINCT
MovementTable._Fld567RRef -- Поле Распоряжение в движениях поступлений
FROM
_AccumReg890 MovementTable -- Регистр Заказов
)
Мы проанализировали три основных способа получения связанных документов в 1С:ERP. Выбор конкретного метода зависит от ваших задач:
КритерийОтбора.СвязанныеДокументы.Документ.РасходныйОрдерНаТовары.Товары.ТоварыКОтгрузке.Используя эти подходы, вы сможете эффективно работать со сложными связями в ERP, экономя время на разработку и ресурсы сервера.