При оформлении оптовых и розничных продаж менеджеры часто сталкиваются с необходимостью видеть объемы отгружаемого товара одновременно в нескольких единицах измерения. Например, базовый учет ведется в штуках, но для логистики и склада критически важно сразу видеть объем в кубических метрах (м³), вес в килограммах или площадь в квадратных метрах (м²). При этом стандартный механизм платформы 1С «Изменить форму» позволяет вывести реквизиты номенклатуры «через точку», но не обеспечивает динамического пересчета при изменении количества товара в строке.
В этой статье мы подробно разберем, почему стандартный вывод реквизитов не работает для динамических расчетов, как правильно реализовать эту задачу с помощью расширения конфигурации (сохранив возможность автоматического обновления), а также рассмотрим встроенные альтернативные механизмы и обходные пути решения проблемы.
Когда пользователь пытается самостоятельно решить проблему через настройку формы (команда Еще — Изменить форму), он находит в структуре табличной части Товары поле Номенклатура, разворачивает его свойства и добавляет на форму сопутствующие реквизиты (например, единицу хранения, объем, вес или коэффициент пересчета). Действительно, при добавлении в документ новой строки с количеством «1» эти данные отображаются корректно, так как они просто считываются напрямую из карточки номенклатуры.
Однако при изменении количества в строке (например, с 1 шт. на 10 шт.) автоматического пересчета в дополнительной колонке не происходит. Это связано со следующими техническими особенностями платформы 1С:
Номенклатура. Они хранятся в базе данных как константы для конкретной номенклатурной позиции.ПриИзменении. Стандартный механизм настройки формы такой код генерировать не умеет.Для решения этой задачи требуется внедрение программного алгоритма пересчета. Ниже мы детально разберем три основных способа реализации.
Использование механизма расширений конфигурации — самый правильный и безопасный путь с точки зрения программирования. Он позволяет внедрить необходимый код и новые элементы интерфейса, не снимая основную конфигурацию с поддержки. Это гарантирует, что типовые обновления системы будут проходить в штатном режиме.
Проанализируем пошагово процесс создания такого расширения:
Шаг 1. Создание реквизитов формы
Нам не нужно создавать новые реквизиты в самом документе (в базе данных), чтобы не увеличивать размер информационной базы и не усложнять структуру таблиц. Достаточно добавить расчетные колонки как Реквизиты формы в расширении формы документа РеализацияТоваровУслуг. Создадим в табличной части Товары на форме реквизит КоличествоДополнительное с типом Число (15, 3).
Шаг 2. Перехват события изменения количества
Нам необходимо привязаться к изменению количества или номенклатуры в строке. Для этого мы перехватываем обработчик события ТоварыКоличествоПриИзменении. В расширении мы создаем метод с директивой &После:
&НаКлиенте
Процедура Расширение_ТоварыКоличествоПриИзмененииПосле(Элемент)
ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Выполняем расчет на клиенте
РассчитатьДополнительноеКоличествоСтроки(ТекущиеДанные);
КонецПроцедуры
Шаг 3. Реализация алгоритма расчета и кэширования
Чтобы система работала быстро и не зависала при редактировании строк, нельзя при каждом изменении количества отправлять запрос к базе данных на сервере (так называемая проблема N+1 запросов). Мы организуем кэширование коэффициентов пересчета непосредственно в модуле формы или будем получать их при активации строки/открытии документа.
Рассмотрим пример серверного метода расчета коэффициентов, который вызывается при заполнении строки номенклатурой или при открытии формы:
&НаСервереБезКонтекста
Функция ПолучитьКоэффициентыПересчета(НоменклатураСсылка)
Результат = Новый Структура("Коэффициент, Найдено", 1, Ложь);
// Проверяем наличие дополнительных единиц в карточке товара
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.ЕдиницаДляОтчетов.Коэффициент КАК Коэффициент
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", НоменклатураСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Если ЗначениеЗаполнено(Выборка.Коэффициент) И Выборка.Коэффициент > 0 Тогда
Результат.Коэффициент = Выборка.Коэффициент;
Результат.Найдено = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
На стороне клиента расчет будет выглядеть следующим образом:
&НаКлиенте
Процедура РассчитатьДополнительноеКоличествоСтроки(СтрокаТабличнойЧасти)
Если Не ЗначениеЗаполнено(СтрокаТабличнойЧасти.Номенклатура) Тогда
СтрокаТабличнойЧасти.КоличествоДополнительное = 0;
Возврат;
КонецЕсли;
// В реальном решении рекомендуется получать коэффициенты из кэш-таблицы на форме
СтруктураКоэф = ПолучитьКоэффициентыПересчета(СтрокаТабличнойЧасти.Номенклатура);
Если СтруктураКоэф.Найдено Тогда
СтрокаТабличнойЧасти.КоличествоДополнительное = СтрокаТабличнойЧасти.Количество * СтруктураКоэф.Коэффициент;
Иначе
СтрокаТабличнойЧасти.КоличествоДополнительное = СтрокаТабличнойЧасти.Количество;
КонецЕсли;
КонецПроцедуры
Шаг 4. Инициализация при открытии сохраненного документа
Чтобы при открытии уже созданных документов расчетные колонки не оставались пустыми, необходимо выполнять аналогичный обход строк табличной части на сервере при создании формы. Для этого перехватываем событие ПриСозданииНаСервере:
&НаСервере
Процедура Расширение_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Обходим строки коллекции и заполняем расчетные колонки на сервере за один проход
Для Каждого СтрокаТовар Из Объект.Товары Цикл
// Здесь мы можем использовать прямой запрос ко всей номенклатуре документа
// для оптимизации производительности
Коэффициент = ПолучитьКоэффициентИзБазы(СтрокаТовар.Номенклатура);
СтрокаТовар.КоличествоДополнительное = СтрокаТовар.Количество * Коэффициент;
КонецЦикла;
КонецПроцедуры
Перед тем как приступать к разработке расширения, важно убедиться, что возможности вашей конфигурации не позволяют решить задачу стандартными средствами. В современных решениях на платформе 1С («1С:ERP», «1С:Комплексная автоматизация», «1С:Управление торговлей 11», «1С:УНФ») заложен мощный функционал двойного учета единиц измерения:
Зачастую вывод дополнительных единиц измерения в саму экранную форму документа реализации требуется только для того, чтобы менеджер визуально контролировал правильность данных перед печатью документов для клиента или логистов.
Если нет строгой необходимости видеть эти цифры на экране в процессе набора позиций, наиболее экономичным и простым решением будет создание внешней печатной формы (ВПФ):
Преимущества использования ВПФ: