Как в документе 1С отфильтровать список единиц измерения по выбранной номенклатуре?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

При работе с табличными частями документов в 1С часто возникает задача: сделать так, чтобы выбор в одном поле зависел от значения в другом. Классический пример — работа с номенклатурой и её единицами измерения. Пользователь выбирает товар в строке, и в соседней колонке должен появиться список не всех возможных единиц измерения из справочника, а только тех, которые относятся к этому конкретному товару. Это значительно ускоряет работу, снижает количество ошибок и делает интерфейс интуитивно понятным.

Проанализируем ситуацию: у нас есть документ, например, «Сдельный наряд». В его табличной части «Операции» есть колонка Номенклатура и колонка ЕдиницаИзмерения1. В справочнике «Номенклатура» для каждого элемента задан свой перечень допустимых единиц измерения (например, в подчинённом справочнике или в отдельной табличной части). Наша цель — при выборе номенклатуры в строке документа, в поле ЕдиницаИзмерения1 предоставить пользователю для выбора только те единицы, которые для этой номенклатуры указаны.

Рассмотрим несколько способов решения этой задачи, от самого простого и рекомендуемого до более сложных, которые могут понадобиться в нестандартных ситуациях.

Решение 1: Механизм «Связи параметров выбора» (рекомендуемый способ)

Платформа 1С:Предприятие 8 предоставляет мощный и удобный декларативный инструмент, который позволяет настроить подобные зависимости без единой строчки кода. Он называется «Связи параметров выбора». Это основной и самый правильный способ решения нашей задачи.

Разберем по шагам, как его настроить:

  1. Откроем конфигуратор и найдем наш документ (в нашем примере — «Сдельный наряд»).
  2. Перейдем на вкладку «Формы» и откроем основную форму документа, в которой находится нужная нам табличная часть.
  3. В дереве элементов формы найдем нашу табличную часть (например, Операции) и внутри нее — поле, отвечающее за выбор единицы измерения (ОперацииЕдиницаИзмерения1).
  4. Выделим это поле и откроем палитру его свойств (правой кнопкой мыши -> «Свойства»).
  5. В палитре свойств найдем свойство СвязиПараметровВыбора. Нажмем на кнопку с тремя точками (...) справа от названия свойства, чтобы открыть окно настройки связей.
  6. В открывшемся окне нам нужно установить связь. Мы говорим системе: «Значение для отбора в списке единиц измерения нужно брать из другого поля». Система попросит указать, из какого именно.
    • В левой части окна (Параметр выбора) мы указываем, по какому полю будет происходить отбор в справочнике единиц измерения. Чаще всего, если единицы измерения подчинены номенклатуре, это будет параметр Отбор.Владелец. Если связь иная (например, через реквизит), то нужно выбрать соответствующее поле отбора.
    • В правой части (Поле для значения) мы указываем, откуда брать значение для этого отбора. Нам нужно значение из колонки Номенклатура текущей строки табличной части. Путь к этому значению будет выглядеть примерно так: Элементы.Операции.ТекущиеДанные.Номенклатура.

После нажатия «ОК» платформа все сделает сама. Теперь, когда пользователь в режиме «Предприятие» выберет номенклатуру в строке, при нажатии на кнопку выбора в поле единицы измерения список будет автоматически отфильтрован. Система возьмет выбранную номенклатуру, подставит ее в отбор по владельцу для справочника единиц измерения и покажет только подходящие значения.

Важный момент: Этот механизм идеально работает, когда есть четкая связь между объектами. Например, справочник «Единицы измерения» подчинен справочнику «Номенклатура». Если же единицы измерения хранятся в табличной части самого элемента номенклатуры, связь будет выглядеть немного иначе, но принцип останется тем же — мы связываем параметр отбора с данными из формы.

Решение 2: Программная обработка события «НачалоВыбора»

Иногда логика фильтрации может быть сложнее, чем простая связь по владельцу. Например, нужно учитывать остатки на складе, свойства товара или другие условия, которые нельзя описать декларативно. В таких случаях можно воспользоваться программным способом, переопределив стандартное поведение поля выбора.

Для этого используется событие элемента формы НачалоВыбора.

Разберем алгоритм действий:

  1. В свойствах поля ОперацииЕдиницаИзмерения1 на вкладке «События» найдем событие НачалоВыбора и создадим для него обработчик на клиенте.
  2. В коде обработчика нам нужно отменить стандартное открытие формы выбора и сформировать свой собственный список значений.

Посмотрим на примерный код такого обработчика:


&НаКлиенте
Процедура ОперацииЕдиницаИзмерения1НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

    // 1. Отменяем стандартное поведение, чтобы открыть свою форму или список
    СтандартнаяОбработка = Ложь;

    // 2. Получаем текущие данные строки, чтобы узнать, какая номенклатура выбрана
    ТекущаяСтрока = Элементы.Операции.ТекущиеДанные;
    Если ТекущаяСтрока = Неопределено Или НЕ ЗначениеЗаполнено(ТекущаяСтрока.Номенклатура) Тогда
        // Если номенклатура не выбрана, ничего не делаем
        Возврат;
    КонецЕсли;

    // 3. Формируем список значений для выбора
    СписокДляВыбора = Новый СписокЗначений;

    // 4. С помощью запроса к серверу получаем нужные единицы измерения
    // (для производительности лучше вызывать серверную функцию)
    МассивЕдиниц = ПолучитьЕдиницыИзмеренияНоменклатуры(ТекущаяСтрока.Номенклатура);

    // 5. Заполняем список
    Для Каждого Единица Из МассивЕдиниц Цикл
        СписокДляВыбора.Добавить(Единица.Ссылка, Единица.Представление);
    КонецЦикла;
    
    // 6. Открываем форму выбора из нашего списка
    ВыбранноеЗначение = ВыбратьИзСписка(СписокДляВыбора, Элемент);
    
    // 7. Если пользователь что-то выбрал, записываем значение в поле
    Если ВыбранноеЗначение <> Неопределено Тогда
        ТекущаяСтрока.ЕдиницаИзмерения1 = ВыбранноеЗначение.Значение;
    КонецЕсли;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьЕдиницыИзмеренияНоменклатуры(Номенклатура)
    
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |   ЕдиницыИзмерения.Ссылка,
        |   ЕдиницыИзмерения.Представление
        |ИЗ
        |   Справочник.ЕдиницыИзмерения КАК ЕдиницыИзмерения
        |ГДЕ
        |   ЕдиницыИзмерения.Владелец = &Номенклатура";

    Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
    
    Результат = Запрос.Выполнить().Выгрузить();
    Возврат Результат;

КонецФункции

Этот метод дает полный контроль над процессом, но он значительно сложнее в реализации и поддержке. Его стоит использовать только тогда, когда декларативный способ через СвязиПараметровВыбора не подходит.

Решение 3: Вывод данных «через точку»

На форумах иногда можно встретить совет «вывести реквизит через точку», например, Номенклатура.ЕдиницаИзмерения. Важно понимать, в какой ситуации это применимо.

Этот подход не предназначен для предоставления списка выбора. Он используется, когда у номенклатуры есть только одна основная единица измерения, хранящаяся как реквизит самого справочника «Номенклатура» (например, реквизит ОсновнаяЕдиницаИзмерения).

В этом случае можно сделать следующее:


&НаКлиенте
Процедура ОперацииНоменклатураПриИзменении(Элемент, СтандартнаяОбработка)
    ТекущаяСтрока = Элементы.Операции.ТекущиеДанные;
    Если ТекущаяСтрока <> Неопределено И ЗначениеЗаполнено(ТекущаяСтрока.Номенклатура) Тогда
        // Предполагается, что у номенклатуры есть реквизит ОсновнаяЕдиницаИзмерения
        // Для получения реквизита может потребоваться вызов сервера
        ТекущаяСтрока.ЕдиницаИзмерения1 = ПолучитьОсновнуюЕдиницу(ТекущаяСтрока.Номенклатура);
    КонецЕсли;
КонецПроцедуры

Этот метод не предоставляет выбора, а лишь автоматизирует заполнение поля на основе другого, что тоже является полезной практикой для упрощения ввода данных.

Полезный совет: изучайте типовые конфигурации

Один из самых эффективных способов научиться решать задачи в 1С — это смотреть, как они уже решены разработчиками фирмы «1С» в стандартных конфигурациях (Управление торговлей, ERP, Бухгалтерия и т.д.).

Откройте в конфигураторе, например, документ РеализацияТоваровУслуг. Найдите его основную форму, в ней — табличную часть Товары. Выделите поле ЕдиницаИзмерения и посмотрите его свойство СвязиПараметровВыбора. Вы увидите готовый, работающий пример реализации той самой задачи, которую мы разбирали. Анализ таких примеров — бесценный источник знаний и лучших практик.

← На главную