Как получить сумму по контрагенту за день по заказам покупателей и реализациям в 1С

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

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

Выбор регистра для получения данных

В типовых конфигурациях на базе обычных форм (УПП 1.3, КА 1.1, УТ 10.3) взаиморасчеты и заказы фиксируются в нескольких регистрах. Проанализируем основные из них:

  1. РасчетыСКонтрагентами — обычно используется для управленческого учета. В нем отражаются движения по заказам и счетам.
  2. ВзаиморасчетыСКонтрагентами — чаще отвечает за регламентированный учет и фактическую задолженность.
  3. ЗаказыПокупателей — специализированный регистр для контроля выполнения заказов (в количественном и суммовом выражении).

Если нам необходимо получить сумму "в работе" по конкретным документам Заказ покупателя, правильнее всего обращаться к виртуальным таблицам оборотов регистров взаиморасчетов, фильтруя данные по типу регистратора.

Базовый запрос по регистратору

Рассмотрим ситуацию, когда нам нужно получить сумму всех оборотов, инициатором которых выступил документ Заказ покупателя. Для этого мы будем использовать виртуальную таблицу Обороты и конструкцию ССЫЛКА для фильтрации типов документов. Разберем пример кода:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	РасчетыОбороты.СуммаВзаиморасчетовОборот КАК Сумма
    |ИЗ
    |	РегистрНакопления.РасчетыСКонтрагентами.Обороты(&ДатаНач, &ДатаКон, Регистратор, Контрагент = &Контрагент) КАК РасчетыОбороты
    |ГДЕ
    |	РасчетыОбороты.Регистратор ССЫЛКА Документ.ЗаказПокупателя";

Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("Контрагент", ВыбранныйКонтрагент);

Результат = Запрос.Выполнить();

Важно помнить: использование периодичности Регистратор в виртуальной таблице позволяет нам получить доступ к полю Регистратор в секции ГДЕ. Без указания этой периодичности система сгруппирует данные за весь период, и мы не сможем определить, какой именно документ сделал движение.

Объединение данных из разных регистров

Часто бывает так, что заказы делают движения в одном регистре, а реализации (РТУ) — в другом. Или нам нужно собрать общую сумму по обоим видам документов. В этом случае эффективно использовать конструкцию ОБЪЕДИНИТЬ ВСЕ. Проанализируем следующий подход:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СУММА(ВложенныйЗапрос.Сумма) КАК ОбщаяСумма
    |ИЗ
    |	(ВЫБРАТЬ
    |		ОборотыРасчеты.СуммаВзаиморасчетовОборот КАК Сумма
    |	ИЗ
    |		РегистрНакопления.РасчетыСКонтрагентами.Обороты(&ДатаНач, &ДатаКон, Регистратор, Контрагент = &Контрагент) КАК ОборотыРасчеты
    |	ГДЕ
    |		ОборотыРасчеты.Регистратор ССЫЛКА Документ.ЗаказПокупателя
    |	
    |	ОБЪЕДИНИТЬ ВСЕ
    |	
    |	ВЫБРАТЬ
    |		ОборотыВзаиморасчеты.СуммаВзаиморасчетовОборот
    |	ИЗ
    |		РегистрНакопления.ВзаиморасчетыСКонтрагентами.Обороты(&ДатаНач, &ДатаКон, Регистратор, Контрагент = &Контрагент) КАК ОборотыВзаиморасчеты
    |	ГДЕ
    |		ОборотыВзаиморасчеты.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг) КАК ВложенныйЗапрос";

Такой запрос вернет нам единую сумму по двум разным типам документов из разных регистров. Это полезно, если в вашей базе Реализация товаров и услуг не делает движений по регистру Расчеты с контрагентами, а пишет только во Взаиморасчеты.

Учет связи Реализации с Заказом-основанием

Одной из самых сложных задач является получение сумм только тех реализаций, которые были созданы на основании заказов за определенный период. Если просто суммировать все реализации, мы можем получить "двойную" сумму или захватить отгрузки по старым заказам. Чтобы связать документы, необходимо обратиться к полю Сделка (если ведется учет по заказам) или к реквизиту ДокументОснование физической таблицы реализации.

Выясним, как это сделать через временные таблицы для оптимизации производительности:

  1. Сначала выберем все заказы контрагента за день во временную таблицу.
  2. Затем выберем обороты по регистрам, где регистратором является сам заказ ИЛИ реализация, у которой основание входит в список наших заказов.

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЗаказПокупателя.Ссылка КАК Ссылка
    |ПОМЕСТИТЬ ВТ_Заказы
    |ИЗ
    |	Документ.ЗаказПокупателя КАК ЗаказПокупателя
    |ГДЕ
    |	ЗаказПокупателя.Дата МЕЖДУ &ДатаНач И &ДатаКон
    |	И ЗаказПокупателя.Контрагент = &Контрагент
    |;
    |
    |ВЫБРАТЬ
    |	СУММА(Обороты.СуммаВзаиморасчетовОборот) КАК ИтоговаяСумма
    |ИЗ
    |	РегистрНакопления.РасчетыСКонтрагентами.Обороты(&ДатаНач, &ДатаКон, Регистратор, Контрагент = &Контрагент) КАК Обороты
    |ГДЕ
    |	(Обороты.Регистратор ССЫЛКА Документ.ЗаказПокупателя И Обороты.Регистратор В (ВЫБРАТЬ Ссылка ИЗ ВТ_Заказы))
    |	ИЛИ (Обороты.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг 
    |        И ВЫРАЗИТЬ(Обороты.Регистратор КАК Документ.РеализацияТоваровУслуг).Сделка В (ВЫБРАТЬ Ссылка ИЗ ВТ_Заказы))";

Важный момент: использование функции ВЫРАЗИТЬ при обращении к реквизитам Регистратора крайне необходимо. Это предотвращает избыточные соединения со всеми таблицами документов, входящих в тип Регистратор, и значительно ускоряет работу запроса на больших базах.

На что стоит обратить внимание (Нюансы)

Проанализируем типичные ошибки и важные методологические аспекты, которые могут повлиять на результат:

Таким образом, мы разобрали несколько способов получения суммы по контрагенту. Выбор конкретного метода зависит от архитектуры вашей конфигурации и того, насколько жестко связаны документы заказов и реализаций в вашем бизнес-процессе.

← На главную