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