Как разделить логику позаказного обеспечения для заказов покупателей и заказов на производство в 1С

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

При автоматизации производственного и складского учета часто возникает необходимость гибко управлять резервированием материалов. Рассмотрим практическую задачу: в информационной системе используется специализированная обработка обеспечения потребностей. Нам необходимо разделить логику резервирования под разные типы заказов. Если в параметрах номенклатуры (или варианта исполнения) включен флаг «Обеспечивается позаказно», система должна резервировать товар только под Заказы покупателей. Если же установлен флаг «Обеспечивается позаказно в производстве» (и позиция является ключевой), резерв должен создаваться исключительно под Заказы на производство. Кроме того, такие строки в обработке обеспечения должны визуально выделяться жирным шрифтом.

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

Этап 1. Разделение серверной логики обеспечения по типу документа

Основная сложность исходного кода обработки заключалась в отсутствии проверки контекста. Обработка не «знала», для какого именно документа-основания она рассчитывает потребности. Чтобы решить эту проблему, нам нужно передать в обработку ссылку на исходный документ и проанализировать его тип на сервере.

Предположим, что в обработке обеспечения ВхОбработкаОбъект уже присутствует реквизит (или мы можем его получить), содержащий ссылку на текущий заказ. Назовем его ДокументЗаказа. Проанализируем ситуацию и модифицируем серверную функцию УправлениеОбеспечениемЗаказов_ВыполнитьНаСервере следующим образом:


Функция УправлениеОбеспечениемЗаказов_ВыполнитьНаСервере(ВхОбработкаОбъект, ВхДействие, ВхДопПараметры = Неопределено) Экспорт
    глОчиститьСообщенияНаСервере();
    
    _ПараметрыОбработки = Новый Структура;
    _МД = ВхОбработкаОбъект.Метаданные;
    
    // Переносим реквизиты обработки в структуру параметров
    Для Каждого _Реквизит Из _МД.Реквизиты Цикл
        Если ТипЗнч(ВхОбработкаОбъект[_Реквизит.Имя]) = Тип("СписокЗначений") Тогда
            _ПараметрыОбработки.Вставить(_Реквизит.Имя, ВхОбработкаОбъект[_Реквизит.Имя].ВыгрузитьЗначения());
        Иначе
            _ПараметрыОбработки.Вставить(_Реквизит.Имя, ВхОбработкаОбъект[_Реквизит.Имя]);
        КонецЕсли;
    КонецЦикла;
    
    Если ВхДействие = "ВыполнитьПервоначальноеЗаполнение" Тогда
        
        // Выгружаем колонки табличных частей для подготовки структуры
        Для Каждого _ТабличнаяЧасть Из _МД.ТабличныеЧасти Цикл
            _ПараметрыОбработки.Вставить(_ТабличнаяЧасть.Имя, ВхОбработкаОбъект[_ТабличнаяЧасть.Имя].ВыгрузитьКолонки());
        КонецЦикла;
        
        // Вызываем типовое или базовое заполнение потребностей
        ОбщийМодуль_УОЗ.ВыполнитьПервоначальноеЗаполнение(_ПараметрыОбработки);
        
        // Определяем тип документа-заказа для разделения логики
        ТипЗаказа = Неопределено;
        Если _ПараметрыОбработки.Свойство("ДокументЗаказа") Тогда
            ТипЗаказа = ТипЗнч(_ПараметрыОбработки.ДокументЗаказа);
        КонецЕсли;
        
        // Обходим табличные части и применяем наши правила резервирования
        Для Каждого _ТабличнаяЧасть Из _МД.ТабличныеЧасти Цикл
            
            Если _ТабличнаяЧасть.Имя = "ТЧПотребностиВТМЦ" Тогда
                
                // Получаем таблицу потребностей, заполненную базовым механизмом
                ТаблицаПотребностей = _ПараметрыОбработки[_ТабличнаяЧасть.Имя];
                
                Для Каждого СтрокаТЧ Из ТаблицаПотребностей Цикл
                    
                    Вариант = СтрокаТЧ.ВариантИсполнения;
                    
                    // Предварительно сбрасываем резерв
                    СтрокаТЧ.КолРезерв = 0;
                    
                    // Сценарий 1: Обеспечение под Заказ покупателя (Заказ клиента)
                    Если ТипЗаказа = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
                        
                        Если Вариант.ОбеспечиваетсяПозаказно Тогда
                            // Резервируем весь объем необеспеченной потребности
                            СтрокаТЧ.КолРезерв = СтрокаТЧ.КолНеобеспечено;
                        КонецЕсли;
                        
                    // Сценарий 2: Обеспечение под Заказ на производство
                    ИначеЕсли ТипЗаказа = Тип("ДокументСсылка.ЗаказНаПроизводство") Тогда
                        
                        // Проверяем сочетание флагов "Ключевая позиция" и "Обеспечивается позаказно в производстве"
                        Если Вариант.ЯвляетсяКлючевойПозицией И Вариант.ОбеспечиваетсяПозаказноВПроизводстве Тогда
                            СтрокаТЧ.КолРезерв = СтрокаТЧ.КолНеобеспечено;
                        КонецЕсли;
                        
                    КонецЕсли;
                    
                КонецЦикла;
                
                // Загружаем модифицированную таблицу обратно в объект обработки
                ВхОбработкаОбъект[_ТабличнаяЧасть.Имя].Загрузить(ТаблицаПотребностей);
                
            Иначе
                // Для остальных ТЧ оставляем стандартное заполнение
                ВхОбработкаОбъект[_ТабличнаяЧасть.Имя].Загрузить(_ПараметрыОбработки[_ТабличнаяЧасть.Имя]);
            КонецЕсли;
            
        КонецЦикла;
        
    КонецЕсли;
    
    Возврат Истина;
КонецФункции

В данном коде мы избавились от синтаксических ошибок, связанных с неверным закрытием циклов и условий, а также ввели строгую проверку типа документа-основания через функцию ТипЗнч(). Это гарантирует, что избыточные резервы не будут создаваться там, где они не требуются.

Этап 2. Настройка визуального оформления строк

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

Вариант А. Реализация для обычных форм (Толстый клиент)

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

Добавим в модуль формы обработки следующий код:


Процедура ТЧПотребностиВТМЦПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    // Проверяем, что строка содержит данные
    Если ДанныеСтроки <> Неопределено Тогда
        
        Вариант = ДанныеСтроки.ВариантИсполнения;
        
        // Проверяем выполнение условий для выделения
        Если ЗначениеЗаполнено(Вариант) 
           И Вариант.ЯвляетсяКлючевойПозицией 
           И Вариант.ОбеспечиваетсяПозаказноВПроизводстве Тогда
            
            // Устанавливаем полужирное начертание шрифта для всей строки
            ОформлениеСтроки.Шрифт = Новый Шрифт(Элемент.Шрифт, , , Истина);
            
            // Принудительно задаем черный цвет текста
            ОформлениеСтроки.ЦветТекста = ЦветаСтиля.ЦветТекстаФормы;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Важное примечание по производительности: Обработчик ПриВыводеСтроки выполняется очень часто. Не выполняйте внутри него запросы к базе данных или сложные вычисления. Обращение через точку к реквизитам справочника (ДанныеСтроки.ВариантИсполнения.ЯвляетсяКлючевойПозицией) допустимо, если данные закэшированы, однако для высоконагруженных таблиц лучше предварительно выгрузить эти флаги в отдельные скрытые колонки самой табличной части при ее заполнении на сервере.

Вариант Б. Реализация для управляемых форм

Если ваша самописная ERP-система использует управляемый интерфейс, писать программный код в модуле формы для раскраски строк не нужно. Платформа 1С v8.3 предоставляет для этого декларативный механизм «Условное оформление».

Выполним настройку по шагам:

  1. Откройте форму обработки в конфигураторе.
  2. В окне свойств формы перейдите на вкладку «Условное оформление».
  3. Добавьте новый элемент оформления и настройте его свойства:
    • Оформление: найдите свойство Шрифт, выберите текущий шрифт и установите флаг Полужирный. В свойстве Цвет текста выберите Черный (или Цвет текста формы).
    • Условие: добавьте новое условие. Левое значение: Объект.ТЧПотребностиВТМЦ.ВариантИсполнения.ОбеспечиваетсяПозаказноВПроизводстве, Вид сравнения: Равно, Правое значение: Истина. Добавьте второе условие: Объект.ТЧПотребностиВТМЦ.ВариантИсполнения.ЯвляетсяКлючевойПозицией, Вид сравнения: Равно, Правое значение: Истина.
    • Оформляемые поля: выберите поля (колонки) вашей табличной части, которые должны выделяться (например, ТЧПотребностиВТМЦНоменклатура или всю строку целиком).

Архитектурные рекомендации на будущее

Создание уникальных флагов обеспечения в карточке номенклатуры под каждый тип документа (например, отдельный флаг под заказ покупателя, отдельный под заказ на производство, под заказ на перемещение) — это экстенсивный путь развития системы. При добавлении новых видов заказов вам придется создавать новые реквизиты в справочниках и переписывать код во многих модулях.

В типовых решениях 1С:ERP эта задача решена более гибко с использованием механизмов обособления и назначений:

Если ваша самописная ERP находится в стадии активного развития, рекомендуем рассмотреть внедрение сквозного аналитического разреза «Назначение» в регистры резервов ТМЦ.

← На главную