Як збільшити швидкість роботи 1С в 100 разів прямим зверненням до MSSQL

Виникла завдання-помітити на видалення документи за 1 рік. Ця операція виконується перед безслідним видаленням і включає виставлення відмітки і видалення рухи по регістрах. Пробне видалення штатними засобами одного місяця тривало 4 години. Це означало, що 12 місяців віддалялися б 48 годин (2 доби). Забігаючи вперед, скажу, що прямим доступом до 1С документи видаляються за 30-40 хвилин. Звернення до MSSQL виконувалося через .Net framework і компонент .Net Bridge.

Визначення імен таблиць MSSQL
Структура бази даних 1С вельми заплутана і складається з малозначущих для людини назв. 1С містить функцію визначення структури зберігання по імені об'єкта. В основу розробки покладена ця функція ПолучитьСтруктуруХраненияБазыДанных, яка згідно російській назві повертає опис структури. У цій структурі важливі 2 поля Призначення, яке має бути одно «Основна», і назву таблиці ИмяТаблицыХранения.



Визначення зміщення дат
Таблиця _YearOffset містить число, що означає зсув року дат. Воно приймає значення 0 або 2000. Так зі зміщенням 2000 дата 01.01.2014 буде зберігатися в базі даних як 01.01.4014. Відповідно при відборі за датами (видалення відбувається за період часу) потрібно враховувати зміщення. Зміщення можна отримати наступним кодом 1С:
командаСмещение = sqlConnection.CreateCommand();
командаСмещение.CommandText = "select top 1 Offset from _YearOffset";
командаСмещение.CommandTimeout = timeout;
чтениеСмещение = командаСмещение.ExecuteReader();
Якщо чтениеСмещение.Read() Тоді
Зсув = чтениеСмещение.GetInt32(0);
КонецЕсли;
чтениеСмещение.Dispose();


Установка позначки на видалення документів
Маючи назви таблиць документів і знаючи, що поля _Date_Time, _Marked і _Posted відповідають за дату, відмітку про видалення та відмітку про проведення відповідно, можна одним SQL-запитом позначити їх все на видалення. Робиться це так:
командаДокумента = sqlConnection.CreateCommand();
командаДокумента.CommandText = "UPDATE " + строкаТаблицы.ИмяТаблицыХранения + " SET _Marked = 0x01, _Posted = 0x00 WHERE _Date_Time BETWEEN @StartDate AND @a list";
командаДокумента.Parameters.AddWithValue("@StartDate", StartDate);
командаДокумента.Parameters.AddWithValue("@EndDate", a list);
командаДокумента.ExecuteNonQuery();
командаДокумента.Dispose();


Установка позначки на видалення у журналах документів
Не дивлячись на встановлення позначки на видалення у документів, у журналах документів зберігаються дублі відміток про видалення на кожен документ. Список журналів, де бере участь документ можна отримати з метаданих документа так: Метадані.ЖурналыДокументов
Відмітка на видалення через поля _Marked і _Posted відбувається аналогічно через команду:
командаЖурналов.CommandText = командаЖурналов.CommandText + "UPDATE " + ОсновнаяТаблицаЖурнала + " SET _Marked = 0x01, _Posted = 0x00 WHERE _DocumentRRef IN (SELECT _IDRRef FROM " + строкаТаблицы.ИмяТаблицыХранения + " WHERE _Date_Time BETWEEN @StartDate AND @a list);"


Видалення рухів регістрів
При видаленні документів 1С видаляє рухи документа по регістрах. У разі прямого доступу ці рухи треба видалити самостійно. Список регістрів можна отримати через метадані ДокументМетаданные.Рухи.
Команда, якій виконується видалення рухів наступна:
командаРегистров.CommandText = командаРегистров.CommandText + "DELETE FROM " + ОсновнаяТаблицаРегистра + " WHERE _RecorderRRef IN (SELECT _IDRRef FROM " + строкаТаблицы.ИмяТаблицыХранения + " WHERE _Date_Time BETWEEN @StartDate AND @a list);"; 


Висновок
Як виявилося, домогтися убыстрения роботи 1С приблизно на 2 порядки не так складно, достатньо виконати 3 види команд. В кінцевій обробці логіка розширена за рахунок вибору документів за видами, додаванням таймауту, додаванням транзакції, пакетним виконанням команд.

Саму обробку можна скачати тут:
ПометкаУдаленияПрямымЗапросом.epf (13,77 kb)

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.