В практике разработки на платформе 1С программисты часто сталкиваются с ситуацией, когда данные во временных таблицах (ВТ) определенно есть, но итоговый результат соединения этих таблиц оказывается пустым или неполным. Это классическая проблема, которая может быть вызвана как логикой работы СУБД, так и спецификой самой платформы. Разберем подробно, почему так происходит и какие методы позволяют гарантированно получить все необходимые записи.
Рассмотрим типичную ситуацию. У нас есть две временные таблицы: втКлиенты (данные по заказам) и ВТПроизводство (данные по выпуску продукции). Мы пытаемся связать их по полям ЗаказКлиента и Номенклатура, используя ЛЕВОЕ СОЕДИНЕНИЕ. Если мы ожидаем увидеть все заказы и привязанные к ним выпуски, но часть строк исчезает, причина обычно кроется в одном из следующих аспектов:
NULL), соединение не сработает.КодСтроки часто приводит к тому, что записи не сопоставляются, если в одном из документов этот код заполнен иначе.NULL, вся строка будет отсечена, если данных во второй таблице не нашлось.Если нам нужно получить абсолютно все записи из обеих таблиц, независимо от того, есть ли для них пара в другой таблице, необходимо использовать ПОЛНОЕ СОЕДИНЕНИЕ. В этом случае, если запись есть в первой таблице, но нет во второй (или наоборот), система все равно выведет строку, заполнив отсутствующие значения значением NULL.
Рассмотрим пример правильного подхода с проверкой на NULL:
ВЫБРАТЬ
ЕСТЬNULL(втКлиенты.ЗаказКлиента, ВТПроизводство.ЗаказКлиента) КАК ЗаказКлиента,
ЕСТЬNULL(втКлиенты.Номенклатура, ВТПроизводство.Номенклатура) КАК Номенклатура,
ЕСТЬNULL(втКлиенты.Заказано, 0) КАК Заказано,
ЕСТЬNULL(ВТПроизводство.ПланКолво, 0) КАК ПланКолво
ИЗ
втКлиенты КАК втКлиенты
ПОЛНОЕ СОЕДИНЕНИЕ ВТПроизводство КАК ВТПроизводство
ПО втКлиенты.ЗаказКлиента = ВТПроизводство.ЗаказКлиента
И втКлиенты.Номенклатура = ВТПроизводство.Номенклатура
Важный нюанс: при полном соединении ключевые поля (Заказ, Номенклатура) обязательно нужно оборачивать в функцию ЕСТЬNULL, выбирая данные из той таблицы, где они заполнены. Иначе в результате вы получите пустые ячейки в ключевых колонках.
В среде 1С профессиональным стандартом для объединения данных из нескольких источников считается метод «Объединить все + Группировка». Этот способ часто работает быстрее полного соединения и позволяет избежать сложных условий связи.
Проанализируем шаги реализации этого метода:
ОБЪЕДИНИТЬ ВСЕ) с выборкой из второй таблицы, добавляя пустые колонки для данных из первой.СУММИРОВАНИЕМ ресурсов и ГРУППИРОВКОЙ по измерениям.Пример реализации:
ВЫБРАТЬ
Т.ЗаказКлиента,
Т.Номенклатура,
СУММА(Т.Заказано) КАК Заказано,
СУММА(Т.ПланКолво) КАК ПланКолво
ИЗ
(ВЫБРАТЬ
втКлиенты.ЗаказКлиента КАК ЗаказКлиента,
втКлиенты.Номенклатура КАК Номенклатура,
втКлиенты.Заказано КАК Заказано,
0 КАК ПланКолво
ИЗ
втКлиенты КАК втКлиенты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ВТПроизводство.ЗаказКлиента,
ВТПроизводство.Номенклатура,
0,
ВТПроизводство.ПланКолво
ИЗ
ВТПроизводство КАК ВТПроизводство) КАК Т
СГРУППИРОВАТЬ ПО
Т.ЗаказКлиента,
Т.Номенклатура
Этот метод гарантирует, что ни одна запись не будет потеряна из-за отсутствия пары в другой таблице или из-за проблем с NULL в условиях связи.
Проанализируем дополнительные факторы, которые могут влиять на результат запроса:
1. Индексация временных таблиц. При выполнении любых соединений (левых, внутренних, полных) крайне важно индексировать поля связи. Если у вас ВТПроизводство соединяется по полям ЗаказКлиента и Номенклатура, добавьте в описание этой ВТ команду ИНДЕКСИРОВАТЬ ПО ЗаказКлиента, Номенклатура. Это значительно ускорит работу и исключит ошибки построения планов запросов СУБД.
2. Проблема «Кода строки». В типовых конфигурациях (ERP, УТ 11) поле КодСтроки используется для разделения одинаковой номенклатуры в одном документе. Если вы соединяете таблицы по этому полю, убедитесь, что оно заполнено в обоих источниках. Часто в регистрах оборотов КодСтроки может быть равен 0, в то время как в документе он заполнен. В таких случаях соединение по этому полю лучше исключить, предварительно сгруппировав данные по номенклатуре.
3. Неявное приведение типов. Если в одной таблице ЗаказКлиента получен из объектной таблицы (Документ.ЗаказКлиента), а в другой через обращение к реквизиту другого документа (например, ЗаказНаПроизводство.ДокументОснование), типы могут не совпасть, если основание имеет составной тип. Попробуйте явно привести типы с помощью ВЫРАЗИТЬ(Поле КАК Документ.ЗаказКлиента).
4. Работа с виртуальными таблицами. При использовании таблицы Обороты старайтесь накладывать условия не в секции ГДЕ, а в параметрах самой виртуальной таблицы. Это работает стабильнее и быстрее. Например:
ИЗ РегистрНакопления.ЗаказыКлиентов.Обороты(&НачалоПериода, &КонецПериода, Авто, ЗаказКлиента В (&МассивЗаказов)) КАК Заказы
Разберем итог: если данные пропадают при соединении, первым делом проверьте типы связующих полей. Если логика задачи подразумевает наличие данных хотя бы в одном из источников — используйте ОБЪЕДИНИТЬ ВСЕ с последующей группировкой. Это самый надежный способ избежать «магического» исчезновения строк в отчетах.