Работа с внешними источниками данных, такими как файлы формата DBF, остается актуальной задачей для многих разработчиков 1С, особенно когда речь идет об интеграции с государственными информационными системами, старым кассовым ПО или логистическими сервисами. Одной из наиболее частых операций является изменение существующих записей в таблице. Существует два основных способа решения этой задачи: использование технологии ADODB (универсальный механизм доступа к данным) и встроенного объекта 1С XBase. Разберем каждый из них подробно, проанализируем нюансы настройки и выясним, какой метод эффективнее в различных ситуациях.
Этот способ основан на выполнении стандартного SQL-запроса через механизм COM-объектов. Он удобен тем, что позволяет изменять данные точечно, используя привычный синтаксис UPDATE, не перебирая все записи файла вручную. Рассмотрим пошагово, как реализовать этот алгоритм.
Для начала нам необходимо создать подключение к папке, где лежит файл. Важно понимать, что для драйверов DBF «Базой данных» является каталог, а «Таблицей» — сам файл.
Проанализируем пример кода для редактирования поля PRICE по коду товара:
Процедура ОбновитьЦенуВDBF(ПутьКФайлу, ИмяФайла, КодТовара, НоваяЦена)
// 1. Создаем объект соединения
Подключение = Новый COMОбъект("ADODB.Connection");
// 2. Формируем строку подключения
// Используем провайдер Microsoft.Jet.OLEDB.4.0 (для 32-битных систем)
Стринг = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=""" + ПутьКФайлу + """;" +
"Extended Properties=""DBASE IV;"";";
Попытка
Подключение.Open(Стринг);
Исключение
Сообщить("Не удалось установить соединение с DBF: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// 3. Подготавливаем команду обновления
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Подключение;
// Формируем текст запроса. Обратите внимание на кавычки для строковых данных
// и отсутствие кавычек для числовых.
ТекстЗапроса = "UPDATE " + ИмяФайла + " SET PRICE = " + СтрЗаменить(Строка(НоваяЦена), ",", ".") +
" WHERE CODE = '" + КодТовара + "'";
Команда.CommandText = ТекстЗапроса;
Команда.CommandType = 1; // adCmdText
// 4. Выполняем команду
Попытка
Команда.Execute();
Сообщить("Данные успешно обновлены!");
Исключение
Сообщить("Ошибка при выполнении запроса: " + ОписаниеОшибки());
КонецПопытки;
// 5. Закрываем соединение
Подключение.Close();
КонецПроцедуры
В этом примере мы используем ADODB.Command. Это более правильный подход, чем открытие Recordset, так как команда UPDATE не возвращает набор строк, а просто модифицирует файл на диске. Обратите внимание на замену запятой на точку в переменной НоваяЦена — SQL-драйверы обычно требуют точку в качестве десятичного разделителя.
При использовании ADODB часто возникает ошибка «Провайдер не найден». Это связано с архитектурой вашей операционной системы и версии 1С:
Если вы используете драйвер ACE OLEDB, строка подключения может выглядеть так:
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Путь + ";Extended Properties=dBase IV;"
DBF-файлы исторически часто используют кодировку CP866 (DOS) или Windows-1251. Если после обновления в файле вместо русского текста появились непонятные символы («кракозябры»), необходимо проверить настройки реестра Windows в ветке HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Xbase. Там можно указать параметр DataCodePage. Однако, использование встроенного объекта XBase в 1С избавляет от этих сложностей, так как позволяет явно указать кодировку при открытии.
Если вам не требуется выполнять сложные SQL-запросы (например, объединение таблиц JOIN), мы рекомендуем использовать родной для 1С объект XBase. Это гораздо стабильнее, так как не зависит от установленных в Windows драйверов OLEDB и их разрядности. Посмотрим на реализацию того же примера с обновлением цены:
Процедура ОбновитьЦенуЧерезXBase(ПолныйПутьКФайлу, КодТовара, НоваяЦена)
БД = Новый XBase;
// Указываем кодировку, если файл в формате DOS
БД.Кодировка = КодировкаXBase.OEM;
Попытка
БД.ОткрытьФайл(ПолныйПутьКФайлу);
Исключение
Сообщить("Ошибка открытия файла: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Если в файле есть индексы (например, файл .CDX), лучше использовать их для поиска
// Но можно и просто перебором, если файл небольшой
БД.Первая();
Пока Не БД.В Конце() Цикл
Если СокрЛП(БД.CODE) = СокрЛП(КодТовара) Тогда
// Начинаем редактирование текущей записи
БД.PRICE = НоваяЦена;
БД.Записать();
Сообщить("Цена обновлена для товара: " + КодТовара);
Прервать; // Выходим, если товар найден и обновлен
КонецЕсли;
БД.Следующая();
КонецЦикла;
БД.ЗакрытьФайл();
КонецПроцедуры
Разберем, что происходит в этом коде. Мы открываем файл, переходим к первой записи методом Первая() и в цикле проверяем условие соответствия кода. Как только нужная запись найдена, мы просто присваиваем новое значение свойству объекта XBase (имя свойства совпадает с именем поля в DBF) и вызываем метод Записать().
Проанализируем ситуации, когда какой метод лучше применять:
UPDATE tov SET PRICE = PRICE * 1.1). Это отработает быстрее, чем цикл в 1С.DELETE) запись не исчезает физически, а помечается как удаленная. Чтобы очистить файл, в XBase нужно использовать метод Сжать() (аналог команды PACK в FoxPro). ADODB через обычный SQL делать PACK не умеет.Таким образом, для простой правки одного-двух полей в небольшом файле наиболее оптимальным и современным способом является использование объекта XBase. Если же вы строите сложную систему обмена данными с использованием SQL-запросов, используйте ADODB, но обязательно убедитесь в наличии корректных драйверов Microsoft ACE на целевой машине.