Как программно выбрать справочник на форме и пометить на удаление все его элементы в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Шаг 1. Заполнение списка доступных справочников из метаданных

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

Рассмотрим пример процедуры инициализации:


Процедура ПриОткрытии()
    СпСправ.УдалитьВсе();
    Для К = 1 По Метаданные.Справочник() Цикл
        СпСправ.ДобавитьЗначение(Метаданные.Справочник(К).Идентификатор, Метаданные.Справочник(К).Представление());
    КонецЦикла;
КонецПроцедуры

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

Шаг 2. Создание объекта справочника по выбранному значению

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

Проанализируем типовые ошибки:

  1. Попытка передать результат функции ТипЗначенияСтр() в СоздатьОбъект() — это приводит к ошибке, так как возвращается тип переменной (например, "Число" или "СписокЗначений"), а не имя типа метаданных.
  2. Передача объекта метаданных напрямую без извлечения его строкового имени через свойство Идентификатор.

Посмотрим на корректный вариант инициализации:


Перем Спр, ИмяВыбранногоСправочника;

Если СпСправ.ТекущаяСтрока() > 0 Тогда
    ИмяВыбранногоСправочника = СпСправ.ПолучитьЗначение(СпСправ.ТекущаяСтрока());
    Спр = СоздатьОбъект("Справочник." + ИмяВыбранногоСправочника);
Иначе
    Предупреждение("Справочник не выбран!");
    Возврат;
КонецЕсли;

Шаг 3. Обход элементов и особенность метода ВыбратьЭлементы()

Следующий шаг — организация цикла по всем записям справочника для их обработки или пометки на удаление через метод Удалить(0).

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

По умолчанию метод ВыбратьЭлементы() без параметров (или со значением 1) пытается отобрать элементы только для текущего владельца, заданного методом ИспользоватьВладельца(). Если владелец не был явно установлен в коде, платформа возвращает 0 записей. Чтобы выполнить сплошную выборку по всей таблице справочника независимо от владельцев и иерархии, необходимо передавать параметр 0.

Разберем готовый алгоритм пакетной пометки элементов на удаление:


Процедура ПометитьВсеЭлементы()
    Перем Спр, ИмяВыбранногоСправочника, ВсегоОбработано, Счетчик;

    Если СпСправ.ТекущаяСтрока() = 0 Тогда
        Предупреждение("Выберите справочник из списка!");
        Возврат;
    КонецЕсли;

    ИмяВыбранногоСправочника = СпСправ.ПолучитьЗначение(СпСправ.ТекущаяСтрока());
    Спр = СоздатьОбъект("Справочник." + ИмяВыбранногоСправочника);

    // Параметр 0 обеспечивает выборку всех элементов подчиненных и иерархических справочников
    Спр.ВыбратьЭлементы(0);

    ВсегоОбработано = 0;
    Счетчик = 0;
    
    НачатьТранзакцию();
    
    Пока Спр.ПолучитьЭлемент() = 1 Цикл
        // Проверяем, не помечен ли элемент ранее
        Если Спр.ПометкаУдаления() = 0 Тогда
            Попытка
                Спр.Удалить(0); // 0 - пометка на удаление, 1 - непосредственное удаление
                ВсегоОбработано = ВсегоОбработано + 1;
                Счетчик = Счетчик + 1;
            Исключение
                Сообщить("Не удалось заблокировать/пометить элемент: " + Спр.ТекущийЭлемент() + " (" + ОписаниеОшибки() + ")");
            КонецПопытки;
        КонецЕсли;
        
        // Фиксация порциями для ускорения работы и предотвращения разрастания транзакции
        Если Счетчик >= 500 Тогда
            ЗафиксироватьТранзакцию();
            НачатьТранзакцию();
            Счетчик = 0;
        КонецЕсли;
    КонецЦикла;
    
    ЗафиксироватьТранзакцию();
    
    Сообщить("Обработка завершена. Всего помечено элементов: " + ВсегоОбработано);
КонецПроцедуры

Оптимизация и безопасность выполнения

Рассмотрим важные технические рекомендации при выполнении массовых операций со справочниками в 1С 7.7:

  1. Использование транзакций: Пакетная пометка на удаление сотен и тысяч элементов в цикле без использования механизма НачатьТранзакцию() / ЗафиксироватьТранзакцию() приводит к существенному замедлению работы файловой базы (DBF), так как диск нагружается операцией записи на каждую итерацию. Порционная фиксация (по 500–1000 элементов) ускоряет процесс в десятки раз.
  2. Обработка блокировок: В многопользовательском режиме элемент может быть открыт и заблокирован другим сеансом. Использование конструкции Попытка ... Исключение предотвращает аварийную остановку всей обработки при обнаружении единичной блокировки.
  3. Удаление ссылок перед физической очисткой: Если целью является полное удаление информации, предпочтительнее сначала пометить элементы на удаление, а затем воспользоваться штатной процедурой контроля ссылочной целостности («Удаление помеченных объектов»), чтобы избежать появления «битых» ссылок в связанных документах и регистрах.
← На главную