Как заменить ссылки в движениях регистров 1С 7.7 DBF без перепроведения документов и решить проблему падения базы при конвертации в SQL

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

В процессе сопровождения и администрирования баз данных на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с необходимостью исправить ошибки учета задним числом. Традиционный путь — изменение документов и их последующее перепроведение — далеко не всегда применим. Перепроведение документов за прошлые закрытые периоды может привести к непредсказуемому изменению себестоимости, «сплыванию» партионного учета, нарушению последовательностей и искажению сданной отчетности.

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

В этой статье мы подробно рассмотрим два основных подхода к решению этой задачи:

  1. Прямая модификация DBF-таблиц с использованием внешней компоненты 1С++ и прямых запросов.
  2. Конвертация базы данных в MS SQL, выполнение групповой замены ссылок специализированными обработками и обратная выгрузка в DBF.

Также мы разберем критическую ошибку, из-за которой процесс конвертации базы данных из DBF в SQL может внезапно прерываться аварийным завершением работы Конфигуратора (ошибка доступа к памяти Memory Access Violation), и найдем способ её устранения.

---

Способ №1. Прямая модификация DBF-таблиц с помощью 1С++ и OLE DB

Для того чтобы не связываться с долгой процедурой выгрузки и загрузки базы данных, мы можем прибегнуть к механизму прямых запросов к таблицам DBF. Стандартные средства 1С 7.7 не позволяют выполнять произвольные низкоуровневые SQL-запросы к собственной базе данных, однако внешняя компонента 1С++ (1cpp.dll) предоставляет такую возможность.

Сначала проанализируем структуру хранения данных в файловой версии 1С 7.7. Каждому регистру накопления или сведений в базе данных соответствуют физические файлы на диске:

Для замены одной ссылки на другую во всех движениях определенного регистра нам необходимо выполнить операцию UPDATE для соответствующей таблицы RA*. Для этого воспользуемся возможностями OLE DB-провайдера FoxPro (Microsoft Visual FoxPro OLE DB Provider или VFPOLEDB), который отлично справляется с модификацией файлов формата DBF/CDX.

Рассмотрим пример кода на языке 1С 7.7 с использованием объектной модели 1С++ для прямого обновления данных в таблице движения регистра:


// Создаем объект для работы с базой данных через ADODB/OLEDB
БазаДанных = СоздатьОбъект("OLEDBData");

// Формируем строку подключения к текущей базе данных DBF
ПутьКБазе = КаталогИБ();
СтрокаПодключения = "Provider=VFPOLEDB.1;Data Source=" + ПутьКБазе + ";Mode=ReadWrite;Collating Sequence=MACHINE;";

Попытка
    БазаДанных.Соединение(СтрокаПодключения);
Исключение
    Предупреждение("Не удалось установить прямое соединение с таблицами DBF!");
    Возврат;
КонецПопытки;

// Перед выполнением запросов модификации рекомендуется выполнить настройки FoxPro для стабильности
// Отключаем строгую валидацию таблиц для предотвращения конфликтов совместного доступа
БазаДанных.ВыполнитьИнструкцию("SET TABLEVALIDATE TO 0");
БазаДанных.ВыполнитьИнструкцию("SET ANSI OFF");

// Подготавливаем параметры замены
// В 1С 7.7 ссылки внутри таблиц DBF хранятся в виде уникального 13-символьного идентификатора (ID) объекта
ID_Старый = ЗначениеВСтрокуВнутр(СсылкаНаСтарыйЭлемент); // Преобразуем в строку внутреннего формата
ID_Новый  = ЗначениеВСтрокуВнутр(СсылкаНаНовыйЭлемент);

// Извлекаем чистый идентификатор (обычно последние 6 или 9 символов в зависимости от типа метаданных)
// Для примера вырежем ID элемента справочника (длина 6 символов в кодировке 36-ричной системы)
ЧистыйID_Старый = Сред(ID_Старый, 5, 6);
ЧистыйID_Новый  = Сред(ID_Новый, 5, 6);

// Определяем имя физического файла таблицы движений нужного регистра
// Выяснить точное имя таблицы (например, RA123) можно, заглянув в файл словаря данных 1cv7.dd
ИмяТаблицыДвижений = "RA123"; 
ИмяПоляСправочника = "SP124"; // Имя колонки измерения регистра, ссылающегося на справочник

// Составляем текст прямого SQL-запроса на обновление записи
ТекстЗапроса = "UPDATE " + ИмяТаблицыДвижений + " SET " + ИмяПоляСправочника + " = '" + ЧистыйID_Новый + "' WHERE " + ИмяПоляСправочника + " = '" + ЧистыйID_Старый + "'";

Попытка
    БазаДанных.ВыполнитьИнструкцию(ТекстЗапроса);
    Сообщить("Замена ссылок в движениях регистра успешно выполнена!");
Исключение
    Сообщить("Ошибка при выполнении прямого UPDATE: " + ОписаниеОшибки(), "!");
КонецПопытки;

Важное предупреждение: При прямом обновлении таблиц движений RA* вы меняете только детальные записи. Накопленные итоги в таблицах RG* при этом не изменятся автоматически. В результате ваши отчеты (например, «Ведомость по остаткам») начнут показывать некорректные или «разорванные» данные: движения будут относиться к новому элементу справочника, а остатки по-прежнему будут числиться за старым.

Чтобы восстановить логическую целостность и актуализировать остатки, после завершения выполнения всех прямых SQL-запросов обязательно запустите процедуру полного пересчета итогов регистров. Для этого зайдите в режиме «Предприятие» в меню Операции -> Управление оперативным учетом -> Установить ТА на... (или выполните пересчет через режим «Монопольно» -> Администрирование -> Пересчет итогов).

В качестве более стабильной и современной альтернативы провайдеру VFPOLEDB для работы с DBF-файлами напрямую мы рекомендуем использовать компоненту 1sqlite. Она позволяет подключить базу данных 1С 7.7 в виртуальное окружение SQLite, предоставляя полноценный SQL-синтаксис и гарантируя отсутствие зависаний и конфликтов блокировок файлов индексов (*.cdx) при работе пользователей в базе данных.

---

Способ №2. Миграция на MS SQL Server и использование готовых обработок

Если объем исправлений велик (замена требуется в десятках различных таблиц регистров и документов), то писать индивидуальные SQL-запросы под каждую таблицу в DBF становится нерационально. В этом случае наиболее надежный и проверенный практикой путь — временный перенос базы данных на СУБД MS SQL Server, запуск универсальной SQL-обработки и последующий возврат базы обратно в файловый формат DBF.

Для SQL-версий 1С 7.7 существует мощный и проверенный годами инструментарий. В частности, на порталах сообщества программистов доступна обработка, выполняющая прямой поиск и замену ссылок во всех SQL-таблицах базы данных 1С без перепроведения документов. Она мгновенно находит и заменяет бинарные идентификаторы во всех таблицах шапок документов (DH*), табличных частей (DT*), движений регистров (RA*) и даже системной таблице подчиненности и связей (1SCRDOC).

Разберем стандартную последовательность действий для этого сценария:

  1. Выполните резервное копирование файловой базы данных.
  2. В Конфигураторе файловой базы запустите процедуру Администрирование -> Выгрузка данных. На выходе мы получим упакованный архив (обычно файл 1cv7.zip), содержащий файл конфигурации 1cv7.md и текстовый файл данных 1cv7.dat.
  3. Разверните экземпляр СУБД MS SQL Server (для тестовых целей подойдет бесплатная версия Express-редакции).
  4. Создайте пустую базу данных на сервере SQL. Для корректной работы 1С 7.7 с современными версиями SQL Server (начиная с 2005 и выше) используйте специальные патчи или секретные релизы платформы (например, с модифицированной библиотекой BkEnd.dll).
  5. Зарегистрируйте новую информационную базу в стартере 1С, выбрав формат «SQL-версия».
  6. Запустите пустую SQL-базу в режиме Конфигуратора, укажите параметры подключения к серверу СУБД и выполните операцию Администрирование -> Загрузка данных, выбрав ранее созданный архивный файл выгрузки.
  7. После успешной загрузки откройте базу в режиме «Предприятие», запустите специализированную обработку поиска и замены ссылок через прямые SQL-запросы, укажите заменяемые элементы справочника и запустите процесс. Вся процедура займет считанные секунды даже на гигабайтных базах, поскольку замена происходит на уровне движка СУБД.
  8. Выполните обратную операцию: выгрузите данные из SQL-версии через Конфигуратор и загрузите их в чистую файловую базу формата DBF.

---

Решение проблемы: Почему Конфигуратор аварийно завершает работу при загрузке данных в SQL?

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

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

Выясним причину сбоя на примере документа под условным названием «СверткаИБ» (или любого аналогичного документа, создаваемого вспомогательными обработками свертки базы данных). Этот документ обладает уникальной спецификой:

В файловой версии (DBF) платформа 1С 7.7 оптимизирует дисковое пространство. Если у документа нет реквизитов шапки и табличной части, то физические файлы таблиц DHxxxx.dbf и DTxxxx.dbf для него в каталоге базы данных просто не создаются. В DBF-формате система прекрасно работает и без них: сам документ существует как запись в общем журнале 1SJOURN, а его движения лежат в таблицах регистров.

Однако при конвертации в SQL-формат ситуация кардинально меняется:

  1. При загрузке данных конфигуратор считывает структуру метаданных из файла конфигурации 1cv7.md и генерирует на лету файл словаря базы данных 1cv7.dds.
  2. Поскольку у нашего документа свертки нет реквизитов, в структуре словаря 1cv7.dds для него отсутствуют описания таблиц _1S_DHxxxx и _1S_DTxxxx.
  3. В то же время загрузчик начинает импортировать движения регистров из файла 1cv7.dat. При обработке таблиц движений регистров СУБД наталкивается на ссылки на документ свертки. Платформа пытается сопоставить эти ссылки со словарем метаданных и физическими таблицами шапок документов на стороне SQL.
  4. Поскольку таблицы шапки для этого документа физически не существует в схеме SQL (она не была создана, так как отсутствовала в словаре DDS), внутренний алгоритм загрузчика 1С теряет указатель на объект метаданных, что приводит к критическому сбою обращения к памяти (Access Violation) и падению процесса 1cv7s.exe.

Пошаговая инструкция по исправлению ошибки загрузки:

Для того чтобы обойти это ограничение платформы и успешно загрузить базу данных в MS SQL Server, нам необходимо принудительно заставить конфигуратор создать физическую таблицу шапки документа в СУБД. Сделаем это следующим образом:

  1. Откройте исходную файловую базу данных DBF в режиме Конфигуратор.
  2. Найдите в дереве метаданных проблемный документ (тот самый пустой документ свертки или документ без реквизитов, на котором спотыкается загрузка).
  3. Добавьте в данный документ один фиктивный реквизит шапки. Например, реквизит с идентификатором ФиктивныйРеквизит, тип данных — Строка, длина — 10 символов.
  4. Сохраните конфигурацию. При сохранении система автоматически обновит словарь метаданных 1cv7.dd и физически создаст пустые таблицы DH* для этого документа.
  5. Сделайте новую выгрузку данных через меню Администрирование -> Выгрузка данных. Теперь в выгруженном файле словаря будет присутствовать полное описание структуры таблиц шапки этого документа.
  6. Повторите процесс загрузки в пустую базу данных SQL. Загрузка пройдет до конца в лучшем виде, без сбоев и зависаний.

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

---

Дополнительные аспекты прямой замены: Работа со служебной таблицей 1SCRDOC

Если вы решите автоматизировать прямую замену ссылок (на стороне SQL или DBF с помощью 1С++), проанализируйте еще один важнейший элемент структуры базы данных 1С 7.7 — таблицу 1SCRDOC (таблица подчиненности документов и общих реквизитов с отбором).

В этой таблице хранятся связи между документами («документ-основание — подчиненный документ»), а также ссылки на элементы справочников, если эти справочники выбраны в качестве значений общих реквизитов документов с установленным флагом «Отбор по реквизиту».

При прямой замене ссылок в таблицах документов (например, в табличной части DT*) обязательно нужно корректировать записи и в таблице 1SCRDOC. В противном случае нарушится работа отборов в журналах документов и механизм структуры подчиненности. Но здесь кроется серьезный подводный камень:

Риск дублирования уникального индекса:
Представьте ситуацию, когда в табличной части одного и того же документа в разных строках были указаны два разных элемента справочника: «Товар №1» (заменяемый) и «Товар №2» (на который мы заменяем). При проведении такого документа в таблицу 1SCRDOC были записаны две строки связи данного документа с обоими товарами.

Если мы выполним простой запрос типа:

UPDATE _1SCRDOC SET MDID = 'Товар_Новый' WHERE MDID = 'Товар_Старый'

СУБД попытается изменить строку связи со старым товаром на новый товар. Но строка связи с новым товаром для этого документа уже существует в таблице! В результате СУБД попытается записать дублирующие данные в поля, входящие в состав уникального кластерного индекса таблицы 1SCRDOC. Это вызовет ошибку СУБД Duplicate Key Error, и транзакция будет отменена.

Для безопасной замены ссылок в системной таблице 1SCRDOC используйте более сложный алгоритм:

  1. Сначала найдите все записи в 1SCRDOC для заменяемого значения, для которых еще нет аналогичных записей с новым значением для того же документа-владельца. Обновите их прямым запросом UPDATE.
  2. Затем найдите те записи, где для одного документа уже существуют связи и со старым, и с новым значением. Эти дублирующие записи со старым значением нужно просто безболезненно удалить запросом DELETE.

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

← На главную