При разработке сложных отчетов в системе «1С:Предприятие 8» программисты часто сталкиваются с ситуацией, когда стандартные связи по ссылочным полям (UUID) невозможны. Возникает соблазн соединить таблицы по строковым полям, используя оператор ПОДОБНО. Однако на этом пути разработчика подстерегает ряд ловушек — от синтаксических ошибок до критического падения производительности системы. Рассмотрим подробно, почему такой подход часто не работает и как решить задачу правильно.
Проанализируем исходный код, представленный в вопросе. Автор пытается выполнить соединение следующим образом:
ПО (УчетЗатрат.АналитикаВидаУчета.Наименование ПОДОБНО "%" + Производство.Номенклатура.Наименование + "%")
Разберем, в чем здесь главная проблема. Язык запросов 1С не поддерживает оператор сложения строк «+». В отличие от встроенного языка 1С, где мы можем свободно складывать строки, в запросе (который транслируется в SQL) такая конструкция недопустима ни в блоке ВЫБРАТЬ, ни в условии ПО, ни в блоке ГДЕ.
Как исправить: Если нам необходимо использовать динамическую маску поиска, ее нужно подготовить заранее во встроенном языке и передать в запрос как готовый параметр. Однако это работает только для условий фильтрации (ГДЕ), но не для условий соединения таблиц (ПО), так как в соединении участвуют поля из обеих таблиц одновременно.
// Правильная подготовка параметра
МаскаПоиска = "%" + ЗначениеДляПоиска + "%";
Запрос.УстановитьПараметр("МаскаПоиска", МаскаПоиска);
// Использование в запросе
ГДЕ УчетЗатрат.АналитикаУчетаЗатрат.Наименование ПОДОБНО &МаскаПоиска
В вопросе упоминается регистр УчетЗатратРегл. Это ключевой объект расширенной аналитики учета затрат (РАУЗ), характерный для конфигураций УПП 1.3 и КА 1.1. Выясним причину, по которой попытка получить номенклатуру напрямую через Наименование аналитики обречена на провал.
В РАУЗ измерение АналитикаУчетаЗатрат ссылается не на справочник Номенклатура, а на специальный справочник Ключи аналитики учета затрат. В этом справочнике поле Наименование является служебным и формируется автоматически. Оно может содержать техническую информацию, которая не совпадает с чистым наименованием номенклатуры из документа ПланПроизводства.
Правильное решение: Для получения связи с номенклатурой необходимо выполнить соединение с регистром сведений АналитикаУчетаЗатрат (или АналитикаВидаУчета), где хранится соответствие ключа аналитики и конкретной ссылки на справочник Номенклатура.
ВЫБРАТЬ
УчетЗатрат.КоличествоОборот,
Аналитика.Затрата КАК НоменклатураИзРегистра
ИЗ
РегистрНакопления.УчетЗатратРегл.Обороты КАК УчетЗатрат
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.АналитикаУчетаЗатрат КАК Аналитика
ПО УчетЗатрат.АналитикаУчетаЗатрат = Аналитика.Ссылка
Даже если бы 1С позволяла складывать строки в условии ПО, использование ПОДОБНО с процентом в начале строки (%Текст%) — это «убийца» производительности. Посмотрим на ситуацию глазами СУБД (SQL Server или PostgreSQL):
%, СУБД не может использовать индекс по этому полю.Рассмотрим по шагам, как профессионально реализовать сопоставление данных, если прямой связи действительно нет.
Шаг 1. Использование временных таблиц.
Вместо прямого соединения огромных таблиц, сначала выберем данные из документа во временную таблицу и подготовим данные для поиска.
// Сначала подготавливаем данные из документа в коде
ТЗ_План = Объект.СоставПлана.Выгрузить();
Для Каждого Стр Из ТЗ_План Цикл
// Добавляем служебную колонку для поиска
Стр.СтрокаПоиска = "%" + Стр.Номенклатура.Наименование + "%";
КонецЦикла;
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.УстановитьПараметр("ТЗ_План", ТЗ_План);
// Помещаем во ВТ
Запрос.Текст = "ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_План ИЗ &ТЗ_План КАК ТЗ_План";
Запрос.Выполнить();
Шаг 2. Оптимизированный запрос.
Теперь мы можем попытаться выполнить соединение. Но помните, что даже во временных таблицах условие ПОДОБНО в соединении работает медленно. Если есть возможность, лучше использовать Систему компоновки данных (СКД).
Шаг 3. Использование СКД для связи наборов данных.
Проанализируем вариант с СКД, который является наиболее правильным для отчетов:
ПОДОБНО там также ограничено.Наименование, а во втором — подготовить такое же поле, и связать их по равенству.Выясним основную причину неудачи автора темы: это попытка применить логику встроенного языка (конкатенация через «+») внутри SQL-запроса, наложенная на непонимание структуры регистра УчетЗатратРегл.
Помните ключевые правила:
ПОДОБНО, если количество записей в таблицах превышает несколько сотен.АналитикаУчетаЗатрат, АналитикаВидаУчета).Соблюдение этих правил позволит вам создавать быстрые и отказоустойчивые отчеты, которые не будут вызывать проблем при росте объема базы данных.