Как обновить остатки в табличной части документа из внешнего DBF-файла через FTP

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

В процессе автоматизации складского учета часто возникает задача синхронизации данных с внешними источниками. Рассмотрим ситуацию, когда нам необходимо получить актуальные остатки товаров от поставщика, которые хранятся в файле формата DBF на удаленном FTP-сервере, и обновить соответствующие значения в табличной части документа Заказ.

В этой статье мы подробно разберем весь цикл работы: от подключения к серверу и скачивания файла до оптимизации поиска номенклатуры и записи данных в информационную базу.

Этап 1: Подготовка окружения и получение файла по FTP

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

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


ИмяФайлаОстатков = "OstIs.DBF";
ПолноеИмяФайлаОстатков = КаталогВременныхФайлов();
ПолноеИмяФайла = СокрЛП(ПолноеИмяФайлаОстатков + ИмяФайлаОстатков);

XBase = Новый XBase;
XBase.Кодировка = КодировкаXBase.OEM; // Обычно DBF используют кодировку DOS (OEM)

// Создаем структуру файла, если планируем в него что-то писать, 
// однако для чтения достаточно просто открыть существующий.
XBase.Поля.Добавить("KONTR","S",150);
XBase.Поля.Добавить("NOMENKL","S",150);
XBase.Поля.Добавить("REMAINS","S",60);
XBase.Поля.Добавить("DATE","D",25);

// Подключаемся к FTP и скачиваем файл
обФТП = Обработки.ftp.Создать();
обФТП.Конструктор(Константы.FTPАдрес.Получить(), Константы.FTPПорт.Получить(), Константы.FTPЛогин.Получить(), Константы.FTPПароль.Получить());
обФТП.Прочитать("OstNa.DBF", ПолноеИмяФайла);
обФТП.Деструктор();

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

Этап 2: Простой цикл обхода файла и поиск номенклатуры

После того как файл скачан, мы открываем его и начинаем перебор записей. Основная задача здесь — сопоставить строку из файла с объектом в справочнике Номенклатура и найти соответствующую строку в табличной части документа.

Рассмотрим базовый алгоритм решения задачи:


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

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

Этап 3: Оптимизация с использованием объекта Соответствие

Чтобы ускорить процесс, мы можем заранее подготовить данные табличной части. Вместо того чтобы каждый раз сканировать таблицу документа, мы выгрузим её в объект Соответствие. Ключом будет выступать Номенклатура, а значением — ссылка на строку таблицы.

Разберем, как это реализовать:

  1. Создаем объект Соответствие.
  2. Обходим табличную часть документа и заполняем соответствие.
  3. В цикле по DBF-файлу просто обращаемся к соответствию по ключу.

Посмотрим на пример кода с оптимизацией:


// Подготавливаем кэш строк табличной части
КартаСтрок = Новый Соответствие;
Для Каждого СтрТЧ Из Состав Цикл
    КартаСтрок.Вставить(СтрТЧ.Номенклатура, СтрТЧ);
КонецЦикла;

XBase.ОткрытьФайл(ПолноеИмяФайла);
XBase.Первая();

Пока Не XBase.ВКонце() Цикл
    ИмяТовара = СокрЛП(XBase.NOMENKL);
    НомСсылка = Справочники.Номенклатура.НайтиПоНаименованию(ИмяТовара, Истина);
    
    Если Не НомСсылка.Пустая() Тогда
        // Мгновенный поиск строки по ссылке номенклатуры
        СтрокаДокумента = КартаСтрок.Получить(НомСсылка);
        Если СтрокаДокумента <> Неопределено Тогда
            СтрокаДокумента.Остатки = Число(XBase.REMAINS);
        КонецЕсли;
    КонецЕсли;
    
    XBase.Следующая();
КонецЦикла;
XBase.ЗакрытьФайл();

Использование Соответствия сокращает сложность алгоритма и значительно ускоряет обработку больших заказов.

Важные технические нюансы при работе с XBase

При работе с внешними файлами формата DBF нужно учитывать несколько критических моментов, которые могут привести к ошибкам или некорректным данным:

Завершение работы и очистка

Проанализируем правила "хорошего тона" при работе с файловой системой. После того как данные загружены, файл XBase должен быть закрыт методом ЗакрытьФайл(). Если этого не сделать, файл может остаться заблокированным процессом 1С, и его нельзя будет удалить или перезаписать программно.

Также рекомендуется удалять временный файл после обработки:


Попытка
    УдалитьФайлы(ПолноеИмяФайла);
Исключение
    Сообщить("Не удалось удалить временный файл: " + ПолноеИмяФайла);
КонецПопытки;

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

← На главную