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

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

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

Причина поведения платформы: как работает метод СоздатьКолонки()

Проанализируем исходный фрагмент кода, приводящий к ошибке:


Процедура ДобавитьКолонкаНажатие(Элемент)
    ТЗ.Колонки.Добавить();
    ЭлементыФормы.ТабПоле.Значение = ТЗ;
    ЭлементыФормы.ТабПоле.СоздатьКолонки();
КонецПроцедуры

Выясним причину сброса положения колонок. Метод СоздатьКолонки() у объекта ТабличноеПоле не выполняет «умное обновление» или добавление только недостающих элементов. Этот метод полностью очищает существующую коллекцию колонок табличного поля и генерирует её заново на основании текущей структуры источника данных (ТаблицаЗначений).

В результате вызова метода происходят следующие изменения:

  1. Коллекция ЭлементыФормы.ТабПоле.Колонки полностью уничтожается.
  2. Колонки создаются заново в том порядке, в котором они расположены в объекте ТаблицаЗначений.
  3. Все визуальные настройки (программный или интерактивный сдвиг колонок, ширина, заголовки, видимость, назначенные элементы управления ПолеВвода, Флажок) безвозвратно сбрасываются к значениям по умолчанию.
  4. Повторное присвоение ЭлементыФормы.ТабПоле.Значение = ТЗ также является избыточным, так как табличное поле уже связано по ссылке с объектом в памяти.

Рассмотрим несколько правильных способов решения этой задачи в зависимости от требований к коду.

Способ 1. Точечное добавление колонки в источник и табличное поле

Если структура таблицы уже сформирована и пользователю требуется добавлять колонки «на лету», не следует вызывать СоздатьКолонки(). Правильный подход — параллельно добавить колонку в источник данных и в визуальную таблицу формы.

Посмотрим на пример реализации:


// 1. Добавляем колонку в источник данных
ИмяНовойКолонки = "Колонка_" + Формат(ТЗ.Колонки.Количество() + 1, "ЧГ=0");
ТипКолонки = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
КолонкаТЗ = ТЗ.Колонки.Добавить(ИмяНовойКолонки, ТипКолонки, "Новая колонка");

// 2. Добавляем колонку в табличное поле без сброса структуры
КолонкаТП = ЭлементыФормы.ТабПоле.Колонки.Добавить(ИмяНовойКолонки, "Новая колонка");
КолонкаТП.Данные = ИмяНовойКолонки; // связываем колонку с полем источника
КолонкаТП.УстановитьЭлементУправления(Тип("ПолеВвода"));

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

Способ 2. Синхронный сдвиг колонок в источнике данных (ТаблицаЗначений)

Если требуется перемещать колонки, логику упорядочивания необходимо применять непосредственно к источнику данных (ТаблицаЗначений), а не только к представлению на форме. Коллекция колонок таблицы значений поддерживает метод Сдвинуть().

Разберем по шагам, как определить текущую колонку в табличном поле и сдвинуть её в самой таблице значений:


ТекущаяКолонкаТП = ЭлементыФормы.ТабПоле.ТекущаяКолонка;

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

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

Способ 3. Однократное формирование структуры

Если состав колонок заранее известен или формируется по сложному алгоритму, рекомендуется сначала полностью сконфигурировать коллекцию колонок в ТаблицаЗначений, применить все сортировки и сдвиги, и только в самом конце однократно вызвать метод СоздатьКолонки().


// Формируем структуру источника полностью
ТЗ.Колонки.Очистить();
ТЗ.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(9)), "Код");
ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), "Номенклатура");
ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 3)), "Количество");

// Перемещаем нужную колонку в источнике
ТЗ.Колонки.Сдвинуть(ТЗ.Колонки.Количество, -1);

// Инициализируем визуальное отображение один раз
ЭлементыФормы.ТабПоле.Значение = ТЗ;
ЭлементыФормы.ТабПоле.СоздатьКолонки();

Особенности для Управляемых форм

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

  1. Новые колонки добавляются в реквизит формы на сервере с помощью метода ИзменитьРеквизиты().
  2. Визуальный элемент колонки создается вызовом метода Элементы.Добавить("ИмяЭлемента", Тип("ПолеФормы"), Элементы.ИмяТаблицы).
  3. Для перемещения элементов формы используется метод Элементы.Переместить(Элемент, Родитель, ЭлементПередКоторымВставить).
← На главную