В процессе эксплуатации систем на базе 1С:Предприятие 7.7, особенно при работе с большими объемами данных в клиент-серверном варианте (SQL), часто возникает задача очистки базы от старых документов. Стандартные средства 1С могут выполнять удаление крайне медленно, поэтому администраторы и программисты прибегают к использованию прямых SQL-запросов и внешних компонент, таких как 1С++ (1cpp.dll). Однако на этом пути часто встречаются технические препятствия, такие как невозможность создания объекта MetaDataWork или сложности с фильтрацией данных по конкретной организации (фирме). Рассмотрим подробно, как решить эти проблемы и безопасно очистить базу.
Объект MetaDataWork является частью популярной библиотеки 1С++. Он предназначен для получения соответствий между метаданными 1С (именами документов, справочников, реквизитов) и реальными именами таблиц и полей в базе данных SQL. Если при вызове СоздатьОбъект("MetaDataWork") система выдает ошибку, это означает, что компонента либо не загружена, либо некорректно зарегистрирована в системе.
Разберем по шагам, как проверить состояние компоненты:
1cpp.dll вообще присутствует в каталоге программы или базы данных. В коде инициализации обязательно должна присутствовать команда ЗагрузитьВнешнююКомпоненту("1cpp.dll").regsvr32 "путь_к_файлу\1cpp.dll".Когда мы работаем с SQL-версией 1С 7.7, данные о документах распределены по нескольким таблицам. Прямое удаление — это эффективный, но опасный метод, требующий четкого понимания структуры БД. Рассмотрим основные таблицы:
_1SJourn — общий журнал документов. Здесь хранятся даты, номера, типы документов и общие реквизиты.DHxxxx — шапки документов конкретного типа (где xxxx — идентификатор типа).DTxxxx — табличные части документов._1SCRDOC — таблица подчиненных документов (связи "документ-основание").Проанализируем типичный алгоритм удаления. Сначала мы должны отобрать список идентификаторов документов (IDDOC), которые подлежат удалению, во временную таблицу, а затем очистить связанные данные.
Пример подготовки списка документов для удаления:
insert into #iddocs
select iddoc, iddocdef from _1sjourn
where date_time_iddoc >= '20140101'
and date_time_iddoc < '20180101'
Одной из главных сложностей является фильтрация по конкретному юридическому лицу (фирме). В 1С 7.7 "Фирма" часто является общим реквизитом. Чтобы узнать, в каком поле таблицы _1SJourn хранится идентификатор фирмы, нам нужно заглянуть в файл 1cv7.dd (находится в каталоге базы данных) или воспользоваться тем самым объектом MetaDataWork.
Допустим, мы выяснили, что реквизиту "Фирма" соответствует поле SP2062. Тогда наш запрос на выборку документов для конкретной фирмы будет выглядеть так:
select iddoc, iddocdef from _1sjourn
where date_time_iddoc > '20140301'
and date_time_iddoc < '20170801'
and SP2062 = ' 1AB ' -- Внутренний ID фирмы в системе 1С
Важный нюанс: Идентификаторы объектов в 1С 7.7 имеют 36-ричный формат (например, ' 1AB '). Просто написать '1' в условии WHERE нельзя, нужно указывать точное строковое значение идентификатора из справочника Фирмы.
Удаление записей из шапок и журналов — это только половина дела. Посмотрим, какие еще действия необходимо выполнить, чтобы не разрушить целостность базы данных:
RAxxxx). Если удалить документ, но оставить движения, итоги в регистрах (таблицы RGxxxx) станут неверными._1SCRDOC, где ChildID или ParentID соответствуют удаляемым документам..ldf) может мгновенно забить все свободное место на диске. Рассмотрим перевод базы в режим Recovery Model: Simple перед началом операции.Чтобы не переключаться между 1С и SQL Management Studio, мы можем использовать возможности 1С++. Это позволит автоматизировать процесс и динамически получать имена таблиц.
Рассмотрим пример кода на языке 1С с использованием класса ODBCRecordset:
Запрос = СоздатьОбъект("ODBCRecordset");
ТекстЗапроса = "
|SELECT iddoc as [Док $Документ]
|FROM _1SJourn (nolock)
|WHERE date_time_iddoc BETWEEN :НачДата AND :КонДата
| AND $ОбщийРеквизит.Фирма = :ВыбФирма
|";
Запрос.УстановитьТекстовыйПараметр("НачДата", НачДата);
Запрос.УстановитьТекстовыйПараметр("КонДата", КонДата);
Запрос.УстановитьТекстовыйПараметр("ВыбФирма", ВыбФирма);
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
В данном примере использование знака $ перед именами реквизитов позволяет компоненте 1С++ самостоятельно подставить нужные имена полей (например, заменить $ОбщийРеквизит.Фирма на SP2062), что избавляет нас от необходимости ручного анализа файлов конфигурации.
Резюме: Если вы столкнулись с ошибкой MetaDataWork, проверьте версию 1cpp.dll и ее регистрацию. При удалении документов через SQL всегда учитывайте связанные таблицы и необходимость пересчета итогов, а для фильтрации по фирме используйте внутренние идентификаторы 1С, хранящиеся в общем журнале.