Перенос данных из устаревших конфигураций 1С 7.7 в современные решения на платформе 8.3 — задача, с которой рано или поздно сталкивается любой разработчик. Часто штатные правила конвертации не подходят под специфические доработки базы или просто отказываются работать из-за различий в релизах. В таких случаях наиболее надежным и гибким инструментом становится самостоятельное написание внешней обработки, использующей механизм COM-соединения. Рассмотрим подробно, как реализовать этот процесс, разобрав технические нюансы взаимодействия двух разных поколений платформ.
Первым шагом в нашей работе будет создание программного интерфейса для управления базой-источником. В отличие от 1С 8.x, где используется COMConnector, в "семерке" мы работаем через OLE-автоматизацию. Проанализируем базовый код инициализации соединения:
// Создаем объект приложения 1С 7.7
v7 = Новый COMObject("v77.Application");
// Формируем строку запуска: путь к базе, монопольный режим, пропуск заставки
ПутьКБазе = "D:\Bases\OldBase\";
ПараметрыЗапуска = "/D""" + ПутьКБазе + """ /M";
Открыта = v7.Initialize(v7.RMTrade, ПараметрыЗапуска, "NO_SPLASH_SHOW");
Если Открыта Тогда
Сообщить("Соединение успешно установлено!");
Иначе
Сообщить("Не удалось подключиться к базе 7.7");
КонецЕсли;
Важный нюанс: Платформа 7.7 является 32-битной. Если вы запускаете этот код на 64-битном сервере 1С или в 64-битном клиентском приложении, вы получите ошибку "Класс не зарегистрирован". Для решения этой проблемы необходимо либо использовать 32-битный клиент 1С 8.3, либо настраивать COM+ приложение в Windows (обертку) для библиотеки v77.Application.
После успешной инициализации мы получаем доступ к метаданным базы-источника. Рассмотрим, как программно обратиться к справочнику и перебрать его элементы. Выясним причину, по которой многие новички застревают на этапе отладки: отладчик 1С 8.3 не может отобразить внутреннюю структуру COM-объекта 7.7. В окне "Вычислить выражение" вы увидите лишь тип "COMОбъект". Это нормально, доступ к свойствам осуществляется напрямую через точку, даже если они не подсвечиваются системой.
// Создаем объект справочника Контрагенты
КонтрагентСОМ = v7.CreateObject("Справочник.Контрагенты");
// Начинаем выборку всех элементов
КонтрагентСОМ.ВыбратьЭлементы();
Пока КонтрагентСОМ.ПолучитьЭлемент() = 1 Цикл
// Пропускаем группы, если нужны только элементы
Если КонтрагентСОМ.ЭтоГруппа() = 1 Тогда
Продолжить;
КонецЕсли;
// Пропускаем помеченные на удаление
Если КонтрагентСОМ.ПометкаУдаления() = 1 Тогда
Продолжить;
КонецЕсли;
// Читаем основные данные
Наименование = СокрЛП(КонтрагентСОМ.Наименование);
ПолнНаименование = СокрЛП(КонтрагентСОМ.ПолнНаименование);
// Пример обращения к подчиненным структурам
// В некоторых конфигурациях ИНН хранится в подчиненном объекте ЮрФизЛицо
Попытка
ИНН_Значение = СокрЛП(КонтрагентСОМ.ЮрФизЛицо.ИНН);
Исключение
ИНН_Значение = СокрЛП(КонтрагентСОМ.ИНН);
КонецПопытки;
КонецЦикла;
В старых конфигурациях (например, "Комплексная 7.7") ИНН и КПП часто хранились в одной строке через разделитель (косую черту или пробел). Рассмотрим алгоритм, который позволяет корректно разделить эти данные для записи в карточку контрагента в 1С 8.3. Разберем по шагам функцию парсинга:
Процедура РазделитьИННКПП(Знач ВходнаяСтрока, ИНН, КПП)
ИНН = "";
КПП = "";
ВходнаяСтрока = СокрЛП(ВходнаяСтрока);
СтрДл = СтрДлина(ВходнаяСтрока);
НомРазд = 0;
// Извлекаем цифры ИНН до первого нецифрового символа
Для к = 1 по СтрДл Цикл
ТекСимв = Сред(ВходнаяСтрока, к, 1);
Если Найти("1234567890", ТекСимв) = 0 Тогда
НомРазд = к;
Прервать;
КонецЕсли;
ИНН = ИНН + ТекСимв;
КонецЦикла;
Если НомРазд = 0 Тогда
Возврат; // КПП отсутствует
КонецЕсли;
// Извлекаем цифры КПП после разделителя
Для к = (НомРазд + 1) по СтрДл Цикл
ТекСимв = Сред(ВходнаяСтрока, к, 1);
Если Найти("1234567890", ТекСимв) = 0 Тогда
Прервать;
КонецЕсли;
КПП = КПП + ТекСимв;
КонецЦикла;
КонецПроцедуры
При получении данных из 7.7 всегда используйте функцию СокрЛП(), так как строковые типы в "семерке" имеют фиксированную длину и часто дополняются пробелами справа.
Проанализируем ситуацию, когда данные (например, юридический адрес или цена) являются периодическими. В 1С 7.7 вы не сможете получить их простым обращением к реквизиту через COM. Для этого нужно использовать вспомогательный объект Периодический. Посмотрим на пример кода:
ОбъектПериодический = v7.CreateObject("Периодический");
// Указываем, какой реквизит какого объекта нам нужен
ОбъектПериодический.ИспользоватьОбъект("ЮридическийАдрес", КонтрагентСОМ.ТекущийЭлемент());
// Получаем значение на нужную дату
АдресНаДату = ОбъектПериодический.ЗначениеНа(ТекущаяДата());
Работа через COM-соединение потребляет значительные ресурсы оперативной памяти, так как фактически запускается экземпляр приложения 1С 7.7 в скрытом режиме. Чтобы избежать "зависания" процессов в диспетчере задач, после выполнения переноса необходимо правильно закрыть соединение. Проанализируем правильную последовательность действий:
Неопределено.
// Очистка
КонтрагентСОМ = Неопределено;
// Если использовались другие объекты - их тоже в Неопределено
v7 = Неопределено;
// Вызываем сборку мусора, если это критично для системы
СредстваКлиента.ОчиститьПамять(); // (Условно)
Практический совет: Если объем данных велик (десятки тысяч контрагентов), не пытайтесь перенести всё за один раз. Разбейте процесс на части или используйте промежуточную выгрузку в XML/Excel. Это убережет вас от переполнения памяти и позволит легче локализовать ошибки в данных конкретных элементов справочника.
Использование COM-соединения — это мощный способ разового переноса данных, когда стандартные инструменты пасуют перед сложностью конфигурации. Несмотря на "капризность" технологии OLE, при соблюдении правил типизации и очистки памяти, она позволяет с ювелирной точностью перенести накопленную за годы информацию в новую современную систему.