При разработке помощников формирования заказов поставщикам, матриц поставщика или отчетов по закупкам в конфигурации «Торговля и Склад 7.7» часто возникает задача — быстро и корректно получить список всей номенклатуры, которая поступала от заданного поставщика за период. Разберем основные подходы к решению этой задачи, проанализируем частые ошибки при составлении запросов и выясним, какой способ лучше выбрать в зависимости от архитектуры базы данных.
Регистр ПартииНаличие аккумулирует информацию о движениях партий товаров. В реквизитах партии хранится ссылка на поставщика, что позволяет получить данные независимо от конкретного типа приходного документа.
Важная особенность встроенного языка запросов 1С 7.7: при обращении к регистрам остатков через объект Запрос платформа требует обязательного наличия хотя бы одной агрегатной функции (например, Приход, Расход или Сумма). Если в тексте запроса указать только переменные и группировки без функций, запрос выполнится без системных ошибок, но вернет пустую таблицу результатов.
Рассмотрим правильный пример запроса по регистру ПартииНаличие с обязательной функцией и фильтром по кодам операций закупки:
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(ТоварыПоставщика)
|Период с ВыбНачДата по ВыбКонДата;
|Номенклатура = Регистр.ПартииНаличие.Номенклатура;
|Поставщик = Регистр.ПартииНаличие.Партия.Поставщик;
|КодОперации = Регистр.ПартииНаличие.КодОперации;
|Кол = Регистр.ПартииНаличие.Количество;
|Функция ПриходКол = Приход(Кол);
|Группировка Номенклатура без групп;
|Условие ((КодОперации = Перечисление.КодыОпераций.Закупка) или (КодОперации = Перечисление.КодыОпераций.ЗакупкаРозница));
|Условие (Поставщик = ВыбПоставщик);
|"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка(1) = 1 Цикл
Сообщить("Товар: " + Запрос.Номенклатура);
КонецЦикла;
КонецЕсли;
Особенности и ограничения использования регистра:
Регистр.ПартииНаличие.Партия.Поставщик выполняет разыменование через точку, что на больших объемах движений приводит к дополнительным обращениям к таблицам базы данных.Если требуется получить список товаров непосредственно из первичных документов без привязки к расчету себестоимости и партионному учету, оптимально использовать запрос по документам. В типовой конфигурации поставки могут оформляться документами ПоступлениеТМЦ, ПоступлениеТМЦВРозницу или ПоступлениеТМЦИмпорт.
Посмотрим на пример запроса по проведенным документам поступления:
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|Период с ВыбНачДата по ВыбКонДата;
|ОбрабатыватьДокументы Проведенные;
|Поставщик = Документ.ПоступлениеТМЦ.Контрагент;
|Товар = Документ.ПоступлениеТМЦ.Номенклатура;
|Группировка Товар без групп;
|Условие (Поставщик = ВыбПоставщик);
|Без итогов;";
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
ТаблицаТоваров = СоздатьОбъект("ТаблицаЗначений");
Запрос.Выгрузить(ТаблицаТоваров, 0, 0);
// Обработка полученной таблицы
КонецЕсли;
Преимущества и нюансы запроса по документам:
Разберем дополнительные варианты, если штатный объект Запрос работает медленно:
ИспользоватьЖурнал() и установкой отбора по графе «Контрагент» обращается напрямую к индексам журнала 1SJOURN, что в ряде случаев выполняется быстрее тяжелого запроса.Партии подчинен справочнику Номенклатура. Если в базе ведется партионный учет, можно сделать выборку по справочнику партий с фильтром по реквизиту Поставщик, получая номенклатуру через ТекущийЭлемент().Владелец.DH..., DT...) с использованием оператора DISTINCT. Это исключает накладные расходы встроенного интерпретатора 1С 7.7.