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