При подготовке к переходу с платформы 1С:Предприятие 7.7 на современную версию 8.3 часто возникает необходимость подготовить данные заранее. Одной из ключевых задач является формирование уникальных идентификаторов (GUID), которые позволят однозначно сопоставить объекты при переносе. Однако программисты, привыкшие к логике 1С 8.x, часто сталкиваются с тем, что в старой версии платформы данные просто «не записываются» без видимых ошибок. Разберем подробно, почему так происходит и как правильно реализовать этот механизм.
Проанализируем ситуацию, с которой сталкиваются многие специалисты. В 1С 7.7 существует принципиальное различие между объектом справочника (созданным через СоздатьОбъект) и ссылкой на элемент. Рассмотрим фрагмент кода, который не работает:
СпрСотр = СоздатьОбъект("Справочник.Номенклатура");
СпрСотр.ВыбратьЭлементы();
Пока СпрСотр.ПолучитьЭлемент() = 1 Цикл
Спр = СпрСотр.ТекущийЭлемент(); // ОШИБКА ЗДЕСЬ
Спр.guid = "УникальныйИдентификатор";
Спр.Записать();
КонецЦикла;
Выясним причину неудачи. Метод ТекущийЭлемент() возвращает ссылку на объект в базе данных. Ссылка в 1С 7.7 предназначена исключительно для чтения данных или передачи в качестве параметра в другие функции. Она не обладает методами записи. Когда вы присваиваете значение реквизиту ссылки, платформа может не выдать ошибку выполнения, но и данные в таблицу БД не попадут. Чтобы запись прошла успешно, необходимо работать напрямую с позиционированным объектом.
Для того чтобы изменения сохранились, нам нужно использовать ту переменную, которая была инициализирована через СоздатьОбъект и на которой был вызван метод ПолучитьЭлемент(). В этот момент переменная СпрСотр уже «держит» конкретную строку справочника и готова к её модификации. Перепишем код корректно:
СпрСотр = СоздатьОбъект("Справочник.Номенклатура");
СпрСотр.ВыбратьЭлементы();
Пока СпрСотр.ПолучитьЭлемент() = 1 Цикл
// Работаем напрямую с объектом СпрСотр
СпрСотр.guid = СгенерироватьНовыйGUID(); // Ваша функция генерации
СпрСотр.Записать();
Сообщить("Записан элемент: " + СпрСотр.Наименование);
КонецЦикла;
В этом случае метод Записать() вызывается у объекта, находящегося в состоянии редактирования, и изменения успешно фиксируются в базе данных.
В платформе 7.7 нет встроенной функции Новый УникальныйИдентификатор(), как в восьмерке. Рассмотрим основные способы получения уникальных строк.
1. Использование внешних компонент. Популярным решением является компонента V7SysInfo. Однако её использование внутри цикла требует осторожности. Посмотрим на оптимизированный пример:
// Объект компоненты создаем ОДИН РАЗ до начала цикла
Инфо = СоздатьОбъект("AddIn.V7SysInfo");
СпрСотр = СоздатьОбъект("Справочник.Контрагенты");
СпрСотр.ВыбратьЭлементы();
Пока СпрСотр.ПолучитьЭлемент() = 1 Цикл
ГлобальноУникальныйИдентификатор = Инфо.СоздатьGUID();
СпрСотр.guid = ГлобальноУникальныйИдентификатор;
СпрСотр.Записать();
КонецЦикла;
2. Использование системных средств Windows (без внешних DLL). Если вы не хотите регистрировать дополнительные компоненты, можно воспользоваться COM-объектом Scriptlet.TypeLib, который есть в любой современной системе Windows. Проанализируем пример функции:
Функция ПолучитьGUID()
ТипЛиб = СоздатьОбъект("Scriptlet.TypeLib");
Возврат ВРег(Сред(ТипЛиб.Guid, 2, 36));
КонецФункции
Рассмотрим ситуацию, когда создавать новый реквизит в справочнике нежелательно (например, чтобы не менять структуру конфигурации). Каждый объект в 1С 7.7 уже имеет свой внутренний уникальный идентификатор. Его можно получить с помощью функции ЗначениеВСтрокуВнутр().
Проанализируем формат этой строки. Она выглядит примерно так: {"B","0","0","123","0","0"," 456 "}. Здесь последние символы (в примере 456) — это уникальный 13-символьный ID объекта в рамках текущей базы. Многие разработчики при миграции в 8.3 используют именно этот ID, преобразуя его в формат GUID (добавляя префиксы или дополняя нулями). Это гарантирует стабильность ссылок при повторных выгрузках без лишних затрат на хранение данных в 7.7.
Важное замечание: Если вы планируете синхронизировать данные из нескольких баз 1С 7.7, которые были созданы простым копированием файлов .dbf или .mdf, внутренние ID в них могут совпадать. В таком случае добавление префикса базы к идентификатору становится обязательным.
Запись большого количества элементов в справочнике — ресурсоемкая операция. Чтобы ускорить процесс в десятки раз, обязательно используйте транзакции. Разберем по шагам:
Записать().ЗафиксироватьТранзакцию() каждые 1000–5000 элементов, чтобы не переполнять лог транзакций в SQL-версии.Посмотрим на пример реализации с транзакциями:
Спр = СоздатьОбъект("Справочник.Номенклатура");
Спр.ВыбратьЭлементы();
НачатьТранзакцию();
Счетчик = 0;
Пока Спр.ПолучитьЭлемент() = 1 Цикл
Спр.guid = ПолучитьGUID(); // Ваша генерация
Спр.Записать();
Счетчик = Счетчик + 1;
// Каждые 1000 записей переоткрываем транзакцию
Если Счетчик % 1000 = 0 Тогда
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Резюмируем: Для успешной записи GUID в 1С 7.7 необходимо работать с объектом, а не со ссылкой, правильно выбирать длину строкового реквизита (ровно 36 символов для стандартного GUID) и использовать транзакции для оптимизации скорости работы.