Как восстановить документ 1С из текстового файла с помощью метаданных?

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

Восстановление данных из текстового файла — это классическая задача для начинающего разработчика 1С, которая позволяет глубоко изучить объектную модель платформы и работу с метаданными. В данной статье мы разберем ситуацию, когда информация о документе была выгружена в упрощенном текстовом формате вида ИмяРеквизита:Значение:Тип, и нам необходимо создать идентичный документ в базе данных, не используя при этом прямые ссылки или уникальные идентификаторы (GUID).

Основная сложность здесь заключается в том, что при чтении файла мы получаем обычные строки. Если для реквизитов типа Строка это не является проблемой, то для Справочников, Документов и Перечислений простого присваивания недостаточно — программа не сможет автоматически преобразовать текст "Основной склад" в ссылку на элемент справочника. Проанализируем, как решить эту задачу по шагам.

Шаг 1. Инициализация объекта и обход метаданных

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


НовыйДокумент = Документы[ИмяТипаДокумента].СоздатьДокумент();
// Устанавливаем дату и номер, если они есть в файле
НовыйДокумент.Дата = ДатаИзФайла;
НовыйДокумент.Номер = НомерИзФайла;

Для заполнения остальных полей мы будем обходить метаданные созданного документа. Это позволит нам точно знать, какой тип данных ожидает каждый конкретный реквизит. Выясним причину, по которой обычное присваивание НовыйДокумент[ИмяРеквизита] = ЗначениеИзФайла не работает: платформа ожидает объект типа СправочникСсылка, а получает Строка.

Шаг 2. Определение типа данных и получение менеджера

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


// Пример разделения строки типа "Справочник.Склады"
МассивЧастей = СтрРазделить(ТипИзФайла, ".");
КлассОбъекта = МассивЧастей[0]; // Справочник
ИмяОбъекта = МассивЧастей[1];   // Склады

Если КлассОбъекта = "Справочник" Тогда
    Менеджер = Справочники[ИмяОбъекта];
ИначеЕсли КлассОбъекта = "Документ" Тогда
    Менеджер = Документы[ИмяОбъекта];
ИначеЕсли КлассОбъекта = "Перечисление" Тогда
    Менеджер = Перечисления[ИмяОбъекта];
КонецЕсли;

Использование квадратных скобок Справочники[ИмяОбъекта] — это мощный инструмент 1С, позволяющий обращаться к любой коллекции метаданных по строковому имени. Это избавляет нас от необходимости писать громоздкие конструкции Если...Тогда для каждого конкретного справочника.

Шаг 3. Поиск ссылочных типов (Справочники и Документы)

Теперь, когда у нас есть доступ к менеджеру, мы должны найти конкретный элемент. В условиях задачи запрещен поиск по УникальныйИдентификатор, поэтому рассмотрим альтернативные методы поиска: по наименованию или по коду.

Поиск по наименованию: Самый простой, но рискованный метод, так как в базе могут быть элементы с одинаковыми названиями.


НайденнаяСсылка = Менеджер.НайтиПоНаименованию(ЗначениеИзФайла, Истина);
Если НайденнаяСсылка.Пустая() Тогда
    Сообщить("Элемент не найден: " + ЗначениеИзФайла);
КонецЕсли;

Поиск по коду: Более надежный метод для справочников. Если при выгрузке вы сохраняли код элемента, используйте Менеджер.НайтиПоКоду(КодИзФайла). Для документов поиск обычно осуществляется по связке Дата + Номер, так как номера могут дублироваться в разных годах.

Шаг 4. Особенности работы с Перечислениями

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


// ЗначениеИзФайла должно содержать имя значения, например "Опт" или "Розница"
Попытка
    НовыйДокумент[ИмяРеквизита] = Перечисления[ИмяОбъекта][ЗначениеИзФайла];
Исключение
    Сообщить("Не удалось определить значение перечисления для " + ИмяРеквизита);
КонецПопытки;

Если в файл выгружен "Синоним" (то, что видит пользователь), а не "Имя", вам придется перебирать все значения перечисления в цикле через Метаданные.Перечисления[ИмяОбъекта].ЗначенияПеречисления и сравнивать их синонимы с текстом из файла.

Шаг 5. Обработка простых типов (Дата, Число, Булево)

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

  1. Число: Используем функцию Число(ЗначениеИзФайла). Важно убедиться, что разделитель дробной части в файле совпадает с локальными настройками системы (обычно запятая или точка).
  2. Дата: Рекомендуется выгружать дату в формате ГГГГММДДччммсс. Тогда преобразование выполняется функцией Дата(ЗначениеИзФайла).
  3. Булево: Можно записывать как "Да"/"Нет" или "Истина"/"Ложь". При загрузке используем простое условие: НовыйДокумент[ИмяРеквизита] = (ЗначениеИзФайла = "Истина").

Шаг 6. Работа с Табличными Частями

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


// Предположим, мы определили, что текущая строка файла относится к ТЧ "Товары"
НоваяСтрока = НовыйДокумент.Товары.Добавить();
// Далее заполняем реквизиты строки так же, как реквизиты шапки
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(ЗначениеИзФайла);
НоваяСтрока.Количество = Число(КоличествоИзФайла);

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

Итоги и рекомендации

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

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

← На главную