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