Разработка и Конфигурация · 7 мин
Как поменять местами строки в таблице значений 1С
Как поменять местами строки в таблице значений 1С: метод Сдвинуть, обмен через вставку, сортировка. Примеры кода, типичные ошибки и проверка результата.
Перестановка строк в таблице значений — частая задача при разработке на платформе 1С: реализация кнопок «вверх/вниз» в табличной части обработки, восстановление порядка после сортировки, ручная настройка приоритетов строк. В отличие от табличной части документа, у объекта «ТаблицаЗначений» нет встроенных команд интерфейса для перемещения строк, поэтому обмен выполняется программно на встроенном языке.
Основных подхода три: метод Сдвинуть(), обмен содержимым через временную строку и пересортировка по служебной колонке с номером. Каждый способ имеет свои ограничения: где-то важно контролировать границы индексов, где-то — сохранять ссылки на строки, используемые в других местах кода. Ниже разобраны все варианты с готовыми фрагментами кода.
Метод Сдвинуть: самый простой способ
Метод Сдвинуть(Строка, Смещение) перемещает указанную строку на заданное число позиций. Положительное смещение двигает строку вниз, отрицательное — вверх. Это штатный способ для кнопок «Вверх» и «Вниз» в формах обработок и отчётов.
Процедура СдвинутьСтрокуВверх(Команда)
ТекущаяСтрока = Элементы.ТаблицаДанных.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
Индекс = ТаблицаДанных.Индекс(ТекущаяСтрока);
Если Индекс > 0 Тогда
ТаблицаДанных.Сдвинуть(Индекс, -1);
КонецЕсли;
КонецПроцедуры
Обратите внимание: метод принимает либо саму строку, либо её индекс. Если сдвинуть строку с индексом 0 на -1, платформа «закольцует» перемещение — строка уйдёт в конец таблицы. Поэтому проверка границ перед вызовом обязательна, иначе пользователь получит неожиданный порядок строк.
ТЗ.Сдвинуть(ИндексСтроки, -1); // вверх
ТЗ.Сдвинуть(ИндексСтроки, 1); // внизОбмен двух произвольных строк через Вставить и Удалить
Метод Сдвинуть удобен для соседних строк, но если нужно поменять местами строки с индексами 2 и 10, вызывать его восемь раз нерационально. В этом случае применяют классический обмен через временную строку: одну строку копируют во временную таблицу или запоминают, удаляют, а затем вставляют на нужную позицию.
Готовой команды «поменять местами» в языке нет, поэтому типовой приём выглядит так: выгружаем обе строки в массив структур или в отдельную таблицу значений, удаляем исходные строки (сначала с большим индексом, чтобы индексы не съехали), затем вставляем их на новые позиции и переносим значения колонок через ЗаполнитьЗначенияСвойств().
Процедура ПоменятьСтрокиМестами(ТЗ, Индекс1, Индекс2)
Если Индекс1 = Индекс2 Тогда
Возврат;
КонецЕсли;
Строка1 = ТЗ[Индекс1];
Строка2 = ТЗ[Индекс2];
// Обмен значениями всех колонок
Для Каждого Колонка Из ТЗ.Колонки Цикл
Буфер = Строка1[Колонка.Имя];
Строка1[Колонка.Имя] = Строка2[Колонка.Имя];
Строка2[Колонка.Имя] = Буфер;
КонецЦикла;
КонецПроцедуры
Перестановка через служебную колонку порядка
Когда порядком строк управляет пользователь и его нужно сохранять между сеансами, надёжнее всего завести числовую колонку, например «Порядок», и менять местами не сами строки, а значения этой колонки, после чего сортировать таблицу методом Сортировать("Порядок").
Процедура ПоднятьСтроку(ТЗ, Индекс)
Если Индекс <= 0 Тогда
Возврат;
КонецЕсли;
ТекущийПорядок = ТЗ[Индекс].Порядок;
ТЗ[Индекс].Порядок = ТЗ[Индекс - 1].Порядок;
ТЗ[Индекс - 1].Порядок = ТекущийПорядок;
ТЗ.Сортировать("Порядок");
КонецПроцедуры
Плюс подхода — порядок легко записать в регистр сведений или хранилище настроек и восстановить при следующем открытии формы. Минус — требуется следить за уникальностью значений колонки: при дубликатах результат сортировки для «одинаковых» строк не гарантирован.
Сравнение способов
Подходит для кнопок вверх/вниз на форме. Ограничение: сдвиг за границу таблицы переносит строку на противоположный край.
Подходит для двух произвольных строк. Ограничение: физическая позиция строк не меняется, меняется только содержимое.
Подходит, когда порядок нужно хранить между сеансами. Ограничение: требуется контроль уникальности значений порядка.
Особенности для динамических списков и табличных частей
Если на форме выведена не таблица значений, а динамический список (например, список справочника), метод Сдвинуть недоступен — динамический список отражает данные базы и порядок в нём определяется сортировкой запроса. Чтобы дать пользователю ручное упорядочивание, добавляют реквизит «Порядок» в объект и меняют его значения с последующей записью элементов.
В табличных частях документов и справочников есть метод Сдвинуть у коллекции строк, и типовые конфигурации часто уже содержат команды перемещения. Если команды нет, её добавляют через расширение формы, не изменяя саму конфигурацию, — это упрощает последующие обновления.
Проверка результата и типичные ошибки
После перестановки убедитесь, что строка действительно оказалась на ожидаемой позиции: сравните индекс до и после, а на форме проверьте, что текущая строка не «потерялась» — иногда после сортировки фокус уходит на другую строку, и её нужно вернуть через Элементы.Таблица.ТекущаяСтрока.
Как проверить результат
Изменился ровно на величину смещения
Строка оказалась в начале или конце таблицы
Значения всех колонок соответствуют ожидаемым строкам
Часть колонок не перенесена или затёрта
Курсор остался на перемещённой строке
Фокус сброшен на первую строку
FAQ
Можно ли менять строки местами мышкой, перетаскиванием?
Для таблицы значений на форме можно включить перетаскивание и обработать событие «Перетаскивание», выполнив в нём Сдвинуть или обмен значениями. Штатного drag-and-drop без программного кода у таблицы значений нет.
Почему Сдвинуть(0, -1) отправляет строку в конец?
Таково поведение платформы: смещение за границу коллекции выполняется циклически. Чтобы избежать этого, перед вызовом проверяйте, что индекс больше нуля для движения вверх и меньше последнего индекса для движения вниз.
Как поменять строки в дереве значений?
У коллекции строк дерева (Строки) тоже есть метод Сдвинуть, работающий внутри одного уровня. Перенос строки между разными родителями делается через добавление новой строки нужному родителю, копирование значений и удаление исходной.
Сохранится ли порядок строк после закрытия формы?
Нет, таблица значений — объект в памяти. Чтобы сохранить порядок, добавьте числовую колонку порядка и сохраняйте её значения в хранилище настроек, регистр сведений или реквизит объекта.
Чем отличается работа с табличной частью документа?
У табличной части также доступен метод Сдвинуть, но изменения фиксируются в базе только после записи документа. Учтите, что перенумерация строк может повлиять на движения, если они зависят от номеров строк.
Что важно запомнить
Для соседних строк используйте Сдвинуть с проверкой границ, для произвольных — обмен значениями колонок, для сохраняемого порядка — служебную числовую колонку и Сортировать. Всегда проверяйте индексы и положение текущей строки после операции.