Как программно выгрузить и воссоздать документ в 1С через текстовый файл без использования стандартных механизмов обмена

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С иногда возникают специфические задачи, когда стандартные средства обмена, такие как XML, JSON или Enterprise Data, недоступны или запрещены условиями технического задания. В такой ситуации необходимо разработать собственный текстовый формат и логику парсинга, которая позволит корректно восстановить объект в базе данных со всеми его реквизитами и табличными частями. Проанализируем, как это реализовать максимально эффективно.

Разбор основной проблемы: Типизация данных

Основная сложность при чтении данных из простого текстового файла заключается в том, что все значения считываются как тип Строка. Однако реквизиты документа могут иметь типы Число, Дата, Булево или быть ссылками на другие объекты (Справочники, Документы, Перечисления). Простое присвоение НовДокумент[ИмяРеквизита] = ЗначениеИзФайла не сработает для ссылочных типов. Нам необходимо выполнить преобразование типов, основываясь на метаданных документа.

Решение 1: Использование метаданных и функций XMLЗначение

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


// Предположим, Мас[0] - имя реквизита, Мас[1] - строковое значение из файла
МетаДок = НовДокумент.Метаданные();
РеквизитМета = МетаДок.Реквизиты.Найти(Мас[0]);

Если РеквизитМета <> Неопределено Тогда
    // Используем XMLЗначение для стандартных типов и простых ссылок
    // Важно: в файле значение должно быть сохранено через XMLСтрока()
    Попытка
        НовДокумент[Мас[0]] = XMLЗначение(РеквизитМета.Тип, Мас[1]);
    Исключение
        // Если это сложная ссылка или составной тип, здесь потребуется доп. логика
        Сообщить("Ошибка приведения типа для реквизита: " + Мас[0]);
    КонецПопытки;
КонецЕсли;

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

Решение 2: Работа со ссылочными типами через UUID

Если вы не хотите полагаться на XML-сериализацию, проанализируем способ работы через уникальные идентификаторы (GUID). Это самый точный метод связи объектов между разными базами.

При выгрузке вместо наименования справочника записывайте его внутренний идентификатор. Рассмотрим, как восстановить ссылку при загрузке:


// В файле сохранена строка вида: "Справочник.Контрагенты|8f3e5b12-..."
ДанныеСсылки = СтрРазделить(ЗначениеИзФайла, "|");
ИмяМетаданных = ДанныеСсылки[0]; // Например, "Справочник.Контрагенты"
Идентификатор = Новый УникальныйИдентификатор(ДанныеСсылки[1]);

// Получаем ссылку по идентификатору
СсылкаНаОбъект = Справочники.Контрагенты.ПолучитьСсылку(Идентификатор);

Важный нюанс: Если вы используете поиск по наименованию или коду (НайтиПоНаименованию), будьте осторожны — в базе могут существовать дубликаты, или наименование может измениться, что приведет к ошибке привязки данных.

Решение 3: Быстрая сериализация через ЗначениеВСтрокуВнутр

Выясним причину, по которой опытные разработчики иногда используют "старые" методы. Существует системная функция ЗначениеВСтрокуВнутр(). Она переводит любой объект (включая целые документы с ТЧ) в специальный текстовый формат 1С. Это самый простой способ выполнить задание "выгрузить в текст", если формат текста не регламентирован жестко.

Запись в файл:


Текст = Новый ЗаписьТекста("C:\Export\doc.txt");
Текст.ЗаписатьСтроку(ЗначениеВСтрокуВнутр(ОбъектДокумент));
Текст.Закрыть();

Восстановление из файла:


Текст = Новый ЧтениеТекста("C:\Export\doc.txt");
СтрокаДанных = Текст.Прочитать();
НовыйОбъект = ЗначениеИзСтрокиВнутр(СтрокаДанных);
НовыйОбъект.УстановитьСсылкуНового(Документы.ИмяДокумента.ПолучитьСсылку());
НовыйОбъект.Записать();

Внимание: Этот метод имеет недостатки. Полученный текст не предназначен для чтения человеком, и он может перестать работать, если структура документа в конфигурации изменится (например, удалят реквизит).

Работа с табличными частями

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

  1. В файле используйте специальный маркер начала табличной части (например, [ТабличнаяЧасть.Товары]).
  2. Для каждой строки ТЧ выгружайте список значений через разделитель (например, ";").
  3. При чтении находим ТЧ по имени через НовДокумент[ИмяТЧ].
  4. Используем метод Добавить() для создания новой строки и заполняем её реквизиты аналогично шапке документа.

// Пример загрузки строки табличной части
НоваяСтрока = НовДокумент.Товары.Добавить();
Для Каждого Колонка Из МетаДок.ТабличныеЧасти.Товары.Реквизиты Цикл
    // Логика поиска значения в массиве данных из файла и его типизация
    ИмяРеквизитаТЧ = Колонка.Имя;
    НоваяСтрока[ИмяРеквизитаТЧ] = XMLЗначение(Колонка.Тип, ЗначениеИзФайла);
КонецЦикла;

Оптимизация производительности: ЗаписьТекста vs ТекстовыйДокумент

Рассмотрим подробнее вопрос производительности. При работе с большими объемами данных (многострочные документы или пакетная выгрузка) не используйте объект ТекстовыйДокумент. Он загружает весь текст в оперативную память, что может привести к зависанию системы.

Вместо этого используйте потоковые объекты ЗаписьТекста и ЧтениеТекста. Они позволяют обрабатывать файл построчно, не нагружая память. Это критически важно для серверных процедур 1С.

Подытожим: Для создания надежного механизма выгрузки в текст мы рекомендуем сочетать использование UUID для ссылок и Метаданные для определения типов при загрузке. Это обеспечит гибкость кода и независимость от изменений порядка реквизитов в конфигурации.

← На главную