Как в 1С отфильтровать записи DBF-файла, начинающиеся на определенные цифры?

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

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

Основы работы с объектом XBase

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


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

Пока НЕ ФайлDBF.ВКонце() Цикл
    // Здесь будет происходить анализ строки
    ФайлDBF.Следующая();
КонецЦикла;
ФайлDBF.ЗакрытьФайл();

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

Реализация фильтрации по префиксу "123"

Основной вопрос заключается в том, как отобрать записи, где значение в колонке account начинается с определенных символов (например, "123"), учитывая, что длина поля может быть фиксированной и составлять 10 или более знаков. Рассмотрим несколько способов реализации этого условия.

Способ 1: Использование функции Лев()

Это классический метод, который работает на любой версии платформы 1С. Мы берем левую часть строки нужной длины и сравниваем ее с эталоном. Выясним, как это выглядит в коде:


ЗначениеВКолонке = СокрЛП(ФайлDBF.account); // Убираем лишние пробелы
Если Лев(ЗначениеВКолонке, 3) = "123" Тогда
    // Данная строка подходит под условие
КонецЕсли;

Способ 2: Функция СтрНачинаетсяС()

Если вы работаете на платформе версии 8.3.6 и выше, рекомендуется использовать специализированную функцию СтрНачинаетсяС(). Она делает код более читаемым и избавляет от необходимости высчитывать количество символов вручную.


Если СтрНачинаетсяС(СокрЛП(ФайлDBF.account), "123") Тогда
    // Обработка подходящей записи
КонецЕсли;

Нюансы типизации и преобразования данных

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

  1. Потеря лидирующих нулей. Если счет начинается на "00123", при преобразовании в число нули исчезнут, и условие "начинается с 123" может сработать некорректно.
  2. Разделители групп разрядов. При неявном преобразовании числа в строку 1С может добавить неразрывные пробелы (например, "1 234").

Чтобы избежать этих проблем, всегда явно приводите значение к строке, используя функцию Формат() с параметром "ЧГ=0" (исключение группировки разрядов):


ЗначениеСтрокой = Формат(ФайлDBF.account, "ЧГ=0");
Если Лев(ЗначениеСтрокой, 3) = "123" Тогда
    // Корректное сравнение
КонецЕсли;

Создание нового DBF-файла с результатами

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

Рассмотрим по шагам процесс копирования структуры и данных:


// 1. Создаем объект для нового файла
НовыйФайл = Новый XBase;
// Добавляем поля аналогично исходному файлу
НовыйФайл.Поля.Добавить("ACCOUNT", "S", 10);
НовыйФайл.Поля.Добавить("SUMMA", "N", 15, 2);
НовыйФайл.СоздатьФайл(ПутьКНовомуФайлу);

// 2. Открываем исходный файл
ИсходныйФайл = Новый XBase;
ИсходныйФайл.ОткрытьФайл(ПутьКИсходнику);
ИсходныйФайл.Первая();

// 3. Цикл фильтрации и записи
Пока НЕ ИсходныйФайл.ВКонце() Цикл
    Если Лев(СокрЛП(ИсходныйФайл.account), 3) = "123" Тогда
        НовыйФайл.Добавить();
        НовыйФайл.account = ИсходныйФайл.account;
        НовыйФайл.summa = ИсходныйФайл.summa;
        НовыйФайл.Записать();
    КонецЕсли;
    ИсходныйФайл.Следующая();
КонецЦикла;

НовыйФайл.ЗакрытьФайл();
ИсходныйФайл.ЗакрытьФайл();

Оптимизация: Использование индексов и ADO

Если ваш DBF-файл содержит миллионы записей, обычный перебор (сканирование всей таблицы) может занять значительное время. Выясним, как ускорить этот процесс.

1. Использование индексов. Если к файлу прилагается индексный файл (.cdx), мы можем установить фильтр. Это позволит платформе считывать только нужные порции данных. Для этого используется метод УстановитьФильтр().

2. Подключение через ADO. Рассмотрим альтернативный подход: работу с DBF как с базой данных через SQL-запросы. Это часто работает быстрее, так как фильтрация происходит на уровне драйвера базы данных.


Connection = Новый COMОбъект("ADODB.Connection");
// Строка подключения зависит от установленных драйверов (Microsoft dBase Driver или Provider=Microsoft.Jet.OLEDB.4.0)
Connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + КаталогФайла + ";Extended Properties=dBASE IV;");

Recordset = Новый COMОбъект("ADODB.Recordset");
ТекстЗапроса = "SELECT * FROM [" + ИмяФайла + "] WHERE account LIKE '123%'";
Recordset.Open(ТекстЗапроса, Connection);

Пока НЕ Recordset.EOF Цикл
    // Прямой доступ к полям через Recordset.Fields("account").Value
    Recordset.MoveNext();
КонецЦикла;

Подведение итогов

Мы рассмотрели несколько способов решения задачи. Для простых повседневных задач идеально подходит использование объекта XBase в сочетании с функцией Лев() или СтрНачинаетсяС(). При реализации всегда обращайте внимание на кодировку (OEM/ANSI) и обрезайте лишние пробелы функцией СокрЛП(), так как строковые поля в DBF имеют фиксированную длину и всегда дополняются пробелами справа.

Соблюдение этих правил позволит вам создавать надежные и быстрые инструменты для обработки внешних данных в среде 1С.

← На главную