Работа с внешними источниками данных в формате DBF — классическая задача для разработчика на платформе 1С 7.7. Часто возникает ситуация, когда данные в DBF файле изменяются (например, сторонней программой или прямой записью), а индексный файл CDX перестает соответствовать реальному содержимому. Это приводит к тому, что поиск через методы Найти или фильтрация данных начинают работать некорректно или вовсе перестают видеть новые записи. В этой статье мы подробно разберем, как правильно организовать процесс переиндексации, чтобы ваши данные всегда были в актуальном состоянии.
Прежде чем переходить к коду, давайте проанализируем, как 1С работает с индексами. В платформе 7.7 основным инструментом для работы с такими файлами является объект XBase. Если мы открываем таблицу методом ОткрытьФайл, указывая и путь к DBF, и путь к CDX, то при добавлении или изменении записей средствами 1С (методы Добавить, УстановитьЗначениеПоля, Записать) индекс должен обновляться автоматически.
Однако на практике автоматика может давать сбой в следующих случаях:
В таких ситуациях нам требуется принудительная переиндексация. Рассмотрим основные способы ее реализации.
Это самый простой способ, предусмотренный встроенным языком. Если индексный файл существует и его структура (заголовок) не повреждена, мы можем вызвать метод Переиндексировать(). Рассмотрим ситуацию на примере:
// Создаем объект для работы с файлом
База = СоздатьОбъект("XBase");
// Открываем файл вместе с существующим индексом
// Третий параметр "0" означает монопольный доступ, что обязательно для индексации
База.ОткрытьФайл(ПутьКФайлу, ПутьКИндексу, 0);
Если База.Открыта() = 1 Тогда
Попытка
База.Переиндексировать();
Сообщить("Индексация успешно завершена!");
Исключение
Сообщить("Ошибка при переиндексации: " + ОписаниеОшибки());
КонецПопытки;
База.ЗакрытьФайл();
Иначе
Сообщить("Не удалось открыть файл. Возможно, он занят другим пользователем.");
КонецЕсли;
Этот метод хорош своей быстротой, но он бессилен, если файл .cdx физически отсутствует или критически поврежден. В профессиональной среде разработчиков 1С 7.7 более надежным считается полное пересоздание индекса "с нуля".
Разберем по шагам наиболее стабильный алгоритм: мы физически удаляем старый индексный файл, создаем объект XBase, описываем структуру индексов заново и генерируем новый CDX. Этот метод гарантирует отсутствие "мусора" в индексах и корректность поиска.
Проанализируем пример кода, который часто используется в реальных задачах:
Процедура ВыполнитьПереиндексацию(ФайлБазы, ФайлИндекс)
БазаКлассиф = СоздатьОбъект("XBase");
// 1. Пытаемся открыть только DBF файл без индекса в монопольном режиме
БазаКлассиф.ОткрытьФайл(ФайлБазы, "", 0);
Если БазаКлассиф.Открыта() = 0 Тогда
Предупреждение("Файл занят! Закройте все программы, использующие " + ФайлБазы);
Возврат;
КонецЕсли;
// 2. Устанавливаем кодовую страницу.
// Для Windows-кодировки обычно используется 1 (1251), для DOS - 0 (866)
БазаКлассиф.КодоваяСтраница(1);
// 3. Описываем структуру индексов.
// Метод ДобавитьИндекс(ИмяТега, Выражение, Уникальность, Убывание, Фильтр)
// ИмяТега - краткое имя индекса, Выражение - поле или комбинация полей
БазаКлассиф.ДобавитьИндекс("CODE", "CODE", 1, 0, "");
БазаКлассиф.ДобавитьИндекс("GROUP", "CODEGR", 0, 0, "");
Состояние("Ждите... Создание индексов для " + ФайлБазы);
// 4. Генерируем файл. Это удалит старый CDX (если он был указан) и создаст новый.
Попытка
БазаКлассиф.СоздатьИндексныйФайл(ФайлИндекс);
Сообщить("Индексация выполнена успешно.");
Исключение
Сообщить("Ошибка создания индекса: " + ОписаниеОшибки());
КонецПопытки;
// 5. Переоткрываем файл уже с новым индексом для дальнейшей работы
БазаКлассиф.ЗакрытьФайл();
БазаКлассиф.ОткрытьФайл(ФайлБазы, ФайлИндекс, 0);
КонецПроцедуры
Рассмотрим подробнее критические моменты, которые могут повлиять на результат работы:
Монопольный доступ: Любые операции с индексами (создание, сжатие, переиндексация) требуют, чтобы файл не был открыт никем другим. В методе ОткрытьФайл за это отвечает третий параметр. Значение 0 — эксклюзивный доступ, 1 — совместный доступ. Если вы пытаетесь индексировать файл, открытый в другой программе, 1С выдаст ошибку.
Кодировка (Code Page): Если ваш DBF пришел из старых систем на Clipper или FoxPro, он может иметь DOS-кодировку. Если в 1С не вызвать КодоваяСтраница(0) перед созданием индекса, то поиск по кириллическим строкам работать не будет. Выясним причину: индекс строится по двоичным кодам символов, и несовпадение кодовых страниц делает сравнение строк бессмысленным.
Очистка удаленных записей (Сжать): В формате DBF записи не удаляются физически сразу, они лишь помечаются специальным флагом. Индексный файл продолжает хранить ссылки на эти записи. Чтобы уменьшить размер файлов и ускорить работу, перед переиндексацией рекомендуется выполнять "упаковку":
// Удаление записей, помеченных на удаление
БазаКлассиф.Сжать();
Ограничения размера: Помните, что 1С 7.7 работает со стандартным драйвером XBase, который имеет ограничение на размер файла в 2 Гб. Если ваш индекс или сама база приближаются к этому объему, стандартные методы могут работать нестабильно. В этом случае стоит задуматься о переходе на SQL или использовании внешних компонент (например, 1CPP).
Мы проанализировали ситуацию с переиндексацией и выяснили, что наиболее надежный способ — это полное пересоздание индексного файла через методы ДобавитьИндекс и СоздатьИндексныйФайл. Это исключает любые ошибки, связанные с повреждением структуры старого CDX. Не забывайте всегда проверять статус открытия файла методом Открыта() и использовать обработку исключений Попытка...Исключение, чтобы ваша обработка не прерывалась ошибкой при блокировке файла другими пользователями.