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

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

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

Разберем типичные ошибки, возникающие при разработке такого функционала, и рассмотрим правильные варианты реализации программного кода.

Анализ типичных ошибок начинающих разработчиков

Проанализируем основные проблемы, которые встречаются в исходных вариантах кода:

  1. Некорректная работа с результатом запроса: У объекта ВыборкаИзРезультатаЗапроса отсутствует метод Получить(). Попытка вызвать конструкцию РезультатЗапроса.Выбрать.Получить(0) приводит к ошибке времени выполнения. Для чтения данных из выборки необходимо выполнять позиционирование с помощью метода Следующий().
  2. Прямое присвоение значений элементам формы: Попытка записать результат вычислений напрямую в элементы управления или выполнять математические операции вида ЭлементыФормы.Поле1 + ЭлементыФормы.Поле2 = ЭлементыФормы.Поле3 синтаксически неверна. Расчеты производятся с переменными или реквизитами обработки, а на форму выводятся связанные данные.
  3. Особенности хранения веса в типовой конфигурации: В документах РеализацияТоваровУслуг и ПоступлениеТоваровУслуг реквизита массы нет ни в шапке, ни в табличной части. Поле Вес хранится в подчиненном справочнике ЕдиницыИзмерения, привязанном к конкретной номенклатуре. Поэтому суммировать нужно произведение количества на вес единицы измерения по табличной части Товары.
  4. Обработка значений NULL и учет проведенности: Если у номенклатуры не задан вес единицы измерения, в результате вычисления выражения появится значение NULL, что может исказить итог. Кроме того, необходимо обязательно отбирать только проведенные документы с помощью условия Ссылка.Проведен = ИСТИНА.

Способ 1. Получение общего веса через объединение запросов к табличным частям

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


Процедура КнопкаВыполнитьНажатие(Кнопка)

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

    Запрос.УстановитьПараметр("Начало", НачалоДня(Нач));
    Запрос.УстановитьПараметр("Конец", КонецДня(Кон));

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

    ВесПродаж = 0;
    ВесПрихода = 0;

    Пока Выборка.Следующий() Цикл
        Если Выборка.ТипОперации = "Расход" Тогда
            ВесПродаж = Выборка.ОбщаяМасса;
        ИначеЕсли Выборка.ТипОперации = "Приход" Тогда
            ВесПрихода = Выборка.ОбщаяМасса;
        КонецЕсли;
    КонецЦикла;

    // Вычисляем общий итог
    ОбщийВес = ВесПродаж + ВесПрихода;

КонецПроцедуры

Разберем по шагам, что происходит в данном коде:

  1. Мы используем конструкцию ОБЪЕДИНИТЬ ВСЕ, что позволяет получить данные по продажам и поступлениям за один запрос.
  2. Функция ЕСТЬNULL гарантирует, что отсутствие веса в единице измерения будет воспринято как 0 и не приведет к потере всей суммы.
  3. Параметры периода приводятся к началу и концу дня с помощью функций НачалоДня() и КонецДня(), чтобы включить в выборку все документы за указанные сутки.
  4. Обход результатов выполняется стандартным методом Выборка.Следующий(), после чего значения распределяются по реквизитам.

Способ 2. Выгрузка в таблицу значений при простых запросах

Если требуется получить единственный суммарный показатель по отдельному документу или агрегату, можно использовать выгрузку результата в объект ТаблицаЗначений. Посмотрим на пример:


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

Запрос.УстановитьПараметр("Начало", НачалоДня(Нач));
Запрос.УстановитьПараметр("Конец", КонецДня(Кон));

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

Если ТаблицаРезультата.Количество() > 0 Тогда
    ВесПродаж = ТаблицаРезультата[0].Масса;
Иначе
    ВесПродаж = 0;
КонецЕсли;

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

← На главную