Как программно установить тип данных и формат поля ввода для каждой строки табличной части в 1С

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

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

1. Настройка составного типа данных в конфигураторе

Выясним главную причину, по которой платформа 1С позволяет хранить разнородные данные в одной колонке. Для того чтобы колонка табличной части или таблицы значений могла принимать значения разных типов, ее реквизит в конфигураторе должен иметь составной тип данных или тип Произвольный (в случае таблицы значений на сервере).

Разберем по шагам порядок подготовки реквизита:

  1. Откроем свойства реквизита табличной части или таблицы значений.
  2. В поле Тип установим флажок Составной тип данных.
  3. Отметим галочками все необходимые типы: Число, Строка, Дата, Булево, а также ссылки на нужные справочники и документы (например, СправочникСсылка.Номенклатура, СправочникСсылка.Контрагенты и т.д.).
  4. При необходимости укажем квалификаторы числа и строки (длину, точность, допустимый знак).

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

2. Динамическая установка формата и ограничение типа в обычных формах

Проанализируем работу с обычными формами (обычное приложение). В элементе управления ТабличноеПоле колонка использует один и тот же элемент управления (обычно ПолеВвода) для всех строк. По этой причине настройки элемента необходимо менять динамически в зависимости от того, какая строка выводится или редактируется.

Для решения задачи нам понадобятся два ключевых события табличного поля:

  1. ПриВыводеСтроки (или ПриПолученииДанных) — отвечает за визуальное оформление и формат отображения текста в ячейке.
  2. ПриПередНачаломИзменения (или ПриНачалеРедактирования) — отвечает за ограничение типов и настройку режима ввода при открытии ячейки на редактирование.

Рассмотрим практический пример кода для оформления вывода данных:


Процедура ТабличноеПоле1ПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
	
	// Получаем оформление ячейки "Значение" для текущей строки
	ЯчейкаЗначение = ОформлениеСтроки.Ячейки.Значение;
	
	// Проверяем тип данных текущей строки и задаем индивидуальный формат
	ТекущийТип = ТипЗг(ДанныеСтроки.Значение);
	
	Если ТекущийТип = Тип("Дата") Тогда
		ЯчейкаЗначение.Формат = "ДФ=dd.MM.yyyy";
	ИначеЕсли ТекущийТип = Тип("Число") Тогда
		ЯчейкаЗначение.Формат = "ЧДЦ=2; ЧГ=3,0";
	Иначе
		// Очищаем формат для остальных типов
		ЯчейкаЗначение.Формат = "";
	КонецЕсли;

КонецПроцедуры

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


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

КонецПроцедуры

3. Реализация в управляемых формах (Управляемое приложение)

Посмотрим, как аналогичная задача решается на управляемых формах. В управляемом приложении работа с элементами происходит на клиенте через свойства элемента формы ТаблицаФормы и текущую строку данных.

Для настройки типа ячейки перед редактированием используется событие таблицы ПриНачалеРедактирования. Рассмотрим пример:


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

КонецПроцедуры

Если в процессе работы пользователь меняет тип значения в соседней колонке (например, в колонке ТипЗначенияСтроки), необходимо сразу обнулить или привести значение к новому типу. Разберем, как это сделать в обработчике события ПриИзменении:


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

КонецПроцедуры

4. Обработка кнопки очистки и сброса типа

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

Чтобы избежать нежелательного сброса настроенного типа, применяют следующие приемы:

  1. Устанавливают свойство элемента формы ВыбиратьТип = Ложь.
  2. В обработчике события Очистка элемента поля ввода принудительно подставляют пустую ссылку или дефолтное значение требуемого типа, отменяя стандартную очистку через параметр Отказ = Истина.

Посмотрим на пример обработки очистки:


&НаКлиенте
Процедура ТаблицаЗначенийЗначениеОчистка(Элемент, Отказ)
	
	ТекущиеДанные = Элементы.ТаблицаЗначений.ТекущиеДанные;
	Если ТекущиеДанные <> Неопределено Тогда
		Отказ = Истина; // Отменяем стандартное сбрасывание в Неопределено
		// Приводим к пустой ссылке или базовому значению текущего типа
		 ОписаниеТипаЯчейки = Элемент.ОграничениеТипа;
		 ТекущиеДанные.Значение = ОписаниеТипаЯчейки.ПривестиЗначение();
	КонецЕсли;

КонецПроцедуры

5. Рекомендации и подводные камни

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

Избегайте тяжёлых операций при выводе строки: В обычных формах событие ПриВыводеСтроки вызывается при каждом перерисовывании ячейки на экране. Никогда не выполняйте запросы к базе данных или обращение к серверу внутри этого события. Все типы и форматы должны определяться на основе данных, уже загруженных в клиентскую память.

Правильное приведение типов: Для безопасного преобразования значений используйте метод ОписаниеТипов.ПривестиЗначение(). Он автоматически преобразует переданное значение к допустимому типу из описания или возвращает значение по умолчанию.

Очистка списка выбора: Если для отдельных строк используется РежимВыбораИзСписка = Истина, не забывайте очищать СписокВыбора и выключать данный режим для тех строк, где требуется обычный ввод текста или выбор из справочника.

← На главную