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