Почему функция НайтиПоСсылкам не возвращает записи регистров накопления и расчета?

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

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

Архитектура подчиненных регистров и поведение функции НайтиПоСсылкам

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

  1. Независимые регистры сведений: не привязаны к документам. Для идентификации конкретной строки платформа использует специальный объект — РегистрСведенийКлючЗаписи, который формируется по значениям ключевых измерений (и периода при периодическом регистре). При нахождении ссылки в таком регистре функция НайтиПоСсылкам() возвратит именно ключ записи.
  2. Регистры накопления, расчета, бухгалтерии и подчиненные регистры сведений: жестко подчинены документу-регистратору. У записей этих регистров нет собственного независимого ссылочного типа в базе данных, а их модификация, удаление и контроль целостности возможны только через набор записей с отбором по конкретному регистратору.

Именно поэтому, когда искомая ссылка (например, сотрудник) находится в измерении, ресурсе или реквизите регистра накопления или расчета, функция НайтиПоСсылкам() возвращает ссылку на документ-регистратор, сформировавший данное движение. С точки зрения ссылочной целостности платформы источником данных и владельцем движения выступает сам документ.

Проанализируем базовый пример вызова функции:


мФильтр = Новый Массив;
мФильтр.Добавить(ИскомыйСотрудник);

// Получаем таблицу со всеми местами использования ссылки
ТабСсылок = НайтиПоСсылкам(мФильтр);

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

  1. ИсходнаяСсылка — ссылка на проверяемый объект (значение из переданного массива).
  2. Данные — ссылка на найденный объект (документ, элемент справочника) либо объект-ключ необъектной таблицы (РегистрСведенийКлючЗаписи). Если ссылка найдена в движениях, здесь будет ссылка на документ-регистратор.
  3. Метаданные — объект метаданных (ОбъектМетаданных), в данных которого обнаружено вхождение ссылки.

Управление областью поиска и параметрами метода

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


НайтиПоСсылкам(<СписокСсылок>, <ОбластьПоиска>, <ВключитьОбъекты>, <ИсключитьОбъекты>)

Рассмотрим назначение каждого параметра подробнее:

  1. <СписокСсылок> — массив ссылок на объекты базы данных, поиск вхождений которых необходимо выполнить.
  2. <ОбластьПоиска> — массив объектов метаданных или описаний областей, в рамках которых осуществляется проверка.
  3. <ВключитьОбъекты> — массив объектов метаданных, которые принудительно включаются в анализ.
  4. <ИсключитьОбъекты> — массив объектов метаданных, поиск по которым выполнять не требуется (например, служебные журналы или регистры истории).

Ограничения прав доступа и производительность

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

  1. Ограничения на уровне записей (RLS): функция НайтиПоСсылкам() выполняет сплошное чтение таблиц. Если у текущего пользователя ограничены права на просмотр хотя бы одного из объектов базы, где потенциально встречается ссылка, вызов завершится системной ошибкой нарушения прав доступа. Чтобы избежать аварийного завершения в серверном коде, поиск рекомендуется выполнять в привилегированном режиме:
    
    УстановитьПривилегированныйРежим(Истина);
    ТаблицаВхождений = НайтиПоСсылкам(МассивСсылок);
    
  2. Нагрузка на СУБД: метод сканирует таблицы последовательно, что на крупных информационных базах может вызывать длительные блокировки и высокую утилизацию ресурсов сервера.

Альтернативные способы поиска конкретных записей в регистрах

Если перед разработчиком стоит задача не просто найти документы-регистраторы, а точно локализовать строки движений (получить номер строки, период, ресурсы или вид расчета), стандартного вызова НайтиПоСсылкам() недостаточно. В таких случаях применяют альтернативные подходы:

  1. Прямой запрос к таблицам движений: формируем запрос к конкретным таблицам регистров накопления или расчета с отбором по измерению, содержащему ссылку:
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Движения.Регистратор КАК Регистратор,
        |   Движения.НомерСтроки КАК НомерСтроки,
        |   Движения.Период КАК Период,
        |   Движения.Сумма КАК Сумма
        |ИЗ
        |   РегистрНакопления.ВзаиморасчетыССотрудниками КАК Движения
        |ГДЕ
        |   Движения.Сотрудник = &Сотрудник";
    
    Запрос.УстановитьПараметр("Сотрудник", ИскомыйСотрудник);
    РезультатЗапроса = Запрос.Выполнить().Выгрузить();
    
  2. Методы Библиотеки стандартных подсистем (БСП): в типовых конфигурациях рекомендуется использовать функцию ОбщегоНазначения.НайтиСсылкиНаОбъекты(), которая реализует оптимизированный поиск с учетом настроек конфигурации и прав доступа.

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

← На главную