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