При создании внешних обработок и отчетов в конфигурации «1С:Управление торговлей 10.3» разработчики нередко сталкиваются с задачей подсчета суммарного веса товаров по проведенным документам поступления и реализации за определенный период. Начинающие программисты часто допускают ошибки в синтаксисе языка запросов, структуре обращения к данным и при получении результатов выборки.
Разберем типичные ошибки, возникающие при разработке такого функционала, и рассмотрим правильные варианты реализации программного кода.
Проанализируем основные проблемы, которые встречаются в исходных вариантах кода:
ВыборкаИзРезультатаЗапроса отсутствует метод Получить(). Попытка вызвать конструкцию РезультатЗапроса.Выбрать.Получить(0) приводит к ошибке времени выполнения. Для чтения данных из выборки необходимо выполнять позиционирование с помощью метода Следующий().ЭлементыФормы.Поле1 + ЭлементыФормы.Поле2 = ЭлементыФормы.Поле3 синтаксически неверна. Расчеты производятся с переменными или реквизитами обработки, а на форму выводятся связанные данные.РеализацияТоваровУслуг и ПоступлениеТоваровУслуг реквизита массы нет ни в шапке, ни в табличной части. Поле Вес хранится в подчиненном справочнике ЕдиницыИзмерения, привязанном к конкретной номенклатуре. Поэтому суммировать нужно произведение количества на вес единицы измерения по табличной части Товары.NULL, что может исказить итог. Кроме того, необходимо обязательно отбирать только проведенные документы с помощью условия Ссылка.Проведен = ИСТИНА.Рассмотрим наиболее надежный и правильный вариант запроса, который обращается к табличным частям Товары документов реализации и поступления, вычисляет вес каждой строки и агрегирует результат в рамках одного обращения к базе данных:
Процедура КнопкаВыполнитьНажатие(Кнопка)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ""Расход"" КАК ТипОперации,
| СУММА(ЕСТЬNULL(Товары.Количество * Товары.ЕдиницаИзмерения.Вес, 0)) КАК ОбщаяМасса
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Проведен
| И Товары.Ссылка.Дата МЕЖДУ &Начало И &Конец
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ""Приход"",
| СУММА(ЕСТЬNULL(Товары.Количество * Товары.ЕдиницаИзмерения.Вес, 0))
|ИЗ
| Документ.ПоступлениеТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Проведен
| И Товары.Ссылка.Дата МЕЖДУ &Начало И &Конец";
Запрос.УстановитьПараметр("Начало", НачалоДня(Нач));
Запрос.УстановитьПараметр("Конец", КонецДня(Кон));
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
ВесПродаж = 0;
ВесПрихода = 0;
Пока Выборка.Следующий() Цикл
Если Выборка.ТипОперации = "Расход" Тогда
ВесПродаж = Выборка.ОбщаяМасса;
ИначеЕсли Выборка.ТипОперации = "Приход" Тогда
ВесПрихода = Выборка.ОбщаяМасса;
КонецЕсли;
КонецЦикла;
// Вычисляем общий итог
ОбщийВес = ВесПродаж + ВесПрихода;
КонецПроцедуры
Разберем по шагам, что происходит в данном коде:
ОБЪЕДИНИТЬ ВСЕ, что позволяет получить данные по продажам и поступлениям за один запрос.ЕСТЬNULL гарантирует, что отсутствие веса в единице измерения будет воспринято как 0 и не приведет к потере всей суммы.НачалоДня() и КонецДня(), чтобы включить в выборку все документы за указанные сутки.Выборка.Следующий(), после чего значения распределяются по реквизитам.Если требуется получить единственный суммарный показатель по отдельному документу или агрегату, можно использовать выгрузку результата в объект ТаблицаЗначений. Посмотрим на пример:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СУММА(ЕСТЬNULL(Товары.Количество * Товары.ЕдиницаИзмерения.Вес, 0)) КАК Масса
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Проведен
| И Товары.Ссылка.Дата МЕЖДУ &Начало И &Конец";
Запрос.УстановитьПараметр("Начало", НачалоДня(Нач));
Запрос.УстановитьПараметр("Конец", КонецДня(Кон));
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Если ТаблицаРезультата.Количество() > 0 Тогда
ВесПродаж = ТаблицаРезультата[0].Масса;
Иначе
ВесПродаж = 0;
КонецЕсли;
Рекомендация: Для отладки текстов запросов и проверки корректности возвращаемых данных всегда используйте типовую внешнюю обработку Консоль запросов. Она позволяет в интерактивном режиме задать параметры, просмотреть структуру колонок и убедиться в правильности итоговых цифр перед добавлением кода в конфигурацию или обработку.