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