Разработка отчетов по продажам — одна из самых частых задач, с которыми сталкивается программист 1С. На первый взгляд она кажется простой: нужно всего лишь сложить проданное количество. Однако при реализации в коде возникает множество нюансов: от выбора правильного регистра до корректной обработки дат и единиц измерения. В этой статье мы подробно разберем, как построить надежный и быстрый запрос для получения данных о продажах.
Прежде чем приступать к написанию кода, выясним, где система хранит информацию о совершенных сделках. В 1С данные о хозяйственных операциях не извлекаются напрямую из документов (это было бы крайне медленно), а берутся из регистров накопления. Проанализируем, какие регистры нам подойдут в зависимости от используемой конфигурации:
ВыручкаИСебестоимостьПродаж. Он содержит максимально полную информацию, включая количество, сумму выручки и себестоимость.Продажи.Хозрасчетный (регистр бухгалтерии) по оборотам счетов 90.01 и 90.02.Рассмотрим ситуацию на примере регистра Продажи. Для получения итогов за период нам категорически не рекомендуется использовать основную таблицу регистра. Вместо этого мы воспользуемся механизмом виртуальных таблиц.
Виртуальная таблица Обороты — это мощный инструмент платформы 1С. Она обращается к заранее рассчитанным итогам, что значительно ускоряет выполнение запроса. Проанализируем преимущества этого подхода: система автоматически суммирует приходы и расходы, учитывая возвраты (которые обычно записываются как отрицательный расход или сторно-запись).
Пример базовой структуры запроса к виртуальной таблице будет выглядеть следующим образом:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты
Разберем типичную ошибку начинающих разработчиков, связанную с параметром &КонецПериода. В 1С дата включает в себя время. Если пользователь выберет дату окончания «31.12.2023», то по умолчанию время установится в значение 00:00:00. Это означает, что все продажи, совершенные в течение последнего дня года, не попадут в отчет.
Чтобы избежать этой проблемы, выясним, как правильно передавать границы периода. Мы должны всегда использовать функцию окончания дня. В коде это реализуется так:
КонецПериодаДляЗапроса = КонецДня(Объект.ДатаОкончания);
Запрос.УстановитьПараметр("КонецПериода", КонецПериодаДляЗапроса);
Если же вы строите отчет на базе Системы компоновки данных (СКД), рекомендуется использовать стандартные периоды или выражение КОНЕЦПЕРИОДА(&ДатаКонца, "ДЕНЬ") в настройках параметров.
Проанализируем ситуацию, упомянутую опытными разработчиками: нельзя просто складывать поле Количество, если товары могут продаваться в разных единицах (например, в штуках и упаковках). Если мы продали 1 упаковку (в которой 10 штук) и 1 штуку, простой запрос покажет общее количество «2», что будет ошибкой.
Рассмотрим, как правильно решить эту задачу:
ЕдиницаИзмерения в запрос и включим его в группировку. Тогда в отчете мы увидим две строки: «Товар — 1 упак» и «Товар — 1 шт».Коэффициент, хранящийся в справочнике упаковок или единиц измерения.Также не забудем про Характеристики. Если один и тот же товар имеет разные цвета или размеры, их необходимо обязательно выводить в отчете, иначе данные по всем вариациям «схлопнутся» в одну строку.
Теперь соберем все наши знания в единый эффективный запрос. Мы добавим группировку по номенклатуре и характеристике, а также выделим количество оборота.
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.Характеристика КАК Характеристика,
ПродажиОбороты.КоличествоОборот КАК КоличествоПродано,
ПродажиОбороты.Номенклатура.ЕдиницаХраненияОстатков КАК ЕдиницаИзмерения
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты
СГРУППИРОВАТЬ ПО
ПродажиОбороты.Номенклатура,
ПродажиОбороты.Характеристика,
ПродажиОбороты.КоличествоОборот,
ПродажиОбороты.Номенклатура.ЕдиницаХраненияОстатков
Посмотрим на задачу шире. В современной практике 1С написание «голого» кода для вывода отчета в консоль используется редко. Лучшим решением будет использование Системы компоновки данных (СКД). Разберем по шагам, почему это выгодно:
При использовании СКД важно правильно настроить роль полей периода. Убедитесь, что для параметров НачалоПериода и КонецПериода установлены соответствующие типы, а в поле «Выражение» для даты окончания прописано использование конца дня. Это гарантирует точность ваших данных.
Таким образом, мы выяснили, что для корректного решения задачи необходимо не только знать язык запросов, но и понимать архитектуру метаданных 1С, правильно обрабатывать временные границы и учитывать специфику хранения единиц измерения товара.