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