Как разрешить редактирование отдельных строк в Заказе клиента после оформления реализации?

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

В типовых конфигурациях «1С:Управление торговлей» (начиная с версии 11), «1С:ERP» и «1С:Комплексная автоматизация» заложен строгий контроль за изменением документов, по которым уже начата отгрузка. Когда менеджер оформляет документ Реализация товаров и услуг на основании Заказа клиента, исходный заказ блокируется системой и переводится в режим «Только чтение» (свойство формы ТолькоПросмотр = Истина). Это необходимо для предотвращения рассинхронизации данных в регистрах накопления и обеспечения корректности взаиморасчетов.

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

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

Выясняем причину: почему не работают стандартные механизмы?

Попытки решить эту задачу «в лоб» часто приводят к ошибкам. Давайте проанализируем основные подводные камни, с которыми сталкиваются разработчики:

  1. Общая блокировка формы. Если у формы установлено свойство ЭтаФорма.ТолькоПросмотр = Истина, то никакие настройки отдельных элементов, колонок или строк табличной части работать не будут. Форма блокируется платформой целиком на самом верхнем уровне.
  2. Ошибки настройки Условного оформления в конфигураторе. Часто разработчики пытаются настроить условное оформление интерактивно в свойствах формы. Однако в типовых конфигурациях при открытии формы срабатывает процедура УстановитьУсловноеОформление(), которая программно очищает коллекцию условного оформления формы и заполняет ее заново. В итоге все настройки, сделанные вручную в конфигураторе, просто стираются.
  3. Попытка заблокировать всю таблицу вместо колонок. При создании правила условного оформления разработчики ошибочно указывают в качестве оформляемого поля саму таблицу Товары. Платформа 1С в управляемых формах требует явного указания конкретных колонок табличной части в списке оформляемых полей, иначе блокировка строк по условию не применится.
  4. Попытка заблокировать реквизиты шапки через Условное оформление. Механизм условного оформления управляемой формы предназначен исключительно для работы со списочными и табличными данными (динамические списки, таблицы значений, табличные части). Заблокировать одиночные поля ввода в шапке документа (например, контрагента, договор, статус) через условное оформление технически невозможно.

Давайте пошагово реализуем правильный, надежный алгоритм, который решит поставленную задачу.

Шаг 1. Отключение глобального свойства ТолькоПросмотр

Для того чтобы мы могли управлять доступностью отдельных элементов формы, нам необходимо полностью отключить стандартный перевод формы в режим «Только чтение». Нам нужно найти место в коде формы (или создать расширение), где система устанавливает свойство ТолькоПросмотр после проверки связанных документов, и принудительно переключить его в Ложь.

В модуле формы документа ЗаказКлиента в обработчике ПриОткрытии или в конце процедуры ПриЧтенииНаСервере пропишем следующий код:


&НаСервере
Процедура ПослеЧтенияНаСервере(ТекущийОбъект)
    // Отключаем глобальный режим "Только чтение" для формы
    ЭтаФорма.ТолькоПросмотр = Ложь;
КонецПроцедуры

Важно: Помните, что простое отключение этого свойства открывает для редактирования весь документ. Если менеджер изменит дату, клиента или склад в уже частично отгруженном заказе, это приведет к критическим ошибкам проведения. Поэтому переходим к следующему шагу — программной блокировке шапки.

Шаг 2. Программная блокировка реквизитов шапки

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

Добавим в модуль формы процедуру, которая будет вызываться при открытии документа:


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

Этот изящный прием позволяет одной процедурой закрыть от изменений всю форму, оставив доступной только табличную часть Товары.

Шаг 3. Программная настройка Условного оформления для строк табличной части

Теперь займемся табличной частью. Нам необходимо заблокировать только те строки, у которых в колонке ВариантОбеспечения установлено значение Отгрузить (так как по ним уже создана реализация). Строки с другими вариантами обеспечения (например, К обеспечению, Резервировать к дате) должны остаться доступными для редактирования.

Создадим процедуру программного добавления правила условного оформления. Этот код должен выполняться на сервере в обработчике ПриСозданииНаСервере после того, как отработали все типовые процедуры инициализации оформления:


&НаСервере
Процедура НастроитьБлокировкуОтгруженныхСтрок()
    
    // 1. Создаем новый элемент условного оформления
    ЭлементОформления = УсловноеОформление.Элементы.Добавить();
    
    // 2. Указываем оформляемые поля (все колонки табличной части Товары)
    Для Каждого Колонка Из Элементы.Товары.ПодчиненныеЭлементы Цикл
        ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
        ПолеОформления.Поле = Новый ПолеКомпоновкиДанных(Колонка.Имя);
    КонецЦикла;
    
    // 3. Задаем условие: блокировать строки, где ВариантОбеспечения = Отгрузить
    ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.ВариантОбеспечения");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = Перечисления.ВариантыОбеспечения.Отгрузить;
    
    // 4. Устанавливаем свойство оформления "ТолькоПросмотр" в значение Истина
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
    
КонецПроцедуры

Благодаря этому коду платформа автоматически наложит свойство ТолькоПросмотр = Истина на каждую ячейку в тех строках табличной части, которые соответствуют нашему условию отбора. Визуально эти строки станут недоступными для изменения, в то время как неотгруженные строки менеджер сможет редактировать в обычном режиме.

Шаг 4. Дополнительная защита на клиенте через событие ПередНачаломИзменения

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

Разберем пример создания такого обработчика:


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

Использование связки из программного Условного оформления (для удобства пользователя и визуального сокрытия доступности) и обработчика ПередНачаломИзменения (для гарантированной защиты базы данных от ошибок) является лучшим стандартом разработки на платформе «1С:Предприятие 8.3».

Анализируем методологические риски решения

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

Альтернативный типовой путь без программирования: Специалисты фирмы «1С» рекомендуют решать подобные задачи без изменения кода конфигурации. Для этого в программе предусмотрен бизнес-процесс корректировки заказов:

  1. Менеджер открывает исходный заказ и использует стандартную команду «Заполнить» -> «Отменить непоставленные строки».
  2. Система автоматически аннулирует недопоставленные позиции и фиксирует причину отмены. Заказ закрывается в текущем отгруженном состоянии.
  3. Для недопоставленных позиций создается новый, абсолютно чистый документ Заказ клиента. Менеджер работает с ним без каких-либо блокировок и ограничений. Это сохраняет чистую историю взаиморасчетов и исключает любые конфликты в регистрах обеспечения.
← На главную