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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Реализация логики «Количество изменено вручную»

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

Шаг 1. Добавление технического реквизита

Разберем первый способ — использование специального флага. Для этого в табличную часть вашего документа необходимо добавить новый реквизит (колонку) с типом Булево. Назовем его КоличествоИзмененоВручную. На форму этот реквизит выводить не обязательно, он будет использоваться только в коде.

Шаг 2. Обработка события изменения

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

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


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

Шаг 3. Использование флага в алгоритмах

Теперь выясним, как использовать это условие в других процедурах. Например, если у нас есть процедура ЗаполнитьКоличествоАвтоматически(), мы должны добавить проверку:


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

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

Реализация отслеживания удаления строки

Вопрос о том, как написать условие «Если строка удалена», требует понимания жизненного цикла объектов в 1С. Когда строка уже удалена, обратиться к ней в коде невозможно, так как ее больше нет в коллекции табличной части. Поэтому работа с удалением строится на перехвате самого процесса удаления.

Метод 1. Обработчик «ПередУдалением»

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


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

Метод 2. Обработчик «ПослеУдаления»

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


&НаКлиенте
Процедура ТоварыПослеУдаления(Элемент)
    
    // Пересчитываем итоги по всему документу, так как состав строк изменился
    РассчитатьИтогиДокумента();
    
КонецПроцедуры

Альтернативный подход: сравнение с исходными данными

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

Разберем этот способ по шагам:

  1. При создании формы на сервере мы копируем текущую табличную часть во временную таблицу значений или массив структур и сохраняем в РеквизитФормыВЗначение.
  2. В нужный момент (например, перед записью документа) мы сравниваем текущие данные табличной части с сохраненной копией.
  3. Если в текущей строке значение Количество не совпадает с тем, что было в копии, значит, «Количество изменено вручную».
  4. Если в копии была строка с определенным идентификатором, а в новой таблице ее нет — значит, «Строка удалена».

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

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

← На главную