Ошибка «Не найдено поле замены» в системе компоновки данных (СКД) — одна из наиболее коварных для начинающих разработчиков. Она возникает в тот момент, когда компоновщик макета пытается сопоставить поля, указанные в настройках или тексте запроса, с реально доступными полями в наборе данных, но не находит соответствия. Разберем подробно причины возникновения этой ошибки и способы ее решения на конкретных примерах.
Наиболее распространенная ситуация, которую мы видим в обсуждении: поле добавлено в соединение или в одну из временных таблиц, но «забыто» в финальном блоке ВЫБРАТЬ. Рассмотрим ситуацию на примере запроса из сообщения форума. Проанализируем, почему поле ИНН вызывало ошибку.
В исходном коде разработчик поместил данные во временную таблицу ВТ_ТребуемыеОбороты, выполнив левое соединение со справочником контрагентов:
ВЫБРАТЬ
ХозрасчетныйОборотыДтКт.Организация,
...
Контрагенты.ИНН
ПОМЕСТИТЬ ВТ_ТребуемыеОбороты
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(...) КАК ХозрасчетныйОборотыДтКт
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
ПО ...
;
Однако в следующем запросе того же пакета, который и возвращает результат в СКД, поле ИНН не было указано:
ВЫБРАТЬ
ВТ_ТребуемыеОбороты.Организация,
ВТ_ТребуемыеОбороты.СуммаОборот
// Поле ИНН здесь отсутствовало!
ИЗ
ВТ_ТребуемыеОбороты КАК ВТ_ТребуемыеОбороты
Когда вы добавляете поле в схему компоновки (на закладке «Наборы данных»), СКД ожидает найти его в финальном результате выполнения запроса. Если запрос его не возвращает, возникает ошибка замены. Решение: обязательно проверьте все части пакета запросов и убедитесь, что поле «проброшено» до самого конца.
Правильный вариант финальной части запроса:
ВЫБРАТЬ
ВТ_ТребуемыеОбороты.Организация,
ВТ_ТребуемыеОбороты.СуммаОборот,
ВТ_ТребуемыеОбороты.ИНН
ИЗ
ВТ_ТребуемыеОбороты КАК ВТ_ТребуемыеОбороты
Часто разработчики пытаются получить данные через поля субконто, которые имеют тип Характеристика.ВидыСубконтоХозрасчетные. Выясним причину, почему прямое соединение может не работать или возвращать пустые значения. В запросах к регистрам бухгалтерии субконто — это составной тип. Если вы просто напишете СубконтоДт1.ИНН, система может не понять, к какому именно справочнику вы обращаетесь.
Рассмотрим более надежный способ получения данных с использованием оператора ВЫБОР и проверки типа ССЫЛКА, который предложили участники обсуждения:
ВЫБРАТЬ
ХозрасчетныйОборотыДтКт.Организация,
ВЫБОР
КОГДА ХозрасчетныйОборотыДтКт.СубконтоДт1 ССЫЛКА Справочник.Контрагенты
ТОГДА ХозрасчетныйОборотыДтКт.СубконтоДт1.ИНН
КОГДА ХозрасчетныйОборотыДтКт.СубконтоКт1 ССЫЛКА Справочник.Контрагенты
ТОГДА ХозрасчетныйОборотыДтКт.СубконтоКт1.ИНН
ИНАЧЕ ""
КОНЕЦ КАК ИНН
ПОМЕСТИТЬ ВТ_ТребуемыеОбороты
Этот подход гарантирует, что поле ИНН будет заполнено только тогда, когда в субконто действительно находится контрагент. Также это избавляет от лишних левых соединений, которые могут замедлять отчет.
Если ваш отчет строится на основе Таблицы Значений, передаваемой в СКД программно, критически важно соблюдать идентичность имен. Посмотрим на алгоритм проверки:
ТЗ_Данные.ИНН (проверьте отсутствие лишних пробелов и латинских букв в кириллическом названии).Типичная ошибка в коде:
// В СКД поле называется "ИНН"
ТаблицаРезультат = Новый ТаблицаЗначений;
ТаблицаРезультат.Колонки.Добавить("TaxID"); // ОШИБКА: Имя не совпадает с СКД
Также проверьте процесс передачи таблицы в компоновщик. Посмотрим на пример правильной передачи:
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТЗ_Данные", ТаблицаРезультат); // Имя должно совпадать с именем в СКД
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
Проанализируем ситуацию, когда у разработчика отчет работает, а у пользователя — нет. Если в системе настроены ограничения прав на уровне записей (RLS), и у пользователя нет прав на чтение определенного реквизита (например, Менеджер в ЗаказеКлиента), СКД может выбросить ошибку замены. Это происходит потому, что при генерации итогового SQL-запроса система исключает недоступные поля, и «заменять» в макете становится нечего.
Как проверить: запустите отчет под полными правами. Если ошибка исчезла — проблема в ролях. Вам потребуется либо добавить права на чтение реквизита, либо использовать в запросе конструкцию РАЗРЕШЕННЫЕ, но учитывать, что поле будет пустым.
Система СКД активно использует расширение языка запросов (фигурные скобки {}). Если вы используете конструкцию типа {ГДЕ ИНН}, но в самом запросе поле называется иначе (например, КонтрагентИНН) или оно не отмечено флагом «Автозаполнение», СКД не сможет сопоставить поле в скобках с полями набора данных.
Рекомендуем придерживаться следующих правил:
ВЫБРАТЬ понятны и уникальны.ОБЪЕДИНИТЬ ВСЕ) убедитесь, что поле присутствует во всех частях объединения с одинаковым типом.Для исправления ошибки «Не найдено поле замены» пройдите по чек-листу: