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