Простой отчёт СКД с дополнительным набором данных, получаемых по com. соединению из другой базы
Пример простого формирования отчёта на СКД, который дополнительно может подтянуть данные из другой базы в случае, когда часть данных содержится в одной ИБ, а часть – в другой и необходимо получить общий итог по ним.
Небольшая предыстория: в течение года был выполнен переход с одной конфигурации на другую, и в конце года, при формировании годовой отчетности по оплатам контрагентам, потребовалось получать данные (об оплатах) из обеих систем.
Все справочники (контрагенты, договоры, прочие НСИ) были перегружены, с сохранением связи (по УИДу) с ранее использовавшейся системой.
Никакого практического смысла грузить в новую систему несколько десятков тысяч документов по оплатам (а с ними все движения и взаимосвязанные документы) не было. Слишком большой объём данных и работы для не частого формирования одного отчёта.
Вариант предложить пользователю сформировать отчет в отдельных системах и просуммировать итоговые значения даже не рассматривался, так как показателей, которые необходимо рассчитать, в отчёте делено не 2-3, и даже не 20, а в разы больше – многовато для ручного пересчёта, не говоря уже о том, что таким образом сверить детализацию по оплатам по десяткам тысяч контрагентов просто невозможно.
Отсюда и родился отчёт, сильно упрощенная версия которого представлена в этой статье.
Итак, для примера, рассмотрим следующую задачу:
1. В двух системах (пусть будет «старая» и «новая») есть идентичные справочники контрагентов, и в этих же двух системах у каждого контрагента идентичный список договоров (в нашем случае, в новой системе перечень договоров может быть больше, но точно не меньше);
2. В этих же двух системах в течение года выполнялись оплаты по указанным договорам.
3. Необходимо сформировать отчёт, который покажет все договора контрагентов и итоговую сумму оплат по ним в течение всего года (с возможностью узнать из чего сложилась итоговая сумма).
Данный отчёт сформирован на СКД, в качестве набора данных используется «Объединение», «Запрос» и «Объект». Можно, кстати, как вариант использовать только «Объект» и положить туда сразу данные из обеих систем, но в перспективе этот же отчёт будет использоваться для получения данных только из новой базы, и тогда можно будет оставить только «Запрос».
Итак, порядок формирования отчёта был такой:
1. Формируется отчёт СКД, в котором добавляется новый набор данных – «Запрос». Порядок формирования наборов данных не так принципиален, но на мой взгляд, с запроса начинать проще, чтобы уже точно знать, как далее должны быть названы все поля, какие будут у них типы и т.д. Это, конечно же, не значит, что далее он не будет корректироваться, но, когда есть какая-то база, уже легче.
В нашем примере это будет простейший запрос: Контрагент – Договор – Документ «Списание с расчетного счета». Перечень контрагентов и даты списаний с расчетного счёта ограничим параметрами.
Также, для упрощения, данные по оплатам в данном примере выбираются не из регистра, а напрямую из документа «Списание с расчётного счета». Структура регистра в каждой базе может значительно отличаться, документ же более-менее идентичный по основным реквизитам.
2. Далее выполняется настройка ресурсов, параметров и др., как при обычном формировании отчёта.
Дополнительно добавляем новый параметр «ДобавитьДанныеИзСтаройБазы», тип – Булево. Он позволит по желанию подключать или отключать получение данных из старой базы. Этап не обязательный если, например, данные из другой базы должны добавляться всегда.
3. Затем, после того, как запрос полностью отлажен и проверен, формируется новый набор данных – «Объект». Для набора данных указывается имя таблицы значений, в которой будут лежать данные из внешней системы (в данном случае - «ДанныеИзВИБ»), а также, описывается каждое поле и его тип. Если необходимо, чтобы данные были объединены с данными из текущей базы, то поля должны называться также, как и в наборе данных «Запрос» и у них должны быть такие же типы.
4. В случае, если это необходимо, добавляется ещё один набор данных – «Объединение», куда переносятся оба набор данных (и запрос, и объект), это позволит объединить данные из двух баз везде, где это возможно.
5. Теперь необходимо сформировать таблицу значений с данными из старой базы. Для этого в модуле объекта, в процедуре «ПриКомпоновкеРезультата» определяется внешний набор данных, который далее передаётся в качестве параметра при инициализации отчёта.
В данном примере получение данных вынесено в отдельную функцию «ПолучитьДанныепоОтчету», где и выполняется формирование таблицы значений (аналогичной той, что создана в наборе данных «Объект») и заполнение данных из старой базы. В данную функцию передаются все значения параметров отчёта, необходимые для получения данных.
5.1. В функции первым шагом формируется новая таблица значений, описываются все поля и типы, один в один, как в наборе данных:
5.2. Далее, выполняется проверка параметра и, если необходимо добавить данные из другой базы, выполняется подключение в другой базе:
5.3. Если соединение успешно установлено – определяем параметры на стороне другой базы. С примитивными типами проблем нет, а вот любые ссылочные типы, перечисление, предопределенные значения справочников необходимо предварительно определить на стороне другой базы. В нашем случае сделали отбор по конкретным контрагентам и т.к. есть информация по соответствию объектов по УИД (РС ОбработанныеОбъектыБД), можно на стороне старой базы получить все эти же элементы запросом:
Аналогично определяются все параметры, которые необходимы для дальнейшего формирования таблицы значений на стороне другой базы – все ссылочные типы, а также массивы, списки значений и т.п. должны быть COM-объектами, т.е. должны быть предварительно сформированы на стороне COM-базы.
5.4. После того, как список параметров будет сформирован, можно выполнять сам запрос. Для ссылочных типов, которые дальше предполагается обработать на нашей стороне (напр., Договор), выбираем ссылку, а для списания, например, выводим представление (т.к. на стороне новой базы этого документа не существует, а включить в отчёт COM-объект нельзя).
Теперь необходимо поместить результат запроса в таблицу значений. «Выгрузить» не подойдёт, так как в результате получится COM-объект, а нам нужна именно таблица значений.
Поэтому копируем ранее созданную таблицу значений и заполняем её данными. Добавляем и заполняем новую колонку «ДогУИД» - куда будем помещать идентификатор договора, чтобы потом найти его на стороне нашей базы. В данной таблице уже не должно быть COM-объектов, только примитивные типы или ссылки из текущей базы.
5.5. Осталось сопоставить договор из старой базы с договором из новой базы (если есть необходимость). В данном случае сделали это через доп. запрос к этой таблице значений и получения данных по договору из регистра, где хранятся связи объектов.
Заполняем итоговую таблицу значений и возвращаем её для формирования отчёта:
6. Выполняем настройки отчёта (группировки, и др.) и в итоге, после объединения данных из двух баз получается примерно такая картина:
Для одного договора и контрагента собраны документы «Списание с расчетного сета» из двух баз, итоговая сумма – в целом по договору. Из внешней базы документ – только строка, из текущей базы – ссылка.
А в дальнейшем, когда данные необходимо будет формировать только из одной базы, можно будет просто взять и отключить второй запрос.
Надеюсь, кому-нибудь окажется полезным.
Внешний отчёт тестировался на платформе 1С:Предприятие 8.3 (8.3.21.1622), под конфигурацией 1С Управление холдингом, редакция 3.1 (3.1.6.15).
Проверено на следующих конфигурациях и релизах:
- 1С:Управление холдингом 3.2 (русский и английский интерфейсы), релизы 3.2.9.2