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