Как исправить ошибку «Не найдено поле замены» в СКД 1С

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

Ошибка «Не найдено поле замены» в системе компоновки данных (СКД) — одна из наиболее коварных для начинающих разработчиков. Она возникает в тот момент, когда компоновщик макета пытается сопоставить поля, указанные в настройках или тексте запроса, с реально доступными полями в наборе данных, но не находит соответствия. Разберем подробно причины возникновения этой ошибки и способы ее решения на конкретных примерах.

Причина 1: Отсутствие поля в итоговой выборке запроса

Наиболее распространенная ситуация, которую мы видим в обсуждении: поле добавлено в соединение или в одну из временных таблиц, но «забыто» в финальном блоке ВЫБРАТЬ. Рассмотрим ситуацию на примере запроса из сообщения форума. Проанализируем, почему поле ИНН вызывало ошибку.

В исходном коде разработчик поместил данные во временную таблицу ВТ_ТребуемыеОбороты, выполнив левое соединение со справочником контрагентов:


ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.Организация,
    ...
    Контрагенты.ИНН
ПОМЕСТИТЬ ВТ_ТребуемыеОбороты
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(...) КАК ХозрасчетныйОборотыДтКт
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
    ПО ...
;

Однако в следующем запросе того же пакета, который и возвращает результат в СКД, поле ИНН не было указано:


ВЫБРАТЬ
    ВТ_ТребуемыеОбороты.Организация,
    ВТ_ТребуемыеОбороты.СуммаОборот
    // Поле ИНН здесь отсутствовало!
ИЗ
    ВТ_ТребуемыеОбороты КАК ВТ_ТребуемыеОбороты

Когда вы добавляете поле в схему компоновки (на закладке «Наборы данных»), СКД ожидает найти его в финальном результате выполнения запроса. Если запрос его не возвращает, возникает ошибка замены. Решение: обязательно проверьте все части пакета запросов и убедитесь, что поле «проброшено» до самого конца.

Правильный вариант финальной части запроса:


ВЫБРАТЬ
    ВТ_ТребуемыеОбороты.Организация,
    ВТ_ТребуемыеОбороты.СуммаОборот,
    ВТ_ТребуемыеОбороты.ИНН
ИЗ
    ВТ_ТребуемыеОбороты КАК ВТ_ТребуемыеОбороты

Причина 2: Проблемы с типами данных и обращением через точку

Часто разработчики пытаются получить данные через поля субконто, которые имеют тип Характеристика.ВидыСубконтоХозрасчетные. Выясним причину, почему прямое соединение может не работать или возвращать пустые значения. В запросах к регистрам бухгалтерии субконто — это составной тип. Если вы просто напишете СубконтоДт1.ИНН, система может не понять, к какому именно справочнику вы обращаетесь.

Рассмотрим более надежный способ получения данных с использованием оператора ВЫБОР и проверки типа ССЫЛКА, который предложили участники обсуждения:


ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.Организация,
    ВЫБОР 
        КОГДА ХозрасчетныйОборотыДтКт.СубконтоДт1 ССЫЛКА Справочник.Контрагенты 
        ТОГДА ХозрасчетныйОборотыДтКт.СубконтоДт1.ИНН 
        КОГДА ХозрасчетныйОборотыДтКт.СубконтоКт1 ССЫЛКА Справочник.Контрагенты 
        ТОГДА ХозрасчетныйОборотыДтКт.СубконтоКт1.ИНН 
        ИНАЧЕ "" 
    КОНЕЦ КАК ИНН
ПОМЕСТИТЬ ВТ_ТребуемыеОбороты

Этот подход гарантирует, что поле ИНН будет заполнено только тогда, когда в субконто действительно находится контрагент. Также это избавляет от лишних левых соединений, которые могут замедлять отчет.

Причина 3: Несоответствие имен во внешних наборах данных (ТЗ)

Если ваш отчет строится на основе Таблицы Значений, передаваемой в СКД программно, критически важно соблюдать идентичность имен. Посмотрим на алгоритм проверки:

  1. В схеме СКД создан набор данных типа «Объект». В поле «Имя объекта содержащего данные» указано, например, ТЗ_Данные.
  2. В этом наборе данных описано поле с именем ИНН (проверьте отсутствие лишних пробелов и латинских букв в кириллическом названии).
  3. В программном коде при формировании таблицы значений колонка должна называться точно так же.

Типичная ошибка в коде:


// В СКД поле называется "ИНН"
ТаблицаРезультат = Новый ТаблицаЗначений;
ТаблицаРезультат.Колонки.Добавить("TaxID"); // ОШИБКА: Имя не совпадает с СКД

Также проверьте процесс передачи таблицы в компоновщик. Посмотрим на пример правильной передачи:


ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТЗ_Данные", ТаблицаРезультат); // Имя должно совпадать с именем в СКД

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);

Причина 4: Права доступа и RLS

Проанализируем ситуацию, когда у разработчика отчет работает, а у пользователя — нет. Если в системе настроены ограничения прав на уровне записей (RLS), и у пользователя нет прав на чтение определенного реквизита (например, Менеджер в ЗаказеКлиента), СКД может выбросить ошибку замены. Это происходит потому, что при генерации итогового SQL-запроса система исключает недоступные поля, и «заменять» в макете становится нечего.

Как проверить: запустите отчет под полными правами. Если ошибка исчезла — проблема в ролях. Вам потребуется либо добавить права на чтение реквизита, либо использовать в запросе конструкцию РАЗРЕШЕННЫЕ, но учитывать, что поле будет пустым.

Причина 5: Фигурные скобки и автозаполнение

Система СКД активно использует расширение языка запросов (фигурные скобки {}). Если вы используете конструкцию типа {ГДЕ ИНН}, но в самом запросе поле называется иначе (например, КонтрагентИНН) или оно не отмечено флагом «Автозаполнение», СКД не сможет сопоставить поле в скобках с полями набора данных.

Рекомендуем придерживаться следующих правил:

Итоги

Для исправления ошибки «Не найдено поле замены» пройдите по чек-листу:

  1. Проверьте, что поле есть в последнем запросе пакета.
  2. Убедитесь, что имя колонки в ТЗ совпадает с именем в наборе данных СКД.
  3. Проверьте регистр и язык написания (ИНН vs INN).
  4. Очистите настройки отчета в режиме «1С:Предприятие» (установите стандартные), так как система могла запомнить старую структуру полей.
  5. Проверьте права доступа пользователя к данному полю.
← На главную