Перенос данных между информационными базами 1С:Предприятия v7.7 средствами OLE-Automation

При разработке и эксплуатации конфигураций 1С:Предприятия часто встаёт задача переноса различных данных (документов и элементов справочников) между информационными базами. При этом конфигурации информационных баз, между которыми следует настроить обмен данными, могут существенно различаться. Часто появляется необходимость в процессе переноса превратить документы одного вида в документы совершенно другого вида. Примером может послужить перенос документов "из торговли в бухгалтерию", когда приходная накладная торговой конфигурации должна быть перенесена в бухгалтерскую конфигурацию в виде операции с проводками.

Автор: Людоговский А.И., ООО "Фирма Элли", г. Москва.
Источник: http://script-coding.info/

Скачать пример обработки (49 664 байт)

Введение

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

Одним из способов решения подобных задач является написание обработки средствами встроенного языка 1С:Предприятия, которая будет осуществлять перенос данных с использованием механизма OLE-Automation. Следует оговориться, что данный подход требует, чтобы база-приёмник и база-источник были доступны пользователю в пределах одной локальной сети. В противном случае необходимо настраивать выгрузку данных в специальный файл с их последующей загрузкой "на другой стороне", но это выходит за рамки проблем, рассматриваемых в этой статье. Предлагаемая ниже методика применима как на файловой, так и на SQL-ной версиях 1С:Предприятия, включая ситуацию, когда база-иточник и база-приёмник имеют разный формат хранения (одна DBF, другая - SQL).

Постановка задачи

Рассмотрим простой пример, когда данные мигрируют в одну сторону: из базы-источника в базу-приёмник. При этом требуется периодический запуск пользователем такой миграции при условии, что в случае повторного импорта данных в базу-приёмник за один и тот же период загруженные ранее документы должны автоматически обновляться и пополняться в соответствии с изменениями в базе-источнике.

Для простоты примера предположим, что необходимо осуществлять миграцию документов из типовой конфигурации "Бухгалтерский учет, редакция 4.5" релиза 7.70.458 в такую же конфигурацию (из дальнейшего изложения будет понятно, что "одинаковость" конфигураций не принципиальна для сути изложения материала и не противоречит целям, заявленным в начале статьи). Пусть при этом база-приёмник является базой управленческого учёта, а база-источник - базой регламентированного учёта. Будем осуществлять перенос документов двух видов:

  • Документ "Услуги сторонних организаций". Выделенный НДС в момент переноса включается в сумму, а все услуги относятся на счёт "44.1.1".
  • Документ "Ввод в эксплуатацию ОС". Каждый документ загружается как операция с проводками Д01.1-К08.4, где каждая проводка соответствует строке табличной части документа. Сумма каждой проводки равна значению реквизита "Первоначальная стоимость" шапки документа плюс НДС, рассчитываемый по ставке 20%.

В процессе переноса нам придётся синхронизировать помимо документов и некоторые справочники.

Примечание: возможно, предлагаемый пример носит немного упрощённый и надуманный характер, однако он полностью отражает суть предлагаемой методики.

Описанная далее в тексте статьи обработка доступна для скачивания. Для полного понимания того, о чём далее пойдёт речь, читателю будет необходимо в процессе чтения просматривать и анализировать код этой обработки. Обработка тестировалась на конфигурации "Бухгалтерский учет, редакция 4.5" релиза 7.70.458 (путём выгрузки данных демо-базы в пустую базу) и предназначена исключительно для иллюстрации излагаемой здесь методики. Перенос реквизитов документов и справочников реализован в обработке лишь в объёме, необходимом для иллюстрации методики, и не претендует на полноту.

Реализация

Итак, напишем обработку, которая будет запускаться на стороне базы-приёмника и осуществлять импорт данных. Выбор "стороны" запуска обусловлен тем, что запись новых и изменённых документов и справочников удобнее осуществлять в текущей информационной базе, нежели в базе, запущенной как OLE-сервер. Объясняется это тем, что в силу некоторых особенностей реализации OLE-сервера 1С:Предприятия применение транзакций на стороне OLE-сервера представляется довольно проблематичным, а без применения механизма транзакций массированная загрузка данных становится небезопасной.

Для обеспечения синхронизации документов придётся внести небольшие изменения в конфигурацию базы-приёмника. Следует добавить общий реквизит документов "GUID" (строка 20 символов, с отбором). Все записываемые в процессе загрузки документы будут получать уникальное значение этого реквизита. При повторной загрузке данных за один и тот же период загруженные ранее документы будут разыскиваться по значению этого реквизита.

Обработка должна иметь интерфейс, позволяющий помимо собственно запуска процесса импорта, указать следующие параметры:

  • Каталог базы-источника, имя пользователя в этой базе и его пароль.
  • Период загрузки данных (диапазон дат).

Алгоритм работы обработки в самых общих чертах сводится к следующему:

  1. Осуществляется подключение к базе-источнику.
  2. Осуществляется выборка и перебор документов базы-источника за указанный диапазон дат.
  3. Если очередной выбранный документ подлежит загрузке, он разыскивается в текущей базе (базе-приёмнике). Если он не найден, создаётся и записывается новый документ. Если он найден, сверяются (и при необходимости исправляются) значения реквизитов найденного документа и этот документ при необходимости перезаписывается.
  4. Каждый обработанный документ базы-источника в процессе перебора запоминается в специальном списке значений.
  5. Осуществляется выборка и перебор документов за указанный диапазон дат в текущей базе (базе-приёмнике).
  6. Если очередной выбранный документ является ранее загруженным (т.е. имеет не пустой GUID), но не принадлежит вышеупомянутому списку, он помечается на удаление.

Таким образом, в результате работы обработки, состав документов двух баз в указанном диапазоне дат оказывается полностью синхронизирован. Данный алгоритм реализован в процедуре обработки "Выполнить".

Особый интерес представляет методика розыска документа, полученного из базы-источника, в текущей базе (т.е., определения того, не был ли этот документ уже загружен ранее). Для этого с помощью функции "ПолучитьID" получается строковый GUID документа базы-источника, по которому этот документ позже и разыскивается в базе-приёмнике. Функция "ПолучитьID" достаточно проста и не требует подробных объяснений (см. код обработки и комментарии к нему). Возвращённый в результате GUID документа содержит уникальную информацию, используемую для идентификации документа в базе-источнике самой платформой 1С:Предприятия. Такой способ идентификации документа является наиболее надёжным. Примечание: при получении GUID'а используется недокументированная функция встроенного языка "_IdToStr". Кроме того, к полученному GUID'у в обработке прибавляется префикс "ЦБД-". Делается это для того, чтобы впоследствии можно было реализовать загрузку данных из нескольких баз-источников (совпадающие GUID'ы разных баз-источников можно различать по префиксам).

Когда GUID документа получен, вызывается процедура загрузки документа нужного вида (в нашем случае это "ЗагрузитьВводОС" или "ЗагрузитьУСО"), которая осуществляет поиск документа в текущей базе по его GUID'у и при необходимости модификацию документа (или создание, если документ не найден). После этого полученный ранее GUID обработанного документа запоминается в специальном списке значений. После окончания перебора документов базы-источника осуществляется перебор документов за тот же диапазон дат в текущей базе с целью отыскать документы, подлежащие удалению. Это будут документы, имеющие в реквизите "GUID" префикс "ЦБД-" (т.е. загруженные когда-то из той же самой базы-источника), но не входящие в вышеупомянутый список значений. Другими словами - это документы, которые были удалены в базе-источнике после последнего обмена данными (или перестали удовлетворять условиям выгрузки). Такие документы помечаются на удаление.

На этом описание алгоритма процедуры "Выполнить" исчерпывается.

Рассмотрим процедуры "ЗагрузитьВводОС" и "ЗагрузитьУСО". В качестве параметров процедуры получают GUID выбранного из базы-источника документа (для его поиска в текущей базе) и ссылку на этот же документ (для обращения к его реквизитам). Документ разыскивается по переданному GUID'у. Если он не найден, создаётся и записывается новый документ. Если документ найден, значения его реквизитов сверяются со значениями реквизитов документа базы-источника и при необходимости документ перезаписывается. При этом проверка на различие значений реквизитов может производиться не для всех реквизитов документа, а только для необходимых. Например, изменение реквизита "Комментарий" в обработке не отслеживается. Это означает, что после загрузки документа пользователь может "вручную" изменять значение этого реквизита, но несмотря на это, при следующей загрузке (синхронизации) данных этот документ не будет признан изменённым и соответственно не будет перезаписываться.

Некоторую сложность представляет загрузка и синхронизация справочников. В нашем примере все обрабатываемые справочники синхронизируются по коду (предполагается, что их коды уникальны). Для загрузки элементов каждого справочника описывается отдельная процедура. При установке значений тех или иных реквизитов документов процедуры "ЗагрузитьВводОС" и "ЗагрузитьУСО" вызывают соответствующую процедуру для обработки нужного справочника.

Процедура обработки справочника (например, "ОбработатьКонтрагента") получает в качестве параметра ссылку на элемент справочника базы-источника. Если справочник иерархический, такая процедура является рекурсивной, т.к. вызывает сама себя для обработки (получения) значения родителя элемента справочника. Таким образом, справочники переносятся со всеми группами и подгруппами (с сохранением иерархии базы-источника). Элемент справочника разыскивается по коду. Если он не найден, создаётся и записывается новый элемент. Если элемент найден, значения его реквизитов сверяются со значениями реквизитов элемента справочника базы-источника и при необходимости элемент справочника перезаписывается.

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

Заключение

Описанная выше методика переноса данных не претендует на универсальность в том смысле, что для того или иного переноса данных придётся каждый раз писать "свою" обработку. Однако такая методика обеспечивает наибольшую гибкость при фильтрации и переработке загружаемых данных в процессе импорта (что в некоторых случаях делает эту методику единственно возможной), а также в результате даёт удобство и простоту применения конечным пользователям.

Данная методика может применяться не только для выгрузки данных из одной информационной базы 1С:Предприятия в другую. Подобным образом можно наладить связь с 1С:Предприятием и совершенно "посторонних" программ. Например, можно строить запрос к произвольной базе данных SQL-сервера средствами ADO, а затем записывать полученные данные в 1С:Предприятии в виде документов и справочников. При этом будет необходимо лишь обеспечить уникальный идентификатор каждой полученной средствами ADO записи, который и будет заноситься в общий реквизит документов "GUID".

Скачать пример обработки (49 664 байт)

Начать дискуссию