Каждый администратор или разработчик 1С хотя бы раз сталкивался с ситуацией, когда в тестовой базе или копии случайно затирались важные данные. Если обе базы (рабочая и копия) находятся на одном сервере СУБД и конфигурации в них абсолютно идентичны, то вернуть утерянную информацию можно быстро и безболезненно. При этом нам не потребуется скачивать сомнительные внешние обработки или использовать сложные правила обмена «Конвертации данных».
В этой статье мы подробно разберем несколько эффективных способов переноса данных регистра сведений: от использования стандартных инструментов фирмы «1С» до написания собственного кода и прямого копирования на уровне базы данных SQL.
Это самый простой и надежный способ, рекомендуемый фирмой «1С». Данная обработка полностью сохраняет все внутренние идентификаторы (UUID) ссылочных данных. Поскольку наши конфигурации одинаковы, перенос пройдет без каких-либо коллизий.
Многие начинающие специалисты пытаются найти эту обработку в самой конфигурации, например в «Управлении торговлей 10.3», но она не встроена в систему по умолчанию. Выясним, где ее можно взять, ничего не скачивая из интернета:
ВыгрузкаЗагрузкаДанныхXML82.epf (или версия для 8.3).Пошаговый алгоритм работы с обработкой:
Что делать, если под рукой нет готовой обработки, а скачивать её из внешних источников запрещено политикой безопасности? Мы можем написать собственную мини-обработку буквально за пару минут. Платформа 1С:Предприятие обладает мощными встроенными механизмами сериализации.
Разберем по шагам, как написать код для выгрузки и загрузки данных регистра.
Код выгрузки (запускаем в рабочей базе):
Создадим внешнюю обработку, добавим на форму кнопку и пропишем следующий обработчик:
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\register_dump.xml"); // укажите доступный путь к файлу
// Создаем набор записей нужного регистра сведений
Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
Набор.Прочитать(); // считываем все существующие записи
ЗаписатьXML(ЗаписьXML, Набор);
ЗаписьXML.Закрыть();
Предупреждение("Данные успешно выгружены в XML!");
Код загрузки (запускаем в базе-копии):
Для загрузки создадим аналогичную кнопку со следующим кодом:
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл("C:\temp\register_dump.xml");
// Читаем данные напрямую в объект набора записей
Набор = ПрочитатьXML(ЧтениеXML);
Набор.Записать(Истина); // Параметр "Истина" очистит старые записи и запишет новые
ЧтениеXML.Закрыть();
Предупреждение("Данные успешно импортированы!");
Этот метод чрезвычайно эффективен, поскольку метод ПрочитатьXML автоматически распознает тип объекта и воссоздает структуру набора записей со всеми измерениями, ресурсами и реквизитами.
Если базы данных крутятся на одном сервере СУБД, мы можем выполнить перенос за несколько секунд вообще без использования интерфейса 1С. Поскольку базы являются идентичными копиями, ссылки на справочники и документы в таблицах SQL (представленные в виде уникальных идентификаторов GUID) полностью совпадают.
Внимание: любые операции напрямую в SQL выполняются на ваш собственный страх и риск. Обязательно сделайте резервную копию базы данных перед началом работ!
Рассмотрим подробнее алгоритм выполнения этой задачи:
Для начала нам необходимо узнать физическое имя таблицы нашего регистра в базе данных. Для этого в режиме «1С:Предприятие» выполним в любой консоли запросов (или простейшем коде) команду:
Сообщить(ПолучитьСтруктуруХраненияБазыДанных().Найти("РегистрСведений.ИмяВашегоРегистра", "ИмяМетаданных").ИмяТаблицыХранения);
Система вернет имя таблицы, которое обычно выглядит как _InfoRegXXXX (где XXXX — числовой идентификатор).
Выполним SQL-запрос для копирования данных из рабочей базы в тестовую. Проанализируем пример такого запроса для MS SQL:
-- Шаг 1. Полностью очищаем поврежденную таблицу в базе-копии
TRUNCATE TABLE ИмяБазыКопии.dbo._InfoRegXXXX;
-- Шаг 2. Переносим все записи напрямую из рабочей базы
INSERT INTO ИмяБазыКопии.dbo._InfoRegXXXX
SELECT * FROM ИмяРабочейБазы.dbo._InfoRegXXXX;
Этот способ работает мгновенно даже на миллионах записей, полностью исключая задержки, связанные с сериализацией и чтением файлов на стороне сервера приложений 1С.
Если мы не хотим сохранять промежуточные файлы на диск и у нас нет прямого доступа к СУБД, мы можем подключиться из базы-копии к рабочей базе напрямую с помощью COM-технологий. Это позволит прочитать данные в источнике и сразу записать их в приемник.
Разберем по шагам код, который необходимо выполнить в базе-копии:
// Шаг 1. Подключаемся к рабочей информационной базе
Соединитель = Новый COMОбъект("V83.COMConnector"); // Используйте V82.COMConnector для платформы 8.2
ПараметрыПодключения = "Srvr=""ИмяСервера"";Ref=""ИмяРабочейБазы"";Usr=""Администратор"";Pwd=""Пароль""";
Попытка
РабочаяБаза = Соединитель.Connect(ПараметрыПодключения);
Исключение
ВызватьИсключение "Ошибка подключения к рабочей базе: " + ОписаниеОшибки();
КонецПопытки;
// Шаг 2. Выбираем данные из рабочей базы с помощью запроса через COM
ЗапросВИсточнике = РабочаяБаза.NewObject("Запрос");
ЗапросВИсточнике.Текст = "ВЫБРАТЬ * ИЗ РегистрСведений.ИмяВашегоРегистра КАК Рег";
Выборка = ЗапросВИсточнике.Выполнить().Выбрать();
// Шаг 3. Подготавливаем набор записей в базе-приемнике
НаборПриемник = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
НаборПриемник.Очистить();
// Шаг 4. Наполняем набор данными
Пока Выборка.Следующий() Цикл
НоваяСтрока = НаборПриемник.Добавить();
// Заполняем все измерения, ресурсы и реквизиты
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
КонецЦикла;
// Шаг 5. Записываем данные с замещением старых записей
НаборПриемник.Записать(Истина);
Предупреждение("Перенос данных через COM-соединение успешно завершен!");
Важное примечание: при заполнении свойств через ЗаполнитьЗначенияСвойств ссылки (справочники, документы) сопоставятся автоматически по их уникальному GUID. Это возможно благодаря тому, что база-копия создавалась как копия рабочей базы.
Если регистр содержит небольшое количество записей (до нескольких тысяч) и нам не хочется писать код, мы можем воспользоваться интерактивными возможностями платформы:
.mxl (внутренний формат 1С) или .xls.Таким образом, мы детально проанализировали пять различных подходов к решению проблемы переноса данных. Выбор конкретного метода зависит от объема данных в регистре, наличия доступа к SQL-серверу и ваших навыков программирования. Для большинства повседневных задач идеальным решением станет использование стандартной обработки ВыгрузкаЗагрузкаДанныхXML или написание простого кода сериализации.