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