В процессе разработки внешних обработок часто возникает задача создания универсального инструмента для массового изменения данных. Одной из таких задач является программный перебор всех справочников или документов в конфигурации, их фильтрация по определенным критериям и последующая обработка (например, добавление префикса к номеру или коду). В этой статье мы подробно разберем, как работать с коллекциями метаданных, как организовать выбор нужных типов объектов и как правильно взаимодействовать с механизмом автонумерации 1С.
Для начала разберем, как 1С хранит информацию о структуре базы данных. Объект Метаданные является точкой доступа ко всей конфигурации. Он содержит коллекции, такие как Документы, Справочники, ПланыВидовХарактеристик и другие. Проанализируем способ обхода этих коллекций. Если нам необходимо получить список всех типов документов, существующих в системе, мы используем цикл Для Каждого.
Рассмотрим простейший пример получения имен всех документов:
Для Каждого Документ Из Метаданные.Документы Цикл
Сообщить("Имя документа: " + Документ.Имя);
КонецЦикла;
Важно понимать, что в данном цикле переменная Документ имеет тип ОбъектМетаданных: Документ, а не является ссылкой на конкретную запись в базе. Через этот объект мы можем получить доступ к свойствам конфигурации, таким как длина номера, тип номера или состав реквизитов.
Зачастую заказчику не нужно обрабатывать сразу все объекты. Выясним, как реализовать фильтрацию. Существует два основных подхода: жесткое ограничение в коде и предоставление выбора пользователю.
Способ 1: Использование массива предопределенных имен. Если список объектов заранее известен и неизменен, мы можем создать массив со строковыми именами нужных метаданных. Проанализируем код:
МассивНужныхТипов = Новый Массив;
МассивНужныхТипов.Добавить("ПриходнаяНакладная");
МассивНужныхТипов.Добавить("РасходнаяНакладная");
Для Каждого ИмяОбъекта Из МассивНужныхТипов Цикл
МетаданныеОбъекта = Метаданные.Документы[ИмяОбъекта];
// Дальнейшая обработка
КонецЦикла;
Способ 2: Визуальный выбор пользователем. Более гибкий вариант — вывести список всех типов объектов в табличную часть на форме, чтобы пользователь мог отметить нужные флажками. Разберем по шагам, как это реализовать:
СписокОбъектов), добавим в нее колонки Пометка (Булево) и ИмяМетаданных (Строка).Метаданные.Документы.Пометка = Истина.При работе с префиксами важно помнить о различиях в свойствах справочников и документов. Рассмотрим их подробнее:
ДлинаНомера и ТипНомера.ДлинаКода и ТипКода.Если мы пишем универсальную функцию, которая должна определять эти параметры динамически, нам необходимо проверять, к какой коллекции относится объект. Посмотрим на пример реализации такой проверки:
Функция ОпределитьПараметрыНумерации(МетаданныеОбъекта)
Результат = Новый Структура("Длина, Тип", 0, "");
Если Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда
Результат.Длина = МетаданныеОбъекта.ДлинаНомера;
Результат.Тип = МетаданныеОбъекта.ТипНомера;
ИначеЕсли Метаданные.Справочники.Содержит(МетаданныеОбъекта) Тогда
Результат.Длина = МетаданныеОбъекта.ДлинаКода;
Результат.Тип = МетаданныеОбъекта.ТипКода;
КонецЕсли;
Возврат Результат;
КонецФункции
Разберем ситуацию, которая часто пугает начинающих разработчиков: после работы обработки все новые документы начинают создаваться с «неправильным» префиксом. Выясним причину этого поведения.
В 1С реализован механизм автоматической генерации номера. Когда пользователь нажимает «Создать», система ищет в базе данных объект с самым большим номером (в лексикографическом порядке) для данного типа. Платформа анализирует этот номер, выделяет в нем текстовую часть (префикс) и числовую часть, увеличивает число на единицу и формирует новый номер.
Важный момент: если вы программно изменили номер хотя бы у одного документа на "ПР-0001", и этот номер стал «старшим» в системе, то все последующие документы будут получать префикс "ПР-". Чтобы избежать хаоса, перед массовым изменением номеров необходимо четко согласовать логику префиксации с требованиями учета.
Для того чтобы получить ссылки на все документы выбранного типа и изменить их, эффективнее всего использовать запрос. Рассмотрим пример формирования текста запроса динамически:
Процедура ОбработатьДокументыТипа(ИмяДокумента, НовыйПрефикс)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка, Номер ИЗ Документ." + ИмяДокумента;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ОбъектДок = Выборка.Ссылка.ПолучитьОбъект();
// Пример упрощенной логики замены префикса
ОбъектДок.Номер = НовыйПрефикс + Сред(Выборка.Номер, СтрДлина(НовыйПрефикс) + 1);
Попытка
ОбъектДок.Записать(РежимЗаписиДокумента.Запись);
Исключение
Сообщить("Ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
В данном примере мы используем прямое обращение к таблице документа через его имя в метаданных. Это позволяет нам получить доступ ко всем существующим в базе записям выбранного типа.
Проанализируем несколько правил, которые помогут избежать критических ошибок при работе с метаданными:
Объект.ОбменДанными.Загрузка = Истина;. Это отключит лишние проверки и подписки на события, что значительно ускорит процесс и предотвратит ошибки, связанные с логикой проведения документов.Таким образом, мы выяснили, что работа с метаданными в 1С требует понимания коллекций конфигурации и механизмов платформы, таких как автонумерация. Используя коллекции Метаданные.Документы и Метаданные.Справочники в сочетании с динамическими запросами, можно создавать мощные инструменты для администрирования и автоматизации системы.