Работа с внешними источниками данных, такими как DBF-файлы, остается актуальной задачей для многих специалистов 1С, особенно когда речь идет об интеграции с государственными системами, банковскими выписками или устаревшим ПО. Одной из типичных задач является фильтрация содержимого файла по определенному критерию и создание нового файла на основе отобранных данных. Разберем подробно, как реализовать проверку вхождения символов и эффективно обработать данные.
Для взаимодействия с форматом DBF в платформе 1С:Предприятие используется встроенный объект XBase. Рассмотрим стандартный механизм обхода файла. Прежде чем приступать к фильтрации, нам необходимо правильно открыть файл и подготовить цикл чтения. Проанализируем базовый алгоритм:
ФайлDBF = Новый XBase;
ФайлDBF.Кодировка = КодировкаXBase.OEM; // Обычно используется OEM (DOS) кодировка
ФайлDBF.ОткрытьФайл(ПутьКФайлу,,Истина); // Открываем только для чтения
ФайлDBF.Первая();
Пока НЕ ФайлDBF.ВКонце() Цикл
// Здесь будет происходить анализ строки
ФайлDBF.Следующая();
КонецЦикла;
ФайлDBF.ЗакрытьФайл();
Важно помнить, что метод ВКонце() является функцией, а обход начинается с вызова Первая(). Если файл пустой, цикл не выполнится ни разу.
Основной вопрос заключается в том, как отобрать записи, где значение в колонке account начинается с определенных символов (например, "123"), учитывая, что длина поля может быть фиксированной и составлять 10 или более знаков. Рассмотрим несколько способов реализации этого условия.
Способ 1: Использование функции Лев()
Это классический метод, который работает на любой версии платформы 1С. Мы берем левую часть строки нужной длины и сравниваем ее с эталоном. Выясним, как это выглядит в коде:
ЗначениеВКолонке = СокрЛП(ФайлDBF.account); // Убираем лишние пробелы
Если Лев(ЗначениеВКолонке, 3) = "123" Тогда
// Данная строка подходит под условие
КонецЕсли;
Способ 2: Функция СтрНачинаетсяС()
Если вы работаете на платформе версии 8.3.6 и выше, рекомендуется использовать специализированную функцию СтрНачинаетсяС(). Она делает код более читаемым и избавляет от необходимости высчитывать количество символов вручную.
Если СтрНачинаетсяС(СокрЛП(ФайлDBF.account), "123") Тогда
// Обработка подходящей записи
КонецЕсли;
Разберем ситуацию, на которую часто не обращают внимания начинающие разработчики: тип данных в самом DBF-файле. Если поле account определено как числовое (Numeric), то прямое обращение к ФайлDBF.account вернет число. Посмотрим, к чему это может привести:
Чтобы избежать этих проблем, всегда явно приводите значение к строке, используя функцию Формат() с параметром "ЧГ=0" (исключение группировки разрядов):
ЗначениеСтрокой = Формат(ФайлDBF.account, "ЧГ=0");
Если Лев(ЗначениеСтрокой, 3) = "123" Тогда
// Корректное сравнение
КонецЕсли;
Проанализируем задачу создания нового файла на основе отфильтрованных данных. Наиболее эффективно выполнять запись "на лету", не загружая все данные в промежуточную таблицу значений. Это существенно экономит оперативную память при работе с большими объемами информации.
Рассмотрим по шагам процесс копирования структуры и данных:
// 1. Создаем объект для нового файла
НовыйФайл = Новый XBase;
// Добавляем поля аналогично исходному файлу
НовыйФайл.Поля.Добавить("ACCOUNT", "S", 10);
НовыйФайл.Поля.Добавить("SUMMA", "N", 15, 2);
НовыйФайл.СоздатьФайл(ПутьКНовомуФайлу);
// 2. Открываем исходный файл
ИсходныйФайл = Новый XBase;
ИсходныйФайл.ОткрытьФайл(ПутьКИсходнику);
ИсходныйФайл.Первая();
// 3. Цикл фильтрации и записи
Пока НЕ ИсходныйФайл.ВКонце() Цикл
Если Лев(СокрЛП(ИсходныйФайл.account), 3) = "123" Тогда
НовыйФайл.Добавить();
НовыйФайл.account = ИсходныйФайл.account;
НовыйФайл.summa = ИсходныйФайл.summa;
НовыйФайл.Записать();
КонецЕсли;
ИсходныйФайл.Следующая();
КонецЦикла;
НовыйФайл.ЗакрытьФайл();
ИсходныйФайл.ЗакрытьФайл();
Если ваш 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С.