Почему не срабатывает событие «ПередОкончаниемРедактирования» и как правильно реализовать пересчет в таблице 1С?

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

В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда процедура-обработчик события таблицы формы просто не вызывается. Особенно это актуально при работе с динамически создаваемыми колонками и таблицами значений. Рассмотрим подробнее, почему так происходит, и разберем, как сделать ваш код надежным, производительным и удобным для поддержки.

Выясним причину: почему обработчик «молчит»?

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

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

Решение проблемы №1: Программное назначение обработчика

Если ваша таблица или её элементы создаются в коде, обязательно проверьте наличие привязки. Разберем на примере, как это должно выглядеть в модуле формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Допустим, элемент таблицы называется "Тп"
    НовыйЭлемент = Элементы.Добавить("Тп", Тип("ТаблицаФормы"));
    // Устанавливаем связь события и процедуры
    НовыйЭлемент.УстановитьДействие("ПередОкончаниемРедактирования", "ТпПередОкончаниемРедактирования");
КонецПроцедуры

Без вызова метода УстановитьДействие платформа проигнорирует наличие процедуры ТпПередОкончаниемРедактирования в модуле, даже если её имя совпадает со стандартным шаблоном.

Решение проблемы №2: Выбор правильного события для пересчета

Часто разработчики выбирают ПередОкончаниемРедактирования для пересчета итогов, но это не лучший вариант с точки зрения UX (пользовательского опыта). Пользователь хочет видеть изменения мгновенно. Рассмотрим альтернативу — использование события ПриИзменении для конкретных колонок.

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

Анализируем качество кода: как избежать ошибок в будущем

Посмотрим на исходный пример кода и проанализируем критические ошибки, которые могут привести к падению программы или неверным расчетам:

  1. Обращение через индексы колонок. Код типа Элемент.Тп[номстр][счк] крайне опасен. Если пользователь переставит колонки местами мышкой, ваши индексы (например, 7-я колонка) будут указывать на совершенно другие данные (например, на дату или комментарий вместо суммы). Это приведет к ошибке приведения типов.
  2. Проблема сортировки. Когда пользователь нажимает на заголовок колонки для сортировки, визуальный индекс строки в элементе формы перестает совпадать с индексом строки в данных (в объекте ТаблицаЗначений). Использование Индекс(ТС) может вернуть не ту строку, которую редактирует пользователь.
  3. Нечитаемые имена переменных. Имена сумт, колк, счк усложняют понимание кода. Профессиональный подход требует осмысленных имен: ТекущаяСумма, КоличествоКолонок, ИндексКолонки.

Правильный алгоритм реализации пересчета

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

Шаг 1. Получение данных через идентификатор. Чтобы гарантированно работать с нужной строкой, используйте метод НайтиПоИдентификатору(). Это защитит расчеты от влияния сортировки.

Шаг 2. Работа с данными напрямую. Обращайтесь к реквизиту формы напрямую (например, Объект.Тп), а не через Элемент.Значение. Это быстрее и безопаснее.

Шаг 3. Использование коллекций. Вместо цикла по цифрам, используйте обход коллекции колонок.

Рассмотрим пример правильной реализации процедуры пересчета:


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

Подведем итоги

Чтобы ваша таблица работала корректно, а данные считались правильно, придерживайтесь следующих правил:

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

← На главную