Как настроить выборку номенклатуры под определенного контрагента в 1С:Бухгалтерия 3.0?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет Торговля и дистрибуция
← На главную

При оформлении документов реализации в конфигурации 1С:Бухгалтерия предприятия 3.0 нередко возникает задача ограничить список доступных товаров в зависимости от выбранного покупателя. Рассмотрим архитектурные особенности типовой конфигурации, типичные ошибки проектирования и по шагам разберем грамотную реализацию механизма товарных матриц с помощью расширения конфигурации.

Архитектурные ограничения и частые ошибки

Разберем, какие способы решения задачи являются ошибочными и к каким последствиям они приводят:

  1. Назначение справочника Контрагенты владельцем справочника Номенклатура: это грубая ошибка проектирования. При включении подчинения один и тот же товар невозможно будет оприходовать на склад и отгрузить разным контрагентам. Ломается сквозной складской и партионный учет, счета учета номенклатуры (08, 10, 41, 43), а также регламентированная отчетность.
  2. Именование групп номенклатуры по именам контрагентов: привязка логики к наименованиям папок приводит к дублированию позиций, росту базы и невозможности адекватно сопоставлять остатки товаров. Кроме того, наименования клиентов могут меняться, а один товар может поставляться нескольким покупателям.
  3. Использование механизма RLS: в типовой «1С:Бухгалтерии предприятия 3.0» механизм RLS работает только в разрезе организаций. Он накладывает статичные ограничения на весь сеанс пользователя и не может динамически менять доступность номенклатуры при смене реквизита в открытом документе.

Архитектурно правильная схема: регистр сведений «Товарные матрицы»

Оптимальный способ организовать связь «Покупатель — Доступные товары» без изменения типовой конфигурации — создать расширение с новым непериодическим независимым регистром сведений ТоварнаяМатрицаКонтрагентов.

Структура регистра включает следующие измерения:

  1. Контрагент — тип СправочникСсылка.Контрагенты.
  2. Номенклатура — тип СправочникСсылка.Номенклатура (или СправочникСсылка.НоменклатурныеГруппы, если привязка идет укрупненно).

Если позиция закреплена за клиентом, в регистре создается соответствующая запись. Если матрица для контрагента не заполнена вовсе, можно считать, что для него доступен весь ассортимент.

Пошаговая техническая реализация механизма

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

Шаг 1. Перехват автоподбора и контекстного ввода

Посмотрим на пример переопределения обработчика ввода по строке. В расширении для модуля менеджера справочника Номенклатура перехватываем событие ОбработкаПолученияДанныхВыбора:


&Вместо("ОбработкаПолученияДанныхВыбора")
Процедура Расш1_ОбработкаПолученияДанныхВыбора(ДанныеВыбора, ПараметрыВыбора, СтандартнаяОбработка)
    
    Если ПараметрыВыбора.Свойство("КонтрагентОтбор") И ЗначениеЗаполнено(ПараметрыВыбора.КонтрагентОтбор) Тогда
        СтандартнаяОбработка = Ложь;
        
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ РАЗРЕШЕННЫЕ
            |	Номенклатура.Ссылка КАК Ссылка,
            |	Номенклатура.Наименование КАК Наименование
            |ИЗ
            |	Справочник.Номенклатура КАК Номенклатура
            |ГДЕ
            |	Номенклатура.Наименование ПОДОБНО &СтрокаПоиска
            |	И (НЕ Номенклатура.ЭтоГруппа)
            |	И Номенклатура.Ссылка В
            |		(ВЫБРАТЬ
            |			Матрица.Номенклатура
            |		ИЗ
            |			РегистрСведений.ТоварнаяМатрицаКонтрагентов КАК Матрица
            |		ГДЕ
            |			Матрица.Контрагент = &Контрагент)";
            
        Запрос.УстановитьПараметр("СтрокаПоиска", "%" + ПараметрыВыбора.СтрокаПоиска + "%");
        Запрос.УстановитьПараметр("Контрагент", ПараметрыВыбора.КонтрагентОтбор);
        
        Выборка = Запрос.Выполнить().Выбрать();
        ДанныеВыбора = Новый СписокЗначений;
        Пока Выборка.Следующий() Цикл
            ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
        КонецЦикла;
    Иначе
        ПродолжитьВызов(ДанныеВыбора, ПараметрыВыбора, СтандартнаяОбработка);
    КонецЕсли;

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

Шаг 2. Настройка параметров выбора на форме документа

Проанализируем форму документа Реализация (акты, накладные, УПД). В расширении формы при изменении контрагента и при открытии документа передаем контекст в параметры выбора колонки номенклатуры:


&НаКлиенте
Процедура Расш1_КонтрагентПриИзмененииПосле(Элемент)
    ОбновитьПараметрыВыбораНоменклатуры();
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьПараметрыВыбораНоменклатуры()
    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(Новый ПараметрВыбора("КонтрагентОтбор", Объект.Контрагент));
    
    Элементы.ТоварыНоменклатура.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
КонецПроцедуры

Шаг 3. Переопределение открытия формы подбора

В обработчике команды подбора или события НачалоВыбора ячейки табличной части отменяем стандартную логику и передаем отбор в форму списка номенклатуры:


&НаКлиенте
Процедура Расш1_ТоварыНоменклатураНачалоВыбораПеред(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    Если ЗначениеЗаполнено(Объект.Контрагент) Тогда
        СтандартнаяОбработка = Ложь;
        
        ПараметрыОтбора = Новый Структура;
        ПараметрыОтбора.Вставить("КонтрагентОтбор", Объект.Контрагент);
        
        ПараметрыФормы = Новый Структура("Отбор", ПараметрыОтбора);
        ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Истина);
        
        ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
    КонецЕсли;
КонецПроцедуры

Шаг 4. Серверный контроль при проведении документа

Пользователь может скопировать строки из другого документа или изменить контрагента в шапке уже заполненной накладной. Чтобы исключить проведение некорректных данных, добавим валидацию в событие ОбработкаПроверкиЗаполнения документа реализации:


&Вместо("ОбработкаПроверкиЗаполнения")
Процедура Расш1_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    ПродолжитьВызов(Отказ, ПроверяемыеРеквизиты);
    
    Если Отказ Или НЕ ЗначениеЗаполнено(Контрагент) Тогда
        Возврат;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Товары.НомерСтроки КАК НомерСтроки,
        |	Товары.Номенклатура КАК Номенклатура
        |ИЗ
        |	Документ.РеализацияТоваровУслуг.Товары КАК Товары
        |ГДЕ
        |	Товары.Ссылка = &Ссылка
        |	И Товары.Номенклатура НЕ В
        |		(ВЫБРАТЬ
        |			Матрица.Номенклатура
        |		ИЗ
        |			РегистрСведений.ТоварнаяМатрицаКонтрагентов КАК Матрица
        |		ГДЕ
        |			Матрица.Контрагент = &Контрагент)";
        
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Запрос.УстановитьПараметр("Контрагент", Контрагент);
    
    Результат = Запрос.Выполнить();
    Если НЕ Результат.Пустой() Тогда
        Выборка = Результат.Выбрать();
        Пока Выборка.Следующий() Цикл
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
                СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                    "Товар ""%1"" в строке %2 недоступен для отгрузки данному контрагенту!",
                    Выборка.Номенклатура,
                    Выборка.НомерСтроки),
                Ссылка,
                "Товары[" + Формат(Выборка.НомерСтроки - 1, "ЧГ=0") + "].Номенклатура",
                "Объект",
                Отказ);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Альтернативные варианты без доработки конфигурации

Если внесение доработок через расширение невозможно, рассмотрим типовые альтернативы:

  1. Использование дополнительных реквизитов (БСП): через механизм «Дополнительные реквизиты и сведения» можно добавить у номенклатуры поле «Группа доступа клиентов» или «Контрагент» и настраивать стандартный отбор в типовом окне подбора вручную через кнопку «Настройка списка».
  2. Работа через предварительные заказы и счета: оформление реализации строго вводом на основании документов «Счет на оплату покупателю», где подбор согласуется менеджером заранее.
← На главную