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

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

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

Возможно ли дублирование ячеек без кода при интерактивном вводе?

Выясним причину, почему стандартными средствами табличного документа без доработки кода это сделать не получится. В платформе 1С:Предприятие табличный документ не обладает встроенным формульным аппаратом, аналогичным Excel (где можно просто написать формулу вида =A1). Ячейки табличного документа в режиме просмотра и редактирования независимы друг от друга.

Кроме того, в типовых конфигурациях (включая 1С:УНФ) все печатные формы по умолчанию формируются с установленным свойством ТолькоПросмотр = Истина. Чтобы пользователь вообще получил возможность редактировать ячейки на форме, требуется программно снять этот флаг, а также убедиться, что у самих редактируемых ячеек свойство Защита установлено в значение Ложь.

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

Реализация через событие ПриИзмененииСодержимогоОбласти

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

Посмотрим на пример кода, предложенный на форуме:


&НаКлиенте
Процедура РезультатПриИзмененииСодержимогоОбласти(Элемент, Область, ДополнительныеПараметры)
	ИмяОбластиБезНомераКолонки = Лев(Область.Имя, 3);
	СледующийНомерКолонки = Число(Прав(Область.Имя, 1)) + 1;
	ОбластьЗаполнения = ИмяОбластиБезНомераКолонки + СледующийНомерКолонки;
	Результат.Область(ОбластьЗаполнения).Текст = Область.Текст;
КонецПроцедуры

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

  1. Хрупкость строкового разбора: Использование функций Лев и Прав для парсинга адреса ячейки приведет к ошибкам при работе с номерами строк или колонок, состоящими из двух и более знаков (например, строки после 9-й). Кроме того, переход от A1 к A2 — это смещение вниз по строкам, а не вправо по колонкам.
  2. Опасность рекурсивного вызова: Изменение ячейки Результат.Область(...).Текст = ... программно внутри обработчика снова вызывает событие ПриИзмененииСодержимогоОбласти. Если не поставить четкое условие проверки исходной ячейки, платформа уйдет в бесконечный цикл.
  3. Текст против значения: Если ячейка содержит типизированные данные (включено свойство СодержитЗначение), копирования только свойства Текст недостаточно — нужно также переносить свойство Значение.

Корректный программный подход с числовыми координатами

Разберем по шагам, как надежно перенести значение ячейки на строку ниже (из A1 в A2), используя строгие числовые координаты объекта ОбластьЯчеекТабличногоДокумента:


&НаКлиенте
Процедура РезультатПриИзмененииСодержимогоОбласти(Элемент, Область, ДополнительныеПараметры)
	
	// Проверяем, что изменилась именно ячейка A1 (строка 1, колонка 1)
	Если Область.Верх = 1 И Область.Лево = 1 Тогда
		
		// Получаем ячейку A2 (строка 2, колонка 1)
		ЯчейкаПриемник = Элемент.Область(Область.Верх + 1, Область.Лево);
		
		// Копируем отображаемый текст
		ЯчейкаПриемник.Текст = Область.Текст;
		
		// Если ячейка типизирована, переносим и само значение
		Если Область.СодержитЗначение Тогда
			ЯчейкаПриемник.СодержитЗначение = Истина;
			ЯчейкаПриемник.ТипЗначения = Область.ТипЗначения;
			ЯчейкаПриемник.Значение = Область.Значение;
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

В этом примере свойство Область.Верх возвращает номер верхней строки области, а Область.Лево — номер левой колонки. Обращение Элемент.Область(Область.Верх + 1, Область.Лево) обращается строго к ячейке под редактируемой, а условие Если Область.Верх = 1... полностью предотвращает бесконечную рекурсию при программной установке данных.

Альтернативные варианты реализации

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

  1. Дублирование одинаковых параметров в макете: Если значение не вводится вручную на готовом листе, а подставляется в процессе формирования документа, код связывания вообще не нужен. В макете печатной формы в обеих ячейках можно установить тип заполнения Параметр и задать им одинаковое имя (например, Комментарий). При вызове метода ЗаполнитьЗначенияСвойств() или передаче структуры параметров в область табличного документа платформа автоматически продублирует значение во все одноименные параметры.
  2. Диалоговое окно ввода перед печатью: Если пользователю обязательно нужно вводить значение вручную, надежнее вынести этот ввод во вспомогательную форму параметров печати (в обычный реквизит формы). После нажатия кнопки «Сформировать» алгоритм сам запишет введенный текст во все необходимые ячейки печатной формы без необходимости перехвата низкоуровневых событий таблицы.
  3. Экспорт во внешние таблицы: Если предполагаются сложные пользовательские пересчеты и формульные зависимости, оптимальным решением без программирования конфигурации будет выгрузка сформированного документа в формат электронных таблиц (XLSX), где формульные связи между ячейками настраиваются штатными средствами офисного редактора.
← На главную