При разработке обработок часто возникает задача выгрузить список документов или справочников из одной информационной базы и загрузить его в другую. Нередко разработчики пытаются сохранить эти данные непосредственно внутри самой внешней обработки (в ее внутренний макет), чтобы передавать всего один файл обработки. Рассмотрим, почему такой подход не поддерживается платформой 1С, а также разберем надежные и проверенные способы решения этой задачи.
Проанализируем архитектурную особенность платформы: в режиме 1С:Предприятие программно перезаписать внутренний макет конфигурации или файла внешней обработки (.epf) невозможно. Внутренние макеты являются частью неизменяемой в рантайме структуры метаданных. Попытка внедрить динамически формируемые данные внутрь файла внешней обработки без конфигуратора не увенчается успехом.
Кроме того, важно помнить об особенности переноса ссылочных типов: прямые ссылки (ДокументСсылка, СправочникСсылка) не работают между разными информационными базами. При загрузке в другую базу перенесенная «сырая» ссылка приведет к появлению надписи «Объект не найден». Поэтому для связи всегда необходимо оперировать ключевыми полями (номер, дата, ИНН, код) или строковым представлением УникальныйИдентификатор (GUID).
Разберем по шагам, как выгрузить данные в файл табличного документа и затем прочитать их в другой базе.
Для сохранения формируем ТабличныйДокумент, построчно заполняем его данными поиска документов и сохраняем в файл формата .mxl:
ТабДок = Новый ТабличныйДокумент;
Для Каждого Стр Из ТабличнаяЧасть Цикл
НомерСтроки = ТабДок.ВысотаТаблицы + 1;
ТабДок.Область(НомерСтроки, 1).Текст = Стр.НомерСчета;
ТабДок.Область(НомерСтроки, 2).Текст = Формат(Стр.ДатаСчета, "ДФ=yyyyMMddHHmmss");
ТабДок.Область(НомерСтроки, 3).Текст = Строка(Стр.СсылкаНаСчет.УникальныйИдентификатор());
КонецЦикла;
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.MXL);
Для загрузки данных во второй базе используем методы Прочитать и обход заполненных областей:
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу);
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("НомерСчета", Новый ОписаниеТипов("Строка"));
ТЗ.Колонки.Добавить("ДатаСчета", Новый ОписаниеТипов("Дата"));
ТЗ.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Для Ном = 1 По ТабДок.ВысотаТаблицы Цикл
ТекстНомера = СокрЛП(ТабДок.Область(Ном, 1).Текст);
Если ЗначениеЗаполнено(ТекстНомера) Тогда
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.НомерСчета = ТекстНомера;
НоваяСтрока.ДатаСчета = Дата(ТабДок.Область(Ном, 2).Текст);
НоваяСтрока.Идентификатор = СокрЛП(ТабДок.Область(Ном, 3).Текст);
КонецЕсли;
КонецЦикла;
При вызове метода ТабДок.Прочитать(ПутьКФайлу) нередко возникает ошибка доступа к файлу вида Ошибка доступа к файлу '\\tsclient\C\Users\...' или Каталог не обнаружен. Выясним основные причины этой ошибки и варианты устранения:
&НаСервере, то путь к файлу ищется на физическом сервере 1С, где сетевой ресурс \\tsclient вашей пользовательской сессии недоступен. Выполняйте выбор и чтение файла на клиенте через &НаКлиенте или передавайте двоичные данные через ВременноеХранилище (методы ПоместитьФайлНаСервер / ПолучитьФайлНаСервере).Если обе информационные базы доступны по сети, можно обойтись без промежуточных файлов и напрямую подтянуть список счетов через COM-коннектор платформы 1С.
Посмотрим на пример подключения к базе с использованием Windows-аутентификации. Если на сервере настроена аутентификация средствами операционной системы, параметры Usr и Pwd в строке подключения указывать не нужно:
COMСоединитель = Новый COMОбъект("V83.COMConnector");
СтрокаПодключения = "Srvr=""Server1C"";Ref=""BaseName"";";
Попытка
Подключение = COMСоединитель.Connect(СтрокаПодключения);
// Выполняем запрос к удаленной базе для получения списка счетов
ЗапросВнешний = Подключение.NewObject("Запрос");
ЗапросВнешний.Текст =
"ВЫБРАТЬ
| Счет.Номер КАК Номер,
| Счет.Дата КАК Дата,
| Счет.СуммаДокумента КАК Сумма
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК Счет
|ГДЕ
| Счет.Проведен = ИСТИНА";
Результат = ЗапросВнешний.Выполнить().Выгрузить();
// Обрабатываем полученную таблицу данных в текущей базе
Для Сч = 0 По Результат.Количество() - 1 Цикл
СтрокаCOM = Результат.Получить(Сч);
// Заполняем табличную часть текущего объекта
КонецЦикла;
Исключение
Сообщить("Ошибка подключения к базе: " + ОписаниеОшибки());
КонецПопытки;
Важное примечание: Если инициализация COM-соединения с Windows-аутентификацией выполняется в серверном модуле (&НаСервере), авторизация будет производиться под учетной записью службы сервера 1С (например, USR1CV8). Чтобы использовалась сессия текущего пользователя Windows, запуск соединения следует выполнять на клиенте.
Для надежного обмена структурированными списками без привязки к макетам удобно применять выгрузку в JSON или XML. Этот подход исключает проблемы с разметкой таблиц и форматированием дат:
// Выгрузка в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПутьКФайлу);
ЗаписатьJSON(ЗаписьJSON, МассивСчетов);
ЗаписьJSON.Закрыть();
// Чтение из JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ПутьКФайлу);
ПрочитанныеДанные = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Использование сериализованных файлов или COM-подключения позволяет полностью исключить зависимость от неизменяемых макетов внешней обработки и гарантирует корректную передачу данных между независимыми базами 1С.