Андрей Луконькин
Перенос данных с использованием технологии OLE
Не за горами новый год, а это значит, что во многих фирмах планируется перевод автоматизированного учета либо на новый качественный уровень, либо в новую чистую базу данных. Как правило, переносятся только справочники и остатки по счетам и регистрам. Существует много способов подобного переноса данных, и каждый выбирает тот, который ему пришелся по нраву, но сейчас я хочу рассказать о применении технологии OLE к данной проблеме.
Сразу хочу сказать, что полный программный код всех обработок печатать бессмысленно из-за достаточно большого объема. На примере одной обработки я покажу основные принципы работы и расскажу свой ход мысли. Готовые обработки можно найти на сайте журнала www.samag.ru в разделе «Исходный код».
Рассмотрим типовой случай перехода с платформы «1С:Предприятие» версии 7.7 на версию 8.1 с нового года.
Задача: перенести справочники «Контрагенты» и «Договора», а также остатки взаиморасчетов по счету 60 из «старой» базы в «новую». До перехода предприятие работало с конфигурацией «Производство + Услуги + Бухгалтерия» (платформа 7.7), после перехода собирается работать с конфигурацией «Управление производственным предприятием» (платформа 8.1).
Разделим задачу на две. Первая – перенос справочников, вторая – перенос остатков по счетам.
При переносе справочников создадим дополнительную структуру (регистр сведений), который будет использоваться для поиска и точной идентификации перенесенных объектов в базе данных. Назовем этот регистр «СтруктураПерегрузки», первое измерение будет «ИД» (строка, длина 150), второе – «Орг» (для случая многофирменного учета), ресурс «Элемент» составного типа данных, включающий в себя все справочники, которые мы собираемся заполнять переносом данных.
При загрузке справочников, кроме записи самих элементов, будет заполняться и этот регистр сведений примерно следующим образом:
Спр8 = Справочники.Контрагенты.СоздатьЭлемент();
Спр8.Наименование = Спр77.Наименование;
Спр8.Записать();
Рег = РегистрыСведений.СтруктураПерегрузки.СоздатьМенеджерЗаписи();
Рег.Ид = Семерка.ЗначениеВСтрокуВнутр(Спр77.текущийэлемент());
Рег.Орг = Орг.Ссылка;
Рег.Элемент = Спр8.Ссылка;
Рег.Записать();
Будем считать этап загрузки справочников подготовительным, перейдем к более подробному рассмотрению переноса данных о задолженности контрагентов.
Создадим внешнюю обработку, разместим на форме переключатель для выбора субсчета 60-го счета, а также дату итогов и дату создаваемой операции (см. рисунок).
Форма обработки загрузки данных во взаиморасчетах
В процедуре «КнопкаСформироватьНажатие» разместим весь необходимый текст программы.
Сначала подключимся через OLE к той базе данных, из которой будем брать данные:
КаталогПрограммы77 = "C:\Program Files\1Cv77\BIN\";
КаталогБазы77 = "C:\1c_base\ПУБ\";
СтрокаПодключения = """" + КаталогПрограммы77 + """" + "enterprise /d""" + КаталогБазы77 + """" + " /nЮзер /p123";
Семерка = Новый COMОбъект("V77S.Application");
Если Семерка.Initialize(Семерка.RMTrade,СтрокаПодключения,"NO_SPLASH_SHOW") Тогда
Сообщить("Открыта база 7.7");
Соединение=Истина;
КонецЕсли;
Каталоги программы и базы данных можно прописать в самом модуле, а можно и сделать интерактивный выбор на форме. Строка подключения собирается из каталога запуска программы, режима запуска, каталога базы данных, имени пользователя и пароля. В данном случае имя пользователя «Юзер», пароль «123».
Далее производим подключение, причем с параметром NO_SPLASH_SHOW, это означает, что запуск базы будет происходить без демонстрации заставки, т.е. практически незаметно для пользователя.
ИНН = Лев(Семерка.Константа.ИННОрганизации,10);
Орг = Справочники.Организации.НайтиПоРеквизиту("ИНН",ИНН);
Опер = Документы.ОперацияБух.СоздатьДокумент();
Опер.Организация = Орг.Ссылка;
Опер.Дата = ДатаОперации;
Определяем по ИНН организацию, по которой хотим выполнить загрузку, и создаем новый документ «Операция».
БИ77 = Семерка.CreateObject("БухгалтерскиеИтоги");
ОлеВидСубконто1=Семерка.EvalExpr("ВидыСубконто.Контрагенты");
ОлеВидСубконто2=Семерка.EvalExpr("ВидыСубконто.Договоры");
Замечу, что создание объектов в подключаемой по OLE-базе происходит с помощью англоязычного синонима CreateObject, а не «СоздатьОбъект». Метод EvalExpr также часто используется при работе с технологией OLE, означает вычисление выражения системы.
Если Счет60=1 Тогда
Счет = ПланыСчетов.Хозрасчетный.РасчетыСПоставщиками;
СчетСтр = "60.1";
ИначеЕсли Счет60=2 Тогда
Счет = ПланыСчетов.Хозрасчетный.РасчетыПоАвансамВыданным;
СчетСтр = "60.2";
ИначеЕсли Счет60=3 Тогда
Счет = ПланыСчетов.Хозрасчетный.РасчетыСПоставщикамиВал;
СчетСтр = "60.11";
ИначеЕсли Счет60=4 Тогда
Счет = ПланыСчетов.Хозрасчетный.РасчетыПоАвансамВыданнымВал;
СчетСтр = "60.22";
КонецЕсли;
Здесь всё достаточно ясно, происходит определение счета взаиморасчетов в зависимости от установленного переключателя на форме.
БИ77.ИспользоватьСубконто("Контрагенты");
БИ77.ИспользоватьСубконто("Договоры");
БИ77.ВыполнитьЗапрос(ДатаИтогов,ДатаИтогов,СчетСтр);
БИ77.ВыбратьСубконто(1);
В подключенной базе выполняем запрос по бухгалтерским итогам на дату, выбранную на форме обработки.
Пока БИ77.ПолучитьСубконто(1)=1 цикл
БИ77.ВыбратьСубконто(2);
ИД = Семерка.ЗначениеВСтрокуВнутр(БИ77.Субконто(1));
Рег = РегистрыСведений.СтруктураПерегрузки;
ОтборПоИД = Новый Структура("ИД, Орг");
ОтборПоИД.ИД = ИД;
ОтборПоИД.Орг = Орг.Ссылка;
ВыборкаИД = рег.Получить(ОтборПоИД);
Суб1 = ВыборкаИД.Элемент.Ссылка;
Начинаем цикл по первому субконто (Контрагенты). Из регистра сведений получаем ссылку на нужный элемент справочника. Вот тут и начинает работать созданный нами механизм. Идентификация происходит не по коду, не по наименованию, не по какому-либо другому реквизиту, а по уникальному внутреннему идентификатору объекта.
Пока БИ77.ПолучитьСубконто(2)=1 цикл
ДебетовоеСальдо = БИ77.скд(1);
КредитовоеСальдо = БИ77.скк(1);
Если ДебетовоеСальдо<>0 Тогда
ИД = Семерка.ЗначениеВСтрокуВнутр(БИ77.Субконто(2));
Рег = РегистрыСведений.СтруктураПерегрузки;
ОтборПоИД = Новый Структура("ИД, Орг");
ОтборПоИД.ИД = ИД;
ОтборПоИД.Орг = Орг.Ссылка;
ВыборкаИД = рег.Получить(ОтборПоИД);
Элемент8 = ВыборкаИД.Элемент.Ссылка;
Движ = Опер.Движения.Хозрасчетный.Добавить();
Движ.СчетДт = Счет.Ссылка;
Движ.СубконтоДт.Вставить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты,Элемент8.Владелец);
Движ.СубконтоДт.Вставить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры,Элемент8);
Движ.СчетКт = ПланыСчетов.Хозрасчетный.Вспомогательный;
Движ.Сумма = ДебетовоеСальдо;
Движ.Активность=Истина;
Движ.Период = ДатаОперации;
Опер.Движения.Хозрасчетный.Записать();
ИначеЕсли КредитовоеСальдо<>0 тогда
ИД = Семерка.ЗначениеВСтрокуВнутр(БИ77.Субконто(2));
Рег = РегистрыСведений.СтруктураПерегрузки;
ОтборПоИД = Новый Структура("ИД, Орг");
ОтборПоИД.ИД = ИД;
ОтборПоИД.Орг = Орг.Ссылка;
ВыборкаИД = рег.Получить(ОтборПоИД);
Элемент8 = ВыборкаИД.Элемент.Ссылка;
Движ = Опер.Движения.Хозрасчетный.Добавить();
Движ.СчетКт = Счет.Ссылка;
Движ.СубконтоКт.Вставить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты,Элемент8.Владелец);
Движ.СубконтоКт.Вставить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры,Элемент8);
Движ.СчетДт = ПланыСчетов.Хозрасчетный.Вспомогательный;
Движ.Сумма = КредитовоеСальдо;
Движ.Активность=Истина;
Движ.Период = ДатаОперации;
Опер.Движения.Хозрасчетный.Записать();
КонецЕсли;
КонецЦикла;
КонецЦикла;
По каждому договору определяем задолженность, и в зависимости от знака («+» или «-») формируем движения документа «Операция».
Опер.Записать();
Семерка="";
Соединение=Ложь;
Сообщить("Закрыта база 7.7");
Записываем созданный документ, закрываем соединение программно. На этом работа программиста заканчивается, остается только бухгалтеру сверить суммы в «старой» и «новой» программе.
В случае с другими счетами, возможно, понадобится создание и других документов. Например, по основным средствам организации необходим документ «ВводНачальныхОстатковОС». Но, используя уже имеющиеся наработки, создать что-то своё, индивидуальное, гораздо проще.
В заключение хочется сказать о некоторых распространенных трудностях, возникающих при работе с OLE.
Для обращения к перечислениям используется конструкция типа:
ЗначПеречисленияOLE = Объект77.Реквизит.Идентификатор();
«ЗначПеречисленияOLE» будет содержать строку со значением перечисления. Обращаться к процедурам глобального модуля можно следующим образом:
ТЗ = Семерка.глРасчетАмортизацииОС(Спр77.ТекущийЭлемент(), ДатаФормирования);
Остается только пожелать удачи в решении проблем и в освоении новых методов выполнения поставленных задач!