Как в 1С:Торговля и Склад 7.7 получить список всех товаров от определенного контрагента?

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

При разработке помощников формирования заказов поставщикам, матриц поставщика или отчетов по закупкам в конфигурации «Торговля и Склад 7.7» часто возникает задача — быстро и корректно получить список всей номенклатуры, которая поступала от заданного поставщика за период. Разберем основные подходы к решению этой задачи, проанализируем частые ошибки при составлении запросов и выясним, какой способ лучше выбрать в зависимости от архитектуры базы данных.

Вариант 1. Запрос по регистру остатков «ПартииНаличие»

Регистр ПартииНаличие аккумулирует информацию о движениях партий товаров. В реквизитах партии хранится ссылка на поставщика, что позволяет получить данные независимо от конкретного типа приходного документа.

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

Рассмотрим правильный пример запроса по регистру ПартииНаличие с обязательной функцией и фильтром по кодам операций закупки:


Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = 
"//{{ЗАПРОС(ТоварыПоставщика)
|Период с ВыбНачДата по ВыбКонДата;
|Номенклатура = Регистр.ПартииНаличие.Номенклатура;
|Поставщик    = Регистр.ПартииНаличие.Партия.Поставщик;
|КодОперации  = Регистр.ПартииНаличие.КодОперации;
|Кол          = Регистр.ПартииНаличие.Количество;
|Функция ПриходКол = Приход(Кол);
|Группировка Номенклатура без групп;
|Условие ((КодОперации = Перечисление.КодыОпераций.Закупка) или (КодОперации = Перечисление.КодыОпераций.ЗакупкаРозница));
|Условие (Поставщик = ВыбПоставщик);
|"//}}ЗАПРОС
;

Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
    Пока Запрос.Группировка(1) = 1 Цикл
        Сообщить("Товар: " + Запрос.Номенклатура);
    КонецЦикла;
КонецЕсли;

Особенности и ограничения использования регистра:

  1. Зависимость от метода списания: если в информационной базе учет ведется «По средней», механизм партионного учета может быть отключен либо реквизит «Партия» не заполняется в движениях регистра. В таком случае отбор по поставщику через регистр работать не будет.
  2. Производительность: конструкция Регистр.ПартииНаличие.Партия.Поставщик выполняет разыменование через точку, что на больших объемах движений приводит к дополнительным обращениям к таблицам базы данных.

Вариант 2. Запрос напрямую по документам поступления

Если требуется получить список товаров непосредственно из первичных документов без привязки к расчету себестоимости и партионному учету, оптимально использовать запрос по документам. В типовой конфигурации поставки могут оформляться документами ПоступлениеТМЦ, ПоступлениеТМЦВРозницу или ПоступлениеТМЦИмпорт.

Посмотрим на пример запроса по проведенным документам поступления:


Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|Период с ВыбНачДата по ВыбКонДата;
|ОбрабатыватьДокументы Проведенные;
|Поставщик  = Документ.ПоступлениеТМЦ.Контрагент;
|Товар      = Документ.ПоступлениеТМЦ.Номенклатура;
|Группировка Товар без групп;
|Условие (Поставщик = ВыбПоставщик);
|Без итогов;";

Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
    ТаблицаТоваров = СоздатьОбъект("ТаблицаЗначений");
    Запрос.Выгрузить(ТаблицаТоваров, 0, 0);
    // Обработка полученной таблицы
КонецЕсли;

Преимущества и нюансы запроса по документам:

  1. Независимость от партий: запрос работает всегда, даже если в базе отключен партионный учет или регистры партий очищены.
  2. Полнота охвата: при необходимости учитывать все виды приходов (включая розницу, импорт или закупки через подотчетных лиц) их необходимо явно перечислить в секциях запроса либо добавить соответствующие условия.

Альтернативные способы оптимизации выборки

Разберем дополнительные варианты, если штатный объект Запрос работает медленно:

  1. Выборка по журналу документов с отбором: в файловом режиме (DBF) последовательный перебор документов с использованием метода ИспользоватьЖурнал() и установкой отбора по графе «Контрагент» обращается напрямую к индексам журнала 1SJOURN, что в ряде случаев выполняется быстрее тяжелого запроса.
  2. Перебор подчиненного справочника «Партии»: справочник Партии подчинен справочнику Номенклатура. Если в базе ведется партионный учет, можно сделать выборку по справочнику партий с фильтром по реквизиту Поставщик, получая номенклатуру через ТекущийЭлемент().Владелец.
  3. Прямые SQL-запросы (1С++ / ODBCRecordset): для баз на платформе MS SQL Server самым быстрым решением является выполнение прямого SQL-запроса к таблицам шапки и табличной части документов (DH..., DT...) с использованием оператора DISTINCT. Это исключает накладные расходы встроенного интерпретатора 1С 7.7.
← На главную