В практике разработки на платформе 1С нередко возникают задачи, когда необходимо сопоставить данные двух несвязанных напрямую документов или регистров по текстовому реквизиту — например, по полю Содержание проводки или операции. Сложность заключается в том, что в одном документе может содержаться только идентификатор или код, а в другом — код вместе с дополнительным описанием.
Разберем подробно, как правильно извлечь часть строки, сформировать условие соединения через ПОДОБНО с использованием временных таблиц и обойти типичные ошибки при работе со строками неограниченной длины.
Рассмотрим стандартную ситуацию: в первых документах в начале поля Содержание содержится ключевой код партии или ящика (например, первые 10–20 символов), за которым следует произвольный текст. Во вторых документах указан только этот код либо он входит в состав текста. Нам необходимо сопоставить строки обеих выборок.
Для корректного соединения необходимо соблюдать ключевые правила:
ПОДСТРОКА: В языке запросов 1С нумерация символов всегда начинается с единицы (1). Указание 0 является синтаксической ошибкой или может приводить к платформозависимым сбоям при трансляции в SQL.= или использовать в условиях соединения. Функция ПОДСТРОКА(Поле, 1, N) или ВЫРАЗИТЬ(Поле КАК СТРОКА(N)) приводит строку к фиксированной длине.ПО Таблица2.Текст ПОДОБНО Таблица1.Шаблон длинный текст должен находиться слева, а шаблон с подстановочным знаком % (джокером) — справа. Для поиска совпадения по началу строки к выделенной подстроке добавляется знак процента в конце: ПОДСТРОКА(Поле, 1, 10) + "%".Проанализируем пример построения пакета запросов, в котором сначала отбираются первичные документы поступления с выделением кода, а затем к ним левым соединением подтягиваются связанные документы таможенных расходов.
ВЫБРАТЬ
ВыборкаТМЗ.Регистратор КАК ДокументПоступления,
ВыборкаТМЗ.СубконтоДт1 КАК Номенклатура,
ПОДСТРОКА(ВыборкаТМЗ.Регистратор.Содержание, 1, 10) + "%" КАК ШаблонКода
ПОМЕСТИТЬ ВТ_ИсходныеТМЗ
ИЗ
РегистрБухгалтерии.Типовой.ДвиженияССубконто(
&НачалоПериода,
&КонецПериода,
Регистратор ССЫЛКА Документ.ОперацияБух
И Регистратор.Содержание ПОДОБНО "%беспл%",
,
) КАК ВыборкаТМЗ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ИсходныеТМЗ.ДокументПоступления КАК ДокументПоступления,
ВТ_ИсходныеТМЗ.Номенклатура КАК Номенклатура,
ТаможенныеПлатежи.Период КАК ПериодРасхода,
ТаможенныеПлатежи.Регистратор КАК ДокументРасхода,
ТаможенныеПлатежи.Сумма КАК СуммаРасхода,
ТаможенныеПлатежи.КоличествоДт КАК Количество
ИЗ
ВТ_ИсходныеТМЗ КАК ВТ_ИсходныеТМЗ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Типовой.ДвиженияССубконто(
&НачалоПериода,
&КонецПериода,
Регистратор ССЫЛКА Документ.ОперацияБух,
,
) КАК ТаможенныеПлатежи
ПО (ТаможенныеПлатежи.Регистратор.Содержание ПОДОБНО ВТ_ИсходныеТМЗ.ШаблонКода)
Разберем по шагам, как работает этот запрос:
ВТ_ИсходныеТМЗ мы отбираем только нужные операции поступления и формируем поле ШаблонКода. Для этого берем первые 10 символов поля содержания и конкатенируем их со знаком процента: ПОДСТРОКА(..., 1, 10) + "%".ЛЕВОЕ СОЕДИНЕНИЕ виртуальной таблицы движений с нашей временной таблицей. В условии соединения проверяем, что поле Содержание таможенного документа начинается со значения шаблона.Важно: Соединение больших таблиц по условию ПОДОБНО исключает возможность использования индексов на уровне СУБД (Hash Join или Merge Join) и приводит к полному сканированию данных (Nested Loop). При работе с большими объемами информации рекомендуется заранее выносить ключевые реквизиты (номера ящиков, артикулы, партии) в отдельные реквизиты документов или субконто.
Рассмотрим сопутствующую проблему, часто возникающую при подготовке отчетов по проводкам: необходимость собрать обороты за прошлые периоды (до начала отчета) и обороты за текущий период, если по счету используется оборотное субконто (например, Статьи затрат).
По субконто с признаком «Только обороты» регистр бухгалтерии не хранит остатков, поэтому таблицы Остатки и ОстаткиИОбороты не содержат данных в разрезе этой аналитики. При попытке связать две таблицы оборотов через ПОЛНОЕ СОЕДИНЕНИЕ только по первому субконто (например, Объект строительства) возникает декартово произведение, из-за чего суммы по статьям затрат задваиваются.
Для корректного сведения таких данных используется конструкция ОБЪЕДИНИТЬ ВСЕ с последующей группировкой или разделением по колонкам:
ВЫБРАТЬ
ТиповойОбороты.Субконто1 КАК ОбъектСтроительства,
ТиповойОбороты.Субконто2 КАК СтатьяЗатрат,
СУММА(ТиповойОбороты.СуммаОборотДт) КАК ОборотДоПериода,
0 КАК ОборотЗаПериод
ИЗ
РегистрБухгалтерии.Типовой.Обороты(&НачПериодаОбороты, &КонПериодаОбороты, , Счет = &Счет, &ВидыСубконто, , , ) КАК ТиповойОбороты
СГРУППИРОВАТЬ ПО
ТиповойОбороты.Субконто1,
ТиповойОбороты.Субконто2
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ТиповойОбороты.Субконто1,
ТиповойОбороты.Субконто2,
0,
СУММА(ТиповойОбороты.СуммаОборотДт)
ИЗ
РегистрБухгалтерии.Типовой.Обороты(&НачПериода, &КонПериода, , Счет = &Счет, &ВидыСубконто, , , ) КАК ТиповойОбороты
СГРУППИРОВАТЬ ПО
ТиповойОбороты.Субконто1,
ТиповойОбороты.Субконто2
При использовании такого запроса в Системе компоновки данных (СКД) поля ресурсов автоматически агрегируются и выводятся в единую строку отчета по каждому объекту и каждой статье затрат без дублирования.