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