Как найти минимальную дату максимальной суммы продаж и максимальную дату минимальной суммы по каждому контрагенту?

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

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

Этап 1: Подготовка данных и расчет экстремумов

Первым делом нам необходимо собрать все продажи в разрезе контрагентов по дням. Для этого лучше всего использовать виртуальную таблицу Обороты регистра накопления. Рассмотрим подробнее, как организовать структуру временных таблиц для эффективного решения задачи.

Разберем по шагам алгоритм создания данных:

  1. Формирование временной таблицы ПродажиПоДням: Мы помещаем туда данные о периоде, контрагенте и сумме выручки. Это позволит нам работать с нормализованным набором данных.
  2. Расчет минимумов и максимумов: Создаем вторую временную таблицу МинМаксСуммы, где с помощью группировки по контрагенту вычисляем МИНИМУМ(СуммаПродажи) и МАКСИМУМ(СуммаПродажи).

ВЫБРАТЬ 
    Продажи.Период КАК ДатаПродажи, 
    Продажи.АналитикаУчетаПоПартнерам КАК Контрагент, 
    Продажи.СуммаВыручкиОборот КАК СуммаПродажи 
ПОМЕСТИТЬ ПродажиПоДням 
ИЗ РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(, , День, ) КАК Продажи;

ВЫБРАТЬ 
    ПродажиПоДням.Контрагент КАК Контрагент, 
    МИНИМУМ(ПродажиПоДням.СуммаПродажи) КАК МинСуммаПродажи, 
    МАКСИМУМ(ПродажиПоДням.СуммаПродажи) КАК МаксСуммаПродажи 
ПОМЕСТИТЬ МинМаксСуммы 
ИЗ ПродажиПоДням КАК ПродажиПоДням 
СГРУППИРОВАТЬ ПО ПродажиПоДням.Контрагент;

Этап 2: Соединение с исходными данными

Теперь, когда у нас есть «эталонные» значения минимальных и максимальных сумм для каждого партнера, нам нужно «притянуть» к ним соответствующие даты. Для этого мы выполняем ЛЕВОЕ СОЕДИНЕНИЕ нашей таблицы с МинМаксСуммы обратно к таблице ПродажиПоДням.

Ключевым моментом здесь является условие соединения: мы связываем таблицы не только по Контрагенту, но и по значению СуммыПродажи. Это гарантирует, что мы получим даты именно для тех строк, где сумма совпадает с найденным экстремумом.


ВЫБРАТЬ 
    МинМаксСуммы.Контрагент КАК Контрагент, 
    МинМаксСуммы.МинСуммаПродажи КАК МинСуммаПродажи, 
    МинМаксСуммы.МаксСуммаПродажи КАК МаксСуммаПродажи, 
    МИНИМУМ(ПродажиПоДнямМин.ДатаПродажи) КАК МинДатаПродажи, 
    МАКСИМУМ(ПродажиПоДнямМакс.ДатаПродажи) КАК МаксДатаПродажи 
ИЗ МинМаксСуммы КАК МинМаксСуммы 
ЛЕВОЕ СОЕДИНЕНИЕ ПродажиПоДням КАК ПродажиПоДнямМакс 
    ПО МинМаксСуммы.Контрагент = ПродажиПоДнямМакс.Контрагент 
    И МинМаксСуммы.МинСуммаПродажи = ПродажиПоДнямМакс.СуммаПродажи 
ЛЕВОЕ СОЕДИНЕНИЕ ПродажиПоДням КАК ПродажиПоДнямМин 
    ПО МинМаксСуммы.Контрагент = ПродажиПоДнямМин.Контрагент 
    И МинМаксСуммы.МаксСуммаПродажи = ПродажиПоДнямМин.СуммаПродажи 
СГРУППИРОВАТЬ ПО 
    МинМаксСуммы.Контрагент, 
    МинМаксСуммы.МинСуммаПродажи, 
    МинМаксСуммы.МаксСуммаПродажи;

Рекомендации по оптимизации запроса

При работе с большими объемами данных в реальных системах, таких как 1С:Управление торговлей или 1С:ERP, важно учитывать следующие советы:

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

← На главную