При разработке отчетов или доработке механизмов в конфигурациях «1С:Управление торговлей 11», «1С:ERP» или «1С:Комплексная автоматизация 2» часто возникает задача разделить товары на складе по их принадлежности. Стандартный подход с использованием регистра накопления ТоварыНаСкладах в данном случае не сработает, так как этот регистр отвечает только за физическое наличие товара на складе, не учитывая, чей это товар — наш собственный или принятый на комиссию.
В этой статье мы подробно разберем, как правильно построить запрос, чтобы выделить комиссионные товары, какие регистры использовать и на какие особенности архитектуры 1С стоит обратить внимание.
Для начала проанализируем ситуацию. В современных конфигурациях 1С разделены понятия «складской учет» и «финансовый учет». Складской учет (регистр ТоварыНаСкладах) фиксирует количество в разрезе номенклатуры, характеристик и складов. Финансовый учет (регистр ТоварыОрганизаций) фиксирует принадлежность этого количества конкретной организации и вид запасов.
Именно поле ВидЗапасов является ключом к решению нашей задачи. В нем хранится информация о том, является ли товар собственным, комиссионным или, например, принятым на ответственное хранение. Поэтому для получения остатков в разрезе прав собственности мы будем использовать виртуальную таблицу ТоварыОрганизаций.Остатки.
Рассмотрим простейший пример запроса. Чтобы отфильтровать только комиссионные товары, нам необходимо соединить таблицу остатков регистра ТоварыОрганизаций со справочником ВидыЗапасов и проверить значение перечисления ТипыЗапасов.
ВЫБРАТЬ
ТоварыОрганизацийОстатки.АналитикаУчетаНоменклатуры КАК Аналитика,
ТоварыОрганизацийОстатки.Организация КАК Организация,
ТоварыОрганизацийОстатки.КоличествоОстаток КАК Количество
ИЗ
РегистрНакопления.ТоварыОрганизаций.Остатки(&Период, ) КАК ТоварыОрганизацийОстатки
ГДЕ
ТоварыОрганизацийОстатки.ВидЗапасов.ТипЗапасов = ЗНАЧЕНИЕ(Перечисление.ТипыЗапасов.КомиссионныйТовар)
В данном запросе мы обращаемся к реквизиту через точку. Однако, для повышения производительности на больших базах, рекомендуется сначала отобрать нужные виды запасов или использовать параметры виртуальной таблицы.
Заметим, что в регистре ТоварыОрганизаций нет прямых измерений Номенклатура или Склад. Вместо них используется измерение АналитикаУчетаНоменклатуры. Это ссылка на системный справочник КлючиАналитикиУчетаНоменклатуры. Чтобы «вытащить» привычные нам данные, нужно выполнить соединение с этим справочником или обратиться к его реквизитам.
Разберем по шагам более полный вариант запроса:
ВЫБРАТЬ
КлючиАналитики.Номенклатура КАК Товар,
КлючиАналитики.Характеристика КАК Характеристика,
КлючиАналитики.Склад КАК Склад,
ВидыЗапасов.ТипЗапасов КАК ТипЗапасов,
ТоварыОрганизацийОстатки.КоличествоОстаток КАК Остаток
ИЗ
РегистрНакопления.ТоварыОрганизаций.Остатки(&КонецПериода, ) КАК ТоварыОрганизацийОстатки
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыЗапасов КАК ВидыЗапасов
ПО ТоварыОрганизацийОстатки.ВидЗапасов = ВидыЗапасов.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КлючиАналитикиУчетаНоменклатуры КАК КлючиАналитики
ПО ТоварыОрганизацийОстатки.АналитикаУчетаНоменклатуры = КлючиАналитики.Ссылка
ГДЕ
ВидыЗапасов.ТипЗапасов = ЗНАЧЕНИЕ(Перечисление.ТипыЗапасов.КомиссионныйТовар)
И КлючиАналитики.Склад = &НужныйСклад
Если вы работаете в версии 11.5 и выше, важно учитывать, что механизмы комиссии были значительно переработаны. Теперь в системе существует два варианта учета: старый (1.0) и новый (2.0). Рассмотрим нюансы, которые могут повлиять на ваш запрос:
ТоварыОрганизаций по-прежнему остается универсальной точкой входа для определения принадлежности запасов.ВидЗапасов может указывать на владельца-организацию внутри вашей же базы. Для выделения товаров от внешних комитентов проанализируйте реквизит ВладелецТовара в справочнике ВидыЗапасов.ТипЗапасов все равно будет содержать значение КомиссионныйТовар, но количество будет числиться не на конкретном складе, а на виртуальном.Часто программистам требуется проверить тип запасов непосредственно в табличной части документов, например, в ПересчетТоваров. Поскольку в самом документе может не быть поля «Тип запасов», его приходится получать динамически. Посмотрим на пример запроса, который сопоставляет строки документа с реальными типами запасов на складе:
ВЫБРАТЬ
ДокТовары.Номенклатура,
ВидыЗапасов.ТипЗапасов КАК ТипЗапасовФакт,
ДокТовары.Количество КАК КоличествоВДокументе
ИЗ
Документ.ПересчетТоваров.Товары КАК ДокТовары
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыОрганизаций.Остатки(&ДатаДокумента, ) КАК Остатки
ПО ДокТовары.Номенклатура = Остатки.АналитикаУчетаНоменклатуры.Номенклатура
И ДокТовары.Характеристика = Остатки.АналитикаУчетаНоменклатуры.Характеристика
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыЗапасов КАК ВидыЗапасов
ПО Остатки.ВидЗапасов = ВидыЗапасов.Ссылка
ГДЕ
ДокТовары.Ссылка = &СсылкаНаДокумент
Важный момент: если по одной и той же номенклатуре на складе лежат и собственные, и комиссионные товары, запрос выше может «раздвоить» строки или потребовать дополнительной логики распределения (LIFO/FIFO), которую система 1С обычно выполняет автоматически при проведении документов через механизмы распределения запасов.
Для того чтобы ваш код работал быстро даже при миллионах записей в регистрах, следуйте этим правилам:
Организации или ВидуЗапасов (если он известен) прямо в параметры Остатки(..., Фильтр). Это сократит объем данных, обрабатываемых СУБД.АналитикаУчетаНоменклатуры в 1С всегда индексирован, что делает соединения с ключами аналитики очень быстрыми.ГДЕ Регистр.ВидЗапасов.ТипЗапасов = ... лучше использовать соединение со справочником. Это позволяет оптимизатору SQL построить более эффективный план запроса.Подведем итог: для работы с комиссионными товарами в 1С 8.3 (УТ/ERP) забудьте про складской регистр ТоварыНаСкладах. Всегда используйте ТоварыОрганизаций в связке с ВидамиЗапасов. Проверка условия ТипЗапасов = КомиссионныйТовар гарантированно вернет вам список позиций, которые не являются собственностью организации.