Как соединить две таблицы без общих полей в запросе СКД 1С

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

При разработке отчетов в системе 1С на базе схемы компоновки данных (СКД) или обычных запросов часто возникает задача: вывести в каждой строке основной таблицы одно общее значение из второй таблицы. Например, нам необходимо выгрузить обороты по контрагентам и договорам с определенного счета и к каждой строке добавить количество дней за период, рассчитанное по производственному календарю.

Разберем по шагам, каким образом можно объединить такие данные в одном запросе или в настройках наборов данных СКД.

Способ 1. Соединение таблиц по условию ИСТИНА

Рассмотрим случай, когда у нас есть две таблицы, не имеющие общих ключевых полей (таких как контрагент или договор). В языке запросов 1С для соединения каждой строки первой таблицы с единственной строкой второй таблицы используется левое соединение по произвольному условию ПО (ИСТИНА).

Проанализируем пример кода запроса, где мы выбираем данные из виртуальной таблицы Хозрасчетный.ОстаткиИОбороты и присоединяем количество дней из регистра сведений ДанныеПроизводственногоКалендаря:


ВЫБРАТЬ
	ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Контрагент,
	ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Договор,
	ХозрасчетныйОстаткиИОбороты.СуммаОборотКт КАК СуммаЗайма,
	ЕСТЬNULL(ВТ_КоличествоДней.КоличествоДней, 0) КАК КоличествоДней
ИЗ
	РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , Счет В ИЕРАРХИИ (&Счет), , ) КАК ХозрасчетныйОстаткиИОбороты
		ЛЕВОЕ СОЕДИНЕНИЕ (
			ВЫБРАТЬ
				КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДанныеПроизводственногоКалендаря.Дата) КАК КоличествоДней
			ИЗ
				РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
			ГДЕ
				ДанныеПроизводственногоКалендаря.Дата МЕЖДУ &НачалоПериода И &КонецПериода
		) КАК ВТ_КоличествоДней
		ПО (ИСТИНА)

При использовании конструктора запроса в 1С настройка выполняется следующим образом:

  1. Переходим на вкладку Связи.
  2. Добавляем связь между основной таблицей и таблицей подсчета дней.
  3. Указываем тип соединения: Левое соединение.
  4. Включаем флаг Произвольное условие (флаг П в конструкторе) и в тексте условия указываем ИСТИНА.

Способ 2. Вложенный запрос в секции ВЫБРАТЬ

Посмотрим на другой вариант решения задачи. Если присоединяемая таблица гарантированно возвращает ровно одну строку и одну колонку (скалярное значение), вычисление можно поместить прямо в список выбираемых полей основного запроса:


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

Этот подход избавляет от необходимости писать явную секцию соединения и делает запрос более компактным.

Способ 3. Вычисление параметров и вычисляемых полей в СКД

Если требуется посчитать общее количество дней за период без обращения к производственному календарю или вынести логику в механизмы компоновки, соединение таблиц в запросе не требуется. Рассмотрим альтернативные инструменты СКД:

  1. Выражение в Параметрах СКД: На вкладке Параметры можно создать или настроить пользовательский параметр и задать для него выражение вычисления количества дней с помощью функций СКД:

    РазностьДат(&НачалоПериода, КонецПериода(&КонецПериода, "День"), "ДЕНЬ") + 1

  2. Вычисляемые поля: На вкладке Вычисляемые поля можно добавить поле КоличествоДней и в выражении вызвать экспортируемую функцию общего модуля конфигурации, передав в нее параметры периода.

Важные рекомендации и подводные камни

Проанализируем нюансы, на которые следует обратить внимание при реализации таких запросов:

  1. Обработка значений NULL: Если за выбранный период в регистре ДанныеПроизводственногоКалендаря отсутствуют записи (например, календарь на следующий год еще не заполнен), левое соединение вернет NULL. Оборачивайте выбираемое значение в функцию ЕСТЬNULL(Поле, 0).
  2. Опасность дублирования строк: Условие соединения ПО (ИСТИНА) выполняет декартово произведение. Если присоединяемая таблица вернет более одной строки, каждая строка отчета продублируется. Следите за тем, чтобы в присоединяемом запросе всегда использовались агрегатные функции (КОЛИЧЕСТВО, СУММА) или группировка.
  3. Отбор по счету: Не рекомендуется жестко прописывать код счета в запросе вида Счет.Код = "66.23". Передавайте счет через параметр Счет В ИЕРАРХИИ (&Счет) или используйте системные предопределенные значения, например ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыПоКраткосрочнымЗаймам).
← На главную