Почему возникает ошибка «Поле не найдено» при работе с Разрезами в регистрах расчета 1С и как её исправить?

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

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

Как формируются поля с суффиксом «Разрез» в виртуальных таблицах

Для начала проанализируем механику работы платформы 1С при обращении к виртуальным таблицам базовых данных регистра расчета. В качестве примера рассмотрим виртуальную таблицу РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления.

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

Чтобы получить детализацию базовых данных по полям базового регистра, нам необходимо использовать третий параметр виртуальной таблицы — параметр «Разрезы». Рассмотрим пример кода, который часто пытаются использовать разработчики:


ВЫБРАТЬ
    ДополнительныеНачисленияБазаОсновныеНачисления.НомерСтроки КАК НомерСтроки,
    ДополнительныеНачисленияБазаОсновныеНачисления.РезультатБаза КАК БазаНачислений,
    ДополнительныеНачисленияБазаОсновныеНачисления.СотрудникРазрез КАК СотрудникРазрез
ИЗ
    РегистрРасчета.ДополнительныеНачисления.БазаОсновныеНачисления(&Измерения, &Измерения, &Разрезы, Регистратор = &Регистратор) КАК ДополнительныеНачисленияБазаОсновныеНачисления

В коде модуля передачи параметра мы задаем массив:


Разрезы = Новый Массив(1);
Разрезы[0] = "Сотрудник";
Запрос.УстановитьПараметр("Разрезы", Разрезы);

Посмотрим на то, что происходит «под капотом». Если в параметр &Разрезы передать массив строк с именами полей (в нашем случае это строка Сотрудник), платформа 1С «на лету» создаст в виртуальной таблице новую колонку. Имя этой новой колонки формируется по строгому правилу: к исходному имени поля добавляется слово «Разрез». Именно так из переданного Сотрудник генерируется доступное для выборки поле СотрудникРазрез.

Истинные причины ошибки «Поле не найдено»

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

  1. Неверный тип переданного параметра. Параметр &Разрезы должен быть строго объектом Массив (содержащим строки) или объектом СписокЗначений (где значение каждого элемента — это Строка). Если вы передадите туда пустой массив, значение другого типа (например, ссылку на конкретного сотрудника из справочника, а не текст) или значение NULL, система не выдаст критического сбоя при передаче параметра. Она просто проигнорирует его. Следовательно, колонки разрезов сгенерированы не будут, и при попытке выбрать поле СотрудникРазрез в секции ВЫБРАТЬ возникнет ошибка.
  2. Отсутствие поля в базовом регистре. Если вы передаете в массив имя поля, которого физически не существует в таблице базового регистра расчета, колонка разреза также не сформируется. Разработчик должен точно знать структуру базы.
  3. Ошибки в архитектуре метаданных (разные типы измерений). Это самая коварная ошибка, которую мы детально разберем ниже.

Тонкости работы и отладки в Консоли запросов

Очень часто разработчики сталкиваются с парадоксом: в программном коде запрос может работать (или падать по другой причине), а при попытке отладить его в стандартной Консоли запросов 1С ошибка «Поле не найдено» появляется постоянно. Разберем по шагам, как правильно настраивать параметры в консоли.

В консоли запросов мы не можем написать программный код инициализации массива. Вместо этого мы используем графический интерфейс:

  1. Откройте вкладку параметров запроса.
  2. Для параметра &Разрезы в колонке «Тип значения» обязательно выберите СписокЗначений.
  3. Откройте сам список значений для редактирования.
  4. Добавьте новую строку. Здесь кроется главная ловушка: по умолчанию тип нового значения может установиться неправильно. Вы обязательно должны явно выбрать тип Строка для элемента списка.
  5. Впишите текстовое имя измерения, например, Сотрудник.

Если по ошибке передать в список значений ссылку на конкретного сотрудника (элемент справочника ФизическиеЛица или Сотрудники), а не строковое название поля, запрос не увидит разрезов и выдаст ошибку.

Связь измерений и базовых регистров: ошибка проектирования архитектуры

Проанализируем ситуацию, когда параметры в консоли и в коде передаются абсолютно верно (массив строк), но ошибка все равно сохраняется. Именно с этим столкнулся автор исходной проблемы.

Механизм базовых таблиц 1С опирается на строгие правила сопоставления. Виртуальная таблица базы пытается связать записи текущего регистра расчета с записями базового регистра. Эта связь происходит по измерениям. Чтобы система могла корректно сопоставить записи и развернуть их в разрезе (создав поле СотрудникРазрез), типы данных этих измерений должны быть совместимы.

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

Если в основном регистре измерение имеет тип Строка, а в базовом регистре (из которого мы тянем базу) это же по смыслу измерение имеет тип ссылочный, система не сможет корректно связать эти таблицы. Логика платформы блокирует построение разреза по несовместимым полям. В результате динамическое поле не создается, и мы получаем ошибку ненайденного поля.

Как исправить эту проблему:

  1. Откройте конфигуратор и перейдите к вашему регистру расчета (например, ДополнительныеНачисления).
  2. Проверьте свойства измерений (например, Сотрудник, Подразделение).
  3. Убедитесь, что их типы данных строго соответствуют логике системы (например, СправочникСсылка.ФизическиеЛица, СправочникСсылка.Подразделения).
  4. Сохраните изменения, обновите конфигурацию базы данных. При необходимости перепроведите документы, чтобы записи в регистре сформировались с корректными ссылочными типами.

Оптимизация: всегда ли нужны разрезы?

В завершение проанализируем целесообразность использования параметра «Разрезы». Разработчики часто добавляют его «на всякий случай», даже когда этого не требует бизнес-логика.

Важно понимать, что параметр «Разрезы» значительно усложняет текст SQL-запроса, который платформа 1С транслирует к СУБД (MS SQL, PostgreSQL и др.). Использование разрезов заставляет базу данных выполнять дополнительные ресурсоемкие операции соединения таблиц (JOIN) и группировки.

Использовать параметр &Разрезы стоит исключительно в следующих случаях:

  1. Вам необходимо отфильтровать полученную базу по сложному условию, зависящему от измерений базового регистра.
  2. Вам нужно получить базу только с определенных записей (например, вычесть базу, где Таблица.Сотрудник <> Таблица.СотрудникРазрез — расчет базы по другим сотрудникам, если такая экзотика предусмотрена алгоритмом).
  3. Требуется пропорциональное распределение базы в зависимости от конкретных измерений (например, подразделений, в которых сотрудник работал в течение расчетного периода).

Если ваша задача состоит лишь в том, чтобы получить общую итоговую сумму базовых начислений для элементарного расчета (например, вычисление 10% премии от оклада по одному конкретному сотруднику и документу), параметр &Разрезы следует оставлять пустым или вообще пропускать. Это сделает ваш запрос более быстрым и снизит нагрузку на сервер базы данных.

← На главную