Как при загрузке из DBF в 1С 7.7 объединить несколько строк в один документ?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

В этой статье мы разберем, как правильно построить алгоритм загрузки, чтобы сгруппировать строки по номеру документа, а также рассмотрим важные технические нюансы, которые обеспечат надежность и скорость работы вашей обработки.

Разбор основной логики группировки строк

Проанализируем типичную ошибку начинающих разработчиков. Когда мы пишем цикл Пока Файл.ВКонце() = 0, внутри которого сразу стоит создание документа, мы получаем ровно столько документов, сколько строк в файле. Чтобы этого избежать, нам необходимо реализовать механизм отслеживания «смены ключа» (в данном случае — номера документа).

Рассмотрим правильный алгоритм действий:

  1. Открыть DBF-файл и подготовить переменную для хранения текущего номера документа.
  2. Начать цикл перебора строк.
  3. Сравнить номер документа в текущей строке файла с номером из предыдущей итерации.
  4. Если номера различаются, значит, начались данные нового документа: нужно записать предыдущий документ (если он был) и создать новый.
  5. Если номера совпадают, просто добавить новую строку в текущий документ и заполнить ее данными.

Посмотрим на пример кода, который реализует эту логику:


Перем ТекНомерДок;
ТекНомерДок = "";
ДБ = СоздатьОбъект("XBase");
ДБ.ОткрытьФайл(ПутьКФайлу);

ДБ.Первая();
Пока ДБ.ВКонце() = 0 Цикл
    // Проверяем, изменился ли номер документа в файле
    Если СокрЛП(ДБ.Номер) <> ТекНомерДок Тогда
        // Если это не первая итерация, записываем предыдущий созданный документ
        Если ТекНомерДок <> "" Тогда
            Док.Записать();
        КонецЕсли;
        
        // Создаем новый документ
        Док = СоздатьОбъект("Документ.Реализация");
        Док.Новый();
        Док.НомерДок = СокрЛП(ДБ.Номер);
        ТекНомерДок = СокрЛП(ДБ.Номер);
    КонецЕсли;

    // В любом случае добавляем строку в текущий (только что созданный или уже открытый) документ
    Док.НоваяСтрока();
    Док.Услуга = ДБ.Инфо; // Здесь должна быть логика поиска элемента справочника
    
    ДБ.Следующая();
КонецЦикла;

// Важно: записываем самый последний документ, так как цикл закончился
Если ТекНомерДок <> "" Тогда
    Док.Записать();
КонецЕсли;
ДБ.ЗакрытьФайл();

Важность сортировки и индексации

Проанализируем критическое условие работы вышеуказанного кода: данный алгоритм будет работать корректно только в том случае, если строки в DBF-файле отсортированы по номеру документа. Если данные в файле перемешаны (например: сначала идет строка документа №1, потом №2, а затем снова №1), программа создаст два разных документа с номером №1.

Чтобы исключить эту проблему, мы рекомендуем использовать индексацию внутри 1С. Выясним, как это сделать программно:


ДБ = СоздатьОбъект("XBase");
ДБ.ОткрытьФайл(ПутьКФайлу);
// Создаем временный индекс по полю номера документа (ND)
ДБ.СоздатьИндексныйФайл("temp.cdx");
ДБ.ДобавитьИндекс("IDX_NUM", "ND", 0, 0, "");
ДБ.ТекущийИндекс("IDX_NUM");
// Теперь строки будут читаться строго по порядку номеров

Поиск элементов справочников

В DBF-файлах информация обычно хранится в виде строк или чисел (названия товаров, коды контрагентов). В документе 1С 7.7 в реквизитах табличной части должны храниться ссылки на объекты справочников. Рассмотрим, как правильно организовать поиск:

При заполнении строки документа обязательно используйте методы НайтиПоНаименованию() или НайтиПоКоду(). Также следует предусмотреть обработку ситуации, когда элемент не найден в базе данных.


СпрНоменклатура = СоздатьОбъект("Справочник.Номенклатура");
// ... внутри цикла загрузки строк ...
Если СпрНоменклатура.НайтиПоНаименованию(СокрЛП(ДБ.Услуга), 0, 1) = 1 Тогда
    Док.Номенклатура = СпрНоменклатура.ТекущийЭлемент();
Иначе
    Сообщить("Внимание: Услуга " + ДБ.Услуга + " не найдена в справочнике!");
КонецЕсли;

Оптимизация скорости загрузки через транзакции

Запись каждого документа в 1С 7.7 — это операция, требующая обращения к базе данных и блокировки таблиц. Если в вашем DBF-файле содержатся тысячи строк, загрузка может затянуться на длительное время. Разберем, как ускорить этот процесс с помощью транзакций.

Использование методов НачатьТранзакцию() и ЗафиксироватьТранзакцию() позволяет объединить запись всех созданных документов в одну операцию на уровне СУБД, что ускоряет процесс в несколько раз.


НачатьТранзакцию();
Пока ДБ.ВКонце() = 0 Цикл
    // Логика создания и заполнения документов...
КонецЦикла;
ЗафиксироватьТранзакцию();

Важно: При использовании транзакций помните о возможности переполнения лога транзакций в SQL-версии или риске потери данных при сбое питания, если транзакция слишком объемная. Рекомендуется фиксировать транзакцию каждые 100-500 документов.

Тонкости преобразования типов данных

При чтении данных из XBase важно учитывать специфику типов 1С 7.7, чтобы избежать ошибок исполнения:

Контроль дубликатов

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

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

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

← На главную