В разработке на платформе 1С часто возникает задача модифицировать данные в новой строке табличной части сразу после ее создания — для этого подойдёт расширение для настройки обработчиков заполнения объектов. Если строка добавляется стандартной кнопкой "Добавить", обычно используется событие ПриНачалеРедактирования. Однако при копировании существующей строки (через F9 или контекстное меню) это событие может не сработать, особенно в старых версиях платформы или при использовании режимов совместимости. Подобное программное изменение форм требует понимания тонкостей работы событий и жизненного цикла элементов.
Проанализируем ситуацию: пользователь копирует строку, и нам нужно, например, очистить определенные колонки или установить в них значения по умолчанию, которые отличаются от исходной строки. Стандартный, казалось бы, обработчик не вызывается. Рассмотрим несколько надежных способов решения этой задачи, которые помогут эффективно реализовать добавление реквизитов и элементов формы на управляемые формы и их последующую обработку.
Прежде чем переходить к сложным методам, давайте поймем, почему стандартные подходы могут не работать. В управляемых формах за добавление строк отвечают в основном два события.
ПриНачалеРедактирования(НоваяСтрока, Копирование)
Это событие идеально подходит для нашей цели. Оно срабатывает, когда пользователь начинает редактировать ячейку в новой строке. Его параметры прямо указывают, была ли это новая строка (НоваяСтрока = Истина) и создана ли она копированием (Копирование = Истина). Проблема, как описано в исходной теме, заключается в том, что в некоторых сценариях, версиях платформы или режимах совместимости оно может не вызываться при копировании. Если вы столкнулись с таким поведением, полагаться на этот обработчик нельзя.
ПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
Это событие срабатывает до того, как платформа фактически создаст и добавит новую строку в коллекцию данных табличной части. Его главное преимущество — параметр Копирование, который безошибочно сообщает нам о намерении пользователя скопировать строку. Однако есть и ключевой недостаток: на момент выполнения этого обработчика самой новой строки как объекта данных еще не существует. Мы не можем получить к ней доступ и изменить ее поля. Но именно это событие станет отправной точкой для надежных обходных путей.
Этот метод заключается в том, чтобы перехватить намерение пользователя скопировать строку, отменить стандартный механизм платформы и выполнить все действия программно. Это дает нам полный контроль над процессом, особенно если в вашей задаче также задействовано программное создание колонок в табличной части с необходимостью их немедленного заполнения.
Разберем по шагам:
ПередНачаломДобавления для нашей табличной части.Копирование.Копирование = Истина, мы устанавливаем Отказ = Истина. Это говорит платформе: "Не выполняй стандартное копирование, я все сделаю сам".Элементы.ИмяТабличнойЧасти.ТекущиеДанные.Объект.ИмяТабличнойЧасти.Добавить().ЗаполнитьЗначенияСвойств().Посмотрим на пример кода:
Предположим, у нас есть табличная часть Товары на форме, и при копировании строки мы хотим очистить поля "Количество" и "Сумма".
&НаКлиенте
Процедура ТоварыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, ПараметрКопирования)
// Проверяем, что это именно операция копирования
Если Копирование Тогда
// 1. Отменяем стандартное действие платформы
Отказ = Истина;
// 2. Получаем исходную строку для копирования
ИсходнаяСтрока = Элементы.Товары.ТекущиеДанные;
Если ИсходнаяСтрока = Неопределено Тогда
// На всякий случай, если текущая строка по какой-то причине не определена
Возврат;
КонецЕсли;
// 3. Добавляем новую строку программно
НоваяСтрока = Объект.Товары.Добавить();
// 4. Копируем данные из исходной строки в новую
ЗаполнитьЗначенияСвойств(НоваяСтрока, ИсходнаяСтрока);
// 5. Вносим необходимые изменения в новую строку
НоваяСтрока.Количество = 0;
НоваяСтрока.Сумма = 0;
// Можно также активизировать новую строку для удобства пользователя
Элементы.Товары.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецЕсли;
КонецПроцедуры
Преимущества этого метода:
ПриНачалеРедактирования и будет работать в любых версиях и режимах.Иногда не хочется полностью отменять стандартный механизм платформы. В этом случае можно использовать асинхронный подход. Идея в том, чтобы позволить платформе самой скопировать строку, а затем, с минимальной задержкой, найти эту новую строку и изменить ее. Подобный прием часто выручает, когда реализуется программный вывод произвольной таблицы значений на управляемую форму.
Разберем по шагам:
ПередНачаломДобавления мы снова проверяем параметр Копирование.Отказ мы не трогаем. Вместо этого мы подключаем однократный обработчик ожидания с нулевой или минимальной задержкой. Это даст платформе время завершить свою операцию копирования.Посмотрим на пример кода:
&НаКлиенте
Процедура ТоварыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, ПараметрКопирования)
Если Копирование Тогда
ПодключитьОбработчикОжидания("ОбработатьСкопированнуюСтроку", 0, Истина);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьСкопированнуюСтроку()
КоличествоСтрок = Объект.Товары.Количество();
Если КоличествоСтрок = 0 Тогда
Возврат;
КонецЕсли;
// Получаем последнюю строку
СкопированнаяСтрока = Объект.Товары[КоличествоСтрок - 1];
// Вносим изменения
СкопированнаяСтрока.Количество = 0;
СкопированнаяСтрока.Сумма = 0;
КонецПроцедуры
Напоследок выясним, почему вообще может возникать проблема с несрабатыванием ПриНачалеРедактирования. Чтобы детально изучить поведение элементов "вживую", можно использовать редактор форм в режиме предприятия (поможет инструментарий разработчика для отладки управляемых форм), который позволяет менять свойства объектов на лету. Основные причины проблем:
Таким образом, если вы столкнулись с проблемой несрабатывания события ПриНачалеРедактирования при копировании, не стоит тратить время на поиск причин в конкретной версии платформы. Лучше сразу воспользуйтесь одним из предложенных надежных методов, которые дадут вам предсказуемый и стабильный результат.