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

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

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

Проблема удаления элементов в цикле

Рассмотрим стандартную ситуацию: у нас есть коллекция ПодчиненныеЭлементы таблицы формы, и мы хотим удалить всё, начиная со второй или третьей колонки. Основная ошибка начинающих разработчиков заключается в попытке использовать простой цикл Для каждого или прямой цикл по индексам от 0 до N.

Проанализируем, почему это не работает. Когда мы вызываем метод Удалить() для элемента коллекции, состав этой коллекции меняется мгновенно. Элемент, который был третьим, становится вторым. Индексы «сдвигаются», и следующий шаг цикла либо пропускает нужный элемент, либо приводит к ошибке обращения по несуществующему индексу. Именно поэтому важно выбрать правильную стратегию обхода.

Способ №1: Использование цикла «Пока» и контроль количества

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

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


НаборЭлементов = Элементы.СписокУчеников.ПодчиненныеЭлементы;
СколькоОставить = 2; // Например, оставляем Код и Наименование

Пока НаборЭлементов.Количество() > СколькоОставить Цикл
    // Всегда удаляем элемент, следующий за последним оставленным.
    // Если оставляем 2 колонки (индексы 0 и 1), то удаляем всегда индекс 2.
    Элементы.Удалить(НаборЭлементов.Получить(СколькоОставить));
КонецЦикла;

В данном примере мы используем объект Элементы для удаления. Важно понимать, что НаборЭлементов.Получить(СколькоОставить) всегда будет возвращать «новую» колонку, которая заняла место удаленной на предыдущей итерации.

Способ №2: Обратный цикл (с конца к началу)

Если нам привычнее работать с циклом Для, то классическим решением задачи удаления является обход коллекции с конца. При таком подходе удаление последнего элемента никак не влияет на индексы тех элементов, которые стоят перед ним и которые нам еще только предстоит обработать.

Рассмотрим, как реализовать перебор со второй колонки (индекс 1) до конца и удалить их:


КолонкиТаблицы = Элементы.СписокУчеников.ПодчиненныеЭлементы;
ВсегоЭлементов = КолонкиТаблицы.Количество();

// Обходим с последнего индекса вниз до индекса 1 (вторая колонка)
Для Индекс = (ВсегоЭлементов - 1) По 1 Шаг -1 Цикл
    ТекущийЭлемент = КолонкиТаблицы[Индекс];
    Элементы.Удалить(ТекущийЭлемент);
КонецЦикла;

Этот метод гарантирует безопасность, так как структура индексов для еще не пройденных итераций остается стабильной. Мы используем Шаг -1, чтобы двигаться в обратном направлении.

Способ №3: Перебор по индексам для вывода сообщений или анализа

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


Подчиненные = Элементы.СписокУчеников.ПодчиненныеЭлементы;

// Начинаем с индекса 1 (это второй элемент в коллекции)
Для й = 1 По Подчиненные.Количество() - 1 Цикл
    Сообщить("Обработка колонки: " + Подчиненные[й].Имя);
    // Здесь можно менять свойства, например:
    // Подчиненные[й].ТолькоПросмотр = Истина;
КонецЦикла;

Важные технические нюансы

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

  1. Типизация элементов: Коллекция ПодчиненныеЭлементы может содержать не только колонки (тип ПолеФормы), но и группы колонок. Если вы планируете удалять только поля, добавьте проверку: Если ТипЗнч(Элемент) = Тип("ПолеФормы") Тогда.
  2. Имена против индексов: Опираться на жесткие индексы (0, 1, 2) рискованно. Пользователь может изменить порядок колонок в режиме «Изменить форму», и ваша логика может затронуть не те данные. Безопаснее всего проверять имя колонки: Если Элемент.Имя = "УченикФИО" Тогда Продолжить; КонецЕсли;.
  3. Элементы vs Реквизиты: Помните, что удаление элемента с формы (визуального объекта) не удаляет данные из таблицы (реквизита формы). Если вы создавали колонки динамически через ИзменитьРеквизиты(), их нужно удалять и из состава реквизитов, иначе при следующем обращении к серверу они могут восстановиться или вызвать конфликты.
  4. Свойство «Видимость»: Зачастую вместо физического удаления элементов гораздо эффективнее и быстрее просто установить Элемент.Видимость = Ложь. Это снижает нагрузку на серверную отрисовку формы и позволяет легко вернуть колонку обратно.

Рекомендация по выбору метода

Проанализировав ситуацию, можно сделать вывод: если ваша цель — полная очистка лишних элементов, используйте цикл «Пока» (Способ №1) или обратный цикл (Способ №2). Если же вам нужно просто пропустить первый элемент при обходе для выполнения каких-то действий, используйте цикл Для с начальным значением счетчика равным 1.

← На главную