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

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

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

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

Почему динамические колонки заблокированы для редактирования?

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

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

Давайте рассмотрим два основных способа решения этой задачи: через прямое добавление колонок на форму и через предварительную подготовку Таблицы Значений (ТЗ).

---

Способ №1. Создание структуры через Таблицу Значений (Рекомендуемый)

Проектирование структуры таблицы «от данных к форме» — самый надежный и простой в реализации способ. Вместо того чтобы вручную настраивать свойства каждой колонки элемента формы, мы сначала полностью формируем структуру в объекте ТаблицаЗначений, типизируем её, привязываем к табличному полю и генерируем элементы управления одной командой.

Рассмотрим по шагам, как реализовать этот алгоритм программно:

Шаг 1. Создаем объект Таблицы Значений и описываем типы колонок. При добавлении колонок в ТЗ обязательно нужно использовать ОписаниеТипов. Это гарантирует, что платформа автоматически подберет правильный элемент управления для формы.

Шаг 2. Привязываем ТЗ к табличному полю. Связываем свойство Значение нашего элемента формы с созданной ТЗ.

Шаг 3. Генерируем колонки формы. Вызываем метод СоздатьКолонки(). Платформа самостоятельно создаст визуальные колонки, свяжет их с реквизитами ТЗ и назначит соответствующие поля ввода.

Посмотрим на практический пример реализации этого подхода в коде:


// 1. Создаем структуру Таблицы Значений
ТЗ = Новый ТаблицаЗначений;

// Базовая колонка номенклатуры
ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

// Динамически добавляем колонки по периодам
д = ДатаС;
Пока д <= ДатаПо Цикл
    
    // Форматируем год без разделителей групп (например, "2026", а не "2 026")
    стрГод = Формат(Год(д), "ЧГ=");
    стрМесяц = Месяц(д);
    Постфикс = "_" + стрГод + "_" + стрМесяц;
    
    // Добавляем типизированные колонки в ТЗ
    ТЗ.Колонки.Добавить("План" + Постфикс, Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
    ТЗ.Колонки.Добавить("Факт" + Постфикс, Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
    ТЗ.Колонки.Добавить("План2" + Постфикс, Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
    
    д = ДобавитьМесяц(д, 1);
КонецЦикла;

// 2. Связываем ТЗ с элементом формы
ЭлементыФормы.СтрокиПлана.Значение = ТЗ;

// 3. Автоматически создаем элементы управления на форме
ЭлементыФормы.СтрокиПлана.СоздатьКолонки();

Этот лаконичный код полностью решает проблему редактирования ячеек. Платформа сама определила, что для колонок планов и фактов нужны поля ввода числового формата, и связала их с данными ТЗ.

---

Способ №2. Ручное создание колонок на форме с привязкой к данным

Если по каким-то причинам вам необходимо добавлять колонки вручную непосредственно в коллекцию ЭлементыФормы.ТабличноеПоле.Колонки, то крайне важно соблюдать правильную последовательность установки свойств. Разберем этот алгоритм.

Проанализируем пример ручной настройки одной колонки:


// Добавляем колонку в элемент формы
Кол = ЭлементыФормы.СтрокиПлана.Колонки.Добавить("Номенклатура");

// Устанавливаем режим редактирования непосредственно в ячейке
Кол.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;

// ВАЖНО: Сначала устанавливаем элемент управления (Поле ввода)
Кол.УстановитьЭлементУправления(Тип("ПолеВвода"));

// Теперь настраиваем параметры самого элемента управления
Кол.ЭлементУправления.КнопкаВыбора = Истина;
Кол.ЭлементУправления.КнопкаОчистки = Истина;

// И только в самом конце привязываем колонку к полю источника данных ТЗ
Кол.Данные = "Номенклатура";

Запомните: Нарушение этой последовательности (например, установка свойства Кол.Данные = "Номенклатура" до вызова метода УстановитьЭлементУправления) приведет к тому, что ячейка заблокируется для изменения на форме.

---

Настройка сложного положения колонок (Многострочный режим)

После вызова метода СоздатьКолонки() все созданные поля будут выстроены в один ряд. В нашей задаче для каждого месяца создается сразу по три колонки: «План», «Факт» и «План2». Чтобы таблица не растягивалась бесконечно по горизонтали, логично расположить эти показатели друг под другом в рамках одной колонки-периода.

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

Давайте посмотрим, как программно настроить отображение колонок после их создания:


д = ДатаС;
Пока д <= ДатаПо Цикл
    стрГод = Формат(Год(д), "ЧГ=");
    стрМесяц = Месяц(д);
    Постфикс = "_" + стрГод + "_" + стрМесяц;
    
    // Получаем ссылки на созданные колонки формы
    КолПлан = ЭлементыФормы.СтрокиПлана.Колонки["План" + Постфикс];
    КолФакт = ЭлементыФормы.СтрокиПлана.Колонки["Факт" + Постфикс];
    КолПлан2 = ЭлементыФормы.СтрокиПлана.Колонки["План2" + Постфикс];
    
    // Настраиваем положение колонок друг под другом
    КолПлан.Положение = ПоложениеКолонки.НоваяКолонка;
    
    КолФакт.Положение = ПоложениеКолонки.НаСледующейСтроке;
    КолФакт.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
    
    КолПлан2.Положение = ПоложениеКолонки.НаСледующейСтроке;
    КолПлан2.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
    
    // Зададим понятные заголовки колонок для пользователя
    КолПлан.ТекстШапки  = "План (" + Формат(д, "ДФ='MMMM yy'") + ")";
    КолФакт.ТекстШапки  = "Факт";
    КолПлан2.ТекстШапки = "План 2";
    
    д = ДобавитьМесяц(д, 1);
КонецЦикла;

Использование свойства РежимРедактированияКолонки.Непосредственно позволяет пользователю начать редактирование ячеек сразу в один клик мыши без необходимости совершать двойной щелчок.

---

Полезный лайфхак: Создание красивой «общей шапки» для периода

Когда мы выводим несколько показателей на один месяц, на форме получается визуальная каша из-за повторяющихся названий месяцев в заголовках. Намного удобнее сделать одну общую шапку с названием месяца (например, «Январь 2026»), а под ней расположить три подколонки: «План», «Факт», «План2».

В обычных формах 1С нет штатных «групп колонок», как в управляемом интерфейсе, но мы можем использовать изящный обходной прием:

  1. Создаем фиктивную (служебную) колонку, которая будет играть роль «общей шапки». Назовем её, к примеру, "Период" + Постфикс. Задаем ей текст шапки с названием месяца и положение ПоложениеКолонки.НоваяКолонка.
  2. Для рабочих колонок «План», «Факт» и «План2» устанавливаем положение ПоложениеКолонки.НаСледующейСтроке под нашей служебной колонкой.
  3. В строках данных под служебной колонкой будут отображаться пустые некрасивые ячейки. Чтобы их скрыть, используем событие табличного поля ПриВыводеСтроки. Мы просто отключаем видимость ячеек этой служебной колонки для каждой выводимой строки:
    
    Процедура СтрокиПланаПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
        // Скрываем ячейки служебных колонок-шапок, чтобы они не отображались в теле таблицы
        Для Каждого Колонка Из Элемент.Колонки Цикл
            Если Лев(Колонка.Имя, 6) = "Шапка_" Тогда
                ОформлениеСтроки.Ячейки[Колонка.Имя].Видимость = Ложь;
            КонецЕсли;
        КонецЦикла;
    КонецПроцедуры
    

В результате в шапке таблицы мы получим красивое визуальное объединение колонок по месяцам, а в области данных будут выводиться и редактироваться только наши показатели.

---

Важные правила работы со строками и числами в именах колонок

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

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

Правильное решение: всегда используйте функцию Формат() с отключением группировки чисел:

ИмяКолонки = "План_" + Формат(Год(РабочаяДата), "ЧГ=");

Символ "ЧГ=" в параметрах форматирования указывает платформе 1С, что группировку разрядов числа выполнять не нужно, и мы гарантированно получим монолитную строку вида "2026".

← На главную