Свертка и обрезка старых баз данных на платформе 1С 7.7 — классическая задача, с которой до сих пор сталкиваются системные администраторы и программисты. Ситуация осложняется, когда конфигурация является сильно измененной или самописной (например, построенной на базе отраслевых решений вроде «Кредитный кооператив» от Приборсервис), а в плане счетов содержатся пользовательские (непредопределенные) счета, созданные непосредственно в режиме «1С:Предприятие».
В этой статье мы подробно разберем два важнейших аспекта этой задачи: как правильно очистить физические таблицы базы данных 1С 7.7 без разрушения структуры ссылок и как настроить правила в «Конвертации данных 2» (КД2) для безошибочного переноса непредопределенных счетов.
---
Попытка «вандального» удаления файлов документов напрямую из каталога базы данных (файлы DH* и DT*) неизбежно приводит к краху всей информационной системы. При первой же проверке физической целостности в Конфигураторе или при попытке открыть журнал документов система выдаст критическую ошибку «Неисправимая ошибка. Таблица 1SJOURN».
Выясним причину этой проблемы. База данных 1С 7.7 в файловом режиме состоит из взаимосвязанных DBF-файлов. Информация распределена следующим образом:
Если мы удаляем файлы DH* и DT*, то записи в журнале 1SJOURN и проводки в 1SENTRY продолжают ссылаться на несуществующие физические таблицы. Это приводит к нарушению ссылочной целостности.
Если нам необходимо полностью очистить копию базы от документов за все прошлые периоды (например, чтобы оставить только «чистые» справочники), выполним следующие шаги:
1SJOURN.*, 1SCRDOC.*, 1SDNLOCK.*.DH*.*, DT*.*.RA*.*, RG*.*.1SOPER.*, 1SENTRY.*, 1SBKTTL*.*, 1SACCSEL.*, 1SSBSEL.*.1SCONST.*.*.cdx в каталоге базы.1SJOURN) с корректной структурой.Если нам нужно обрезать базу до определенной даты (например, удалить документы до 01.01.2018), прямое удаление файлов DBF не подойдет, так как нам нужно сохранить документы за последующие периоды. В этом случае применим программный метод удаления. Чтобы процесс не растянулся на несколько суток, сгруппируем удаление в транзакции по 500–1000 документов.
Рассмотрим пример кода обработки для удаления документов за период:
Процедура ВыполнитьУдаление()
Док = СоздатьОбъект("Документ");
// Определяем период обрезки
ДатаНачала = '01.01.2010';
ДатаОкончания = '31.12.2017';
Док.ВыбратьДокументы(ДатаНачала, ДатаОкончания);
Счетчик = 0;
НачатьТранзакцию();
Пока Док.ПолучитьДокумент() = 1 Цикл
Попытка
// Удаляем документ непосредственно (без пометки на удаление)
Док.Удалить(1);
Счетчик = Счетчик + 1;
// Фиксируем транзакцию каждые 500 документов для ускорения работы
Если Счетчик % 500 = 0 Тогда
ЗафиксироватьТранзакцию();
Сообщить("Успешно удалено документов: " + Счетчик);
НачатьТранзакцию();
КонецЕсли;
Исключение
Сообщить("Не удалось удалить документ: " + Док.ТекущийДокумент() + " - " + ОписаниеОшибки(), "!");
КонецПопытки;
КонецЦикла;
ЗафиксироватьТранзакцию();
Сообщить("Процесс обрезки успешно завершен. Всего удалено документов: " + Счетчик);
КонецПроцедуры
Перед запуском этой обработки рекомендуется временно отключить Журнал регистрации в Конфигураторе, а также перевести точку актуальности (ТА) на дату начала удаляемого периода. Это существенно снизит нагрузку на дисковую подсистему и ускорит удаление в десятки раз.
---
Перейдем ко второй проблеме. Допустим, мы решили пойти по пути переноса документов за нужный период из старой базы в чистую новую базу с помощью «Конвертации данных 2». При стандартной настройке правил выгрузки планов счетов программисты часто сталкиваются с тем, что счета, созданные пользователями в режиме «1С:Предприятие», переносятся с пустыми значениями или вызывают ошибки вида Значение не найдено: 80.2.
Разберем причину этого поведения. По умолчанию КД2 сопоставляет планы счетов через таблицу «Конвертация значений» (ПКЗ). Если в правилах конвертации объектов (ПКО) для плана счетов заполнена хотя бы одна строчка сопоставления значений, КД2 полностью игнорирует стандартные правила поиска свойств (ПКС) по коду или наименованию. В результате предопределенные счета (прописанные в конфигураторе) сопоставляются успешно, а непредопределенные счета игнорируются, так как их нет в статичной таблице сопоставления правил.
Чтобы обойти это ограничение платформы и корректно переносить как системные счета, так и пользовательские, нам необходимо настроить два раздельных ПКО для одного плана счетов и настроить динамическое переключение между ними в момент выгрузки.
Шаг 1. Создание ПКО для предопределенных счетов
ОсновнойПредопределенный (источник и приемник — ваш план счетов).01.1 -> 01.1, 10.1 -> 10.1 и т.д.).Шаг 2. Создание ПКО для непредопределенных счетов
Основной.Код (ставим флаг «Поиск»). Также можно добавить свойство Наименование, Вид, Активный, чтобы при отсутствии счета в приемнике система могла создать его автоматически с правильными параметрами.Шаг 3. Динамическое перенаправление в ПКС документов
Теперь нам нужно объяснить системе, в каких случаях использовать первое правило, а в каких — второе. Для этого откроем правила конвертации свойств (ПКС) для реквизитов документов, имеющих тип счета (например, КоррСчет, СчетУчета и т.д.). В обработчике события «Перед выгрузкой» напишем следующий код:
Если ПустоеЗначение(Источник.КоррСчет) = 1 Тогда
Отказ = 1;
Иначе
// В 1С 7.7 у объекта "Счет" нет прямого флага "Предопределенный".
// Мы можем определить пользовательские счета по их кодам.
КодСчета = Источник.КоррСчет.Код;
Если (КодСчета = "68.10") Или (КодСчета = "80.1") Или (КодСчета = "80.2") Тогда
// Счета созданы пользователями, выгружаем их через поиск по коду
ИмяПКО = "Основной";
Иначе
// Предопределенные счета выгружаем через таблицу соответствий
ИмяПКО = "ОсновнойПредопределенный";
КонецЕсли;
КонецЕсли;
Если пользовательских счетов в системе много и их список постоянно меняется, жесткое перечисление кодов в коде ПКС будет неудобным. В таком случае мы можем создать глобальный алгоритм в КД2 (например, функцию ПредопределенныйСчет(Код)) и вызывать ее во всех правилах.
Создадим алгоритм с именем ПредопределенныйСчет:
// Входящий параметр: КодСчета
// Возвращает: 1 - если счет предопределенный, 0 - если пользовательский
Если (КодСчета = "68.10") или (КодСчета = "80.1") или (КодСчета = "80.2") Тогда
Возврат 0;
КонецЕсли;
Возврат 1;
Тогда код в ПКС документов сократится и станет универсальным:
Если ПустоеЗначение(Источник.КоррСчет) = 1 Тогда
Отказ = 1;
Иначе
КодСчета = Источник.КоррСчет.Код;
// Вызываем наш глобальный алгоритм
Если ПредопределенныйСчет(КодСчета) = 0 Тогда
ИмяПКО = "Основной";
Иначе
ИмяПКО = "ОсновнойПредопределенный";
КонецЕсли;
КонецЕсли;
---
При переносе данных между базами 1С 7.7 с помощью КД2 часто возникают технические ошибки при работе со стандартными обработками загрузки V77Imp.ert. КД2 генерирует модули загрузки, ориентируясь на стандарты 1С 8. Это вызывает следующие проблемы:
Проведен и ПометкаУдаления (в 1С 7.7 проведение и пометка удаления регулируются методами объекта, а не его реквизитами).ПолучитьСтроку() без указания контекста объекта).Если в обработчике события ПослеЗагрузки для документов нам требуется проверить заполнение загруженных реквизитов (например, проверить, заполнился ли корреспондирующий счет в строках), обязательно обращаемся к методам табличной части через контекст загружаемого объекта Объект:
// Неправильно для 1С 7.7 (вызовет ошибку "Функция не обнаружена"):
// ВыбратьСтроки();
// Пока ПолучитьСтроку() = 1 Цикл ...
// Правильно:
Объект.ВыбратьСтроки();
Пока Объект.ПолучитьСтроку() = 1 Цикл
Если ПустоеЗначение(Объект.КоррСчет) = 1 Then
Сообщить("Документ " + Строка(Объект) + ": в строке № " + Объект.НомерСтроки + " не заполнен счет!", "!");
EndIf;
КонецЦикла;
Чтобы документы в базе-приемнике корректно проводились или помечались на удаление в процессе загрузки по правилам КД2, необходимо внедрить исправление в стандартную обработку загрузки.
Для этого откроем Конфигуратор базы «Конвертация данных 2» (КД2), найдем обработку ВыгрузкаКонвертации, перейдем к макету ПроцедурыИФункцииМодуляЗагрузки и найдем там функцию ЗагрузитьДокументV8(). В этой функции необходимо заменить стандартный код обработки признаков проведения на вызовы встроенных процедур 1С 7.7:
// Фрагмент кода интеграции проведения документов для 1С 7.7 в модуле загрузки:
Если ИмяРеквизита = "Проведен" Тогда
Если ЗначениеРеквизита = 1 Тогда
Попытка
Объект.Записать();
Объект.Провести();
Исключение
Сообщить("Ошибка проведения документа: " + ОписаниеОшибки(), "!");
КонецПопытки;
КонецЕсли;
ИначеЕсли ИмяРеквизита = "ПометкаУдаления" Тогда
Если ЗначениеРеквизита = 1 Тогда
Объект.Удалить(0); // Пометка на удаление без непосредственного удаления
КонецЕсли;
КонецЕсли;
После внесения этих изменений в макет КД2, все вновь выгружаемые модули переносщика V77Imp.ert будут автоматически содержать рабочий код для загрузки документов со статусами проведения и удаления.
---
Выполняя обрезку и перенос данных в среде 1С 7.7, придерживаемся следующих правил:
DH* и DT* вручную без очистки системного журнала 1SJOURN и последующего восстановления индексов.