Как использовать данные из локального DBF-файла в СКД на 64-битном сервере 1С?

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

Рассмотрим достаточно распространенную архитектурную задачу: имеется сторонняя база данных, которая формирует файл в формате DBF. Этот файл физически располагается на локальных компьютерах пользователей, при этом структура файла у всех одинаковая, а наполнение — разное. Наша цель — прочитать эти данные и использовать их для построения отчета с помощью Системы Компоновки Данных (СКД) на 64-битном сервере приложения 1С. Проанализируем ситуацию и разберем по шагам все возможные способы решения этой проблемы.

Чтение файла DBF на 64-битном сервере

Первое препятствие, с которым мы сталкиваемся — это разрядность сервера. Многие разработчики по привычке пытаются настроить внешние источники данных и ищут системные ODBC или OLE DB драйверы. На 64-битном сервере 32-битные драйверы работать не будут. Если вам принципиально нужны драйверы, придется устанавливать 64-битный пакет Microsoft Access Database Engine.

Однако мы поступим проще и надежнее. Платформа 1С:Предприятие имеет встроенный объект XBase, который нативно читает и записывает DBF-файлы. Он отлично работает как в 32-битной, так и в 64-битной среде без установки дополнительных компонентов системы.

Рассмотрим, как прочитать данные и поместить их в Таблицу Значений:


Функция ПрочитатьDBFВТаблицу(ПутьКФайлу)
    ТаблицаДанных = Новый ТаблицаЗначений;
    
    ФайлDBF = Новый XBase;
    ФайлDBF.Кодировка = КодировкаXBase.OEM; // или ANSI, в зависимости от файла
    ФайлDBF.ОткрытьФайл(ПутьКФайлу);
    
    Если Не ФайлDBF.Открыта() Тогда
        Сообщить("Не удалось открыть файл DBF!");
        Возврат ТаблицаДанных;
    КонецЕсли;
    
    // Создаем колонки в ТЗ по структуре DBF
    Для Каждого Поле Из ФайлDBF.Поля Цикл
        ТаблицаДанных.Колонки.Добавить(Поле.Имя);
    КонецЦикла;
    
    // Читаем данные
    ФайлDBF.Первая();
    Пока Не ФайлDBF.ВКонце() Цикл
        НоваяСтрока = ТаблицаДанных.Добавить();
        Для Каждого Поле Из ФайлDBF.Поля Цикл
            НоваяСтрока[Поле.Имя] = ФайлDBF[Поле.Имя];
        КонецЦикла;
        ФайлDBF.Следующая();
    КонецЦикла;
    
    ФайлDBF.ЗакрытьФайл();
    Возврат ТаблицаДанных;
КонецФункции

Решение 1: Передача Таблицы Значений в СКД как «Набор данных - объект»

Если данные из файла нужны только для формирования отчета и их не нужно хранить в базе 1С, оптимальным решением будет использование Таблицы Значений. Выясним, как передать ее в СКД, если в отчете уже используется запрос к базе.

  1. Откроем схему компоновки данных. Создадим первый набор данных — «Набор данных - запрос», в котором опишем получение данных из информационной базы.
  2. Добавим второй набор — «Набор данных - объект». В поле Имя объекта, содержащего данные укажем, например, ДанныеDBF. Добавим необходимые поля, совпадающие с колонками нашей Таблицы Значений.
  3. Перейдем на закладку «Связи наборов данных». Укажем связь между набором-запросом и набором-объектом по ключевым полям. Помните, что СКД всегда использует левое соединение.

Теперь программно инициализируем отчет. Подготовим структуру ВнешниеНаборы и передадим ее в ПроцессорКомпоновкиДанных:


// Получаем ТЗ из файла
ТаблицаDBF = ПрочитатьDBFВТаблицу(ПутьКФайлуЛокально);

ВнешниеНаборыДанных = Новый Структура;
// Ключ структуры должен строго совпадать с именем объекта в СКД!
ВнешниеНаборыДанных.Вставить("ДанныеDBF", ТаблицаDBF);

СхемаКомпоновки = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаКомпоновки.НастройкиПоУмолчанию;

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// Передаем внешние наборы 
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Решение 2: Передача Таблицы Значений как параметра в запрос СКД

Связь наборов данных на уровне СКД иногда работает не так гибко, как обычный SQL-запрос, особенно если требуется внутреннее или полное соединение. Посмотрим на альтернативный метод, который позволяет использовать переданную таблицу прямо в тексте запроса СКД.

Для этого в запросе СКД мы используем конструкцию ПОМЕСТИТЬ, принимая таблицу как параметр:


ВЫБРАТЬ
    *
ПОМЕСТИТЬ ВТ_ДанныеИзФайла
ИЗ
    &ТаблицаDBF КАК ВнешниеДанные
;
//////////////////////////////////////////////////
ВЫБРАТЬ
    РегистрПродажи.Номенклатура,
    Файл.Количество
ИЗ
    ВТ_ДанныеИзФайла КАК Файл
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты КАК РегистрПродажи
        ПО Файл.Артикул = РегистрПродажи.Номенклатура.Артикул

При программном формировании отчета нам останется только установить значение параметра ТаблицаDBF, передав туда нашу сформированную Таблицу Значений.

Решение 3: Временное хранение данных в базе 1С

Если логика работы требует не просто разового вывода отчета, а сохранения загруженных данных на какое-то время (например, для последующего анализа или распределенной обработки), нам потребуется создать объект метаданных. Разберем, что выбрать: Справочник или Регистр Сведений.

Регистр Сведений предпочтительнее. Справочник при записи создает уникальные ссылки (GUID), расходует больше ресурсов и оставляет «мусор», если ссылки где-то зависнут. Регистр сведений работает быстрее и не ссылочный.

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

Чтобы этого избежать, мы создадим Регистр Сведений со следующей структурой:

  1. Измерение: ИмяКомпьютера (строка) — для разделения данных разных пользователей.
  2. Измерение: НомерСтрокиФайла (число) или Идентификатор (УникальныйИдентификатор) — это ключевое поле сделает каждую загружаемую строку абсолютно уникальной, независимо от того, дублируются ли сами бизнес-данные в DBF.
  3. Ресурсы: поля из файла DBF (Сумма, Количество и т.д.).

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

Важное замечание про Журнал Регистрации: Отключить запись в журнал регистрации программно только на момент загрузки для одного регистра или пользователя невозможно. Настройки логирования задаются глобально в Конфигураторе для каждого объекта метаданных. Если вы не хотите, чтобы временные записи засоряли лог, вам нужно в свойствах самого Регистра Сведений в Конфигураторе установить свойство «История данных» и настройки журнала регистрации в положение «Не регистрировать».

← На главную