При разработке отчетов и обработок в платформе 1С 7.7 часто возникает необходимость вывести данные о суммах и объемах продаж по конкретным позициям номенклатуры. Разберем типичные ошибки, с которыми сталкиваются начинающие разработчики при обращении к оборотным регистрам накопления, и рассмотрим правильный алгоритм получения показателей через объект Запрос.
Выясним причину, почему при попытке получить данные напрямую из объекта Регистр.Продажи через методы ВыбратьИтоги() и ПолучитьИтог() программа выводит одинаковые значения для всех строк отчета.
Когда мы обращаемся к объекту регистра без предварительного вызова метода УстановитьФильтр() или УстановитьЗначениеФильтра(), метод ВыбратьИтоги() рассчитывает общие общие итоги по всему регистру за всё время, не разделяя суммы по конкретным позициям справочника Номенклатура.
Кроме того, оборотный регистр Продажи хранит агрегированные суммы реализации и количество. Если требуется узнать среднюю цену реализации за период, в самом регистре она не хранится как отдельное поле — ее необходимо вычислять математически путем деления общей стоимости на количество.
Наиболее эффективным и быстродействующим способом получения итогов по продажам в 1С 7.7 является использование объекта Запрос. Рассмотрим, как правильно составить текст запроса для обращения к оборотным ресурсам регистра.
Для корректного получения данных необходимо сделать следующее:
Период с ... по ....Номенклатура) и ресурсов (Количество, ПродСтоимость).Сумма() к ресурсам регистра.Посмотрим на пример готового кода для формирования запроса:
Перем Запрос, ТекстЗапроса, Таб;
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "//{{ЗАПРОС(Сформировать)
|Период с ВыбНачПериода по ВыбКонПериода;
|Номенклатура = Регистр.Продажи.Номенклатура;
|Количество = Регистр.Продажи.Количество;
|ПродСтоимость = Регистр.Продажи.ПродСтоимость;
|Функция КоличествоСумма = Сумма(Количество);
|Функция ПродСтоимостьСумма = Сумма(ПродСтоимость);
|Группировка Номенклатура Без Групп упорядочить по Номенклатура.Наименование;
|";
Если ПустоеЗначение(ВыбТМЦ) = 0 Тогда
ТекстЗапроса = ТекстЗапроса + "Условие(Номенклатура в ВыбТМЦ);";
КонецЕсли;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
Проанализируем процесс обхода результатов запроса и расчета средней продажной цены. В цикле обхода группировки вычисляем цену делением суммы на количество. При этом обязательно проверяем делитель на равенство нулю, чтобы избежать фатальной ошибки выполнения программы.
Пока Запрос.Группировка("Номенклатура") = 1 Цикл
ТекНоменклатура = Запрос.Номенклатура;
ВсегоКоличество = Запрос.КоличествоСумма;
ВсегоСумма = Запрос.ПродСтоимостьСумма;
// Безопасный расчет цены продажи
Если ВсегоКоличество <> 0 Тогда
ЦенаПродажи = ВсегоСумма / ВсегоКоличество;
Иначе
ЦенаПродажи = 0;
КонецЕсли;
// Вывод полученных данных в печатную форму или таблицу значений
// Таб.ВывестиСекцию("Строка");
КонецЦикла;
При работе с регистром Продажи необходимо учитывать следующие моменты:
.Получить(Дата).Сумма(). Функции остатков НачОст и КонОст применять к таким регистрам нельзя.ВыгрузитьИтоги: Если требуется получить данные регистра без использования объекта Запрос, можно воспользоваться методом Регистр.Продажи.ВыгрузитьИтоги(ТЗ). В этом случае данные будут помещены в объект ТаблицаЗначений, где их можно сгруппировать и отфильтровать средствами языка.