Как ускорить медленное проведение документов по партиям в 1С 7.7 Торговля и Склад на MS SQL Server

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

При работе в конфигурации 1С:Предприятие 7.7 «Торговля и Склад» (ТиС) на сервере баз данных MS SQL Server 2008 пользователи часто сталкиваются с существенным замедлением проведения объемных расходных накладных (по 200–500 строк). Проблема многократно усиливается при активном списании партий в режиме реального времени. Разберем детально, почему возникает просадка производительности, как организовать разделение на оперативное и регламентное проведение по расписанию, а также как кардинально ускорить расчет партий с помощью современных методов оптимизации.

Причины падения производительности при партионном учете

Чтобы найти правильное решение, проанализируем внутреннюю архитектуру типовой конфигурации «Торговля и Склад» редакции 9.2 и особенности работы платформы 1С 7.7 с СУБД:

  1. Построчный опрос регистров в цикле. Штатный механизм модуля документа РасходнаяНакладная в процедуре ОбработкаПроведения() перебирает каждую строку табличной части. Для каждого товара инициируется отдельное обращение к регистру ПартииНаличие и ПартииОтданные. Для накладной из 300 строк платформа генерирует сотни вложенных SQL-запросов внутри одной открытой транзакции, создавая массивную нагрузку на сеть и сервер.
  2. «Временный расчет» при проведении задним числом. Если документ проводится хотя бы на секунду раньше точки актуальности (ТА), платформа 1С 7.7 выполняет пересчет остатков на момент документа. Она поднимает итоги на конец прошлого закрытого месяца и последовательно накладывает все движения за текущий месяц до позиции проводимого документа. Чем больше документов в базе за месяц, тем сильнее замедляется каждое проведение.
  3. Накопление нулевых остатков. При полном списании партии по количеству в таблицах итогов регистров могут оставаться нулевые записи. Их накопление увеличивает размер служебных таблиц и замедляет выборку остатков.
  4. Блокировки таблицы журнала. В 1С 7.7 при проведении блокируется таблица _1SJOURN, из-за чего несколько менеджеров не могут одновременно проводить крупные документы.

Вариант 1. Автоматизация ночного перепроведения документов по расписанию

Рассмотрим вариант разделения учета: днем накладные проводятся только по количественным остаткам (или без расчета партий), а ночью регламентный процесс последовательно рассчитывает себестоимость и движения по партиям за прошедший день.

Разберем по шагам, как настроить автоматический запуск перепроведения с помощью системного планировщика задач (Task Scheduler), командной строки и внешней компоненты FormEx.

  1. Передача параметров через командную строку. Создадим в планировщике Windows задание, запускающее 1С под специальным системным пользователем с передачей флага автоматической обработки:

    Команда запуска:

    
    "C:\Program Files (x86)\1Cv77\BIN\1cv7s.exe" enterprise /D"\\Server\1CBase\" /N"RobotNight" /P"SecretPass" /PRM"NightPosting"
    
  2. Обработка параметров в глобальном модуле. В процедуре ПриНачалеРаботыСистемы() считываем переданный параметр с помощью метода компоненты FormEx:

    
    Процедура ПриНачалеРаботыСистемы()
        // Загрузка внешней компоненты FormEx для работы с параметрами
        Если ЗагрузитьВнешнююКомпоненту("FormEx.dll") = 0 Тогда
            Сообщить("Не удалось загрузить FormEx.dll!", "!");
        КонецЕсли;
    
        Сервис = СоздатьОбъект("Сервис");
        ПараметрЗапуска = Сервис.ПараметрЗапуска;
    
        Если ВРег(СокрЛП(ПараметрЗапуска)) = "NIGHTPOSTING" Тогда
            // Запуск регламентной обработки
            ОткрытьФорму("Обработка.АвтоПерепроведениеПартий", 1);
        КонецЕсли;
    КонецПроцедуры
    
  3. Алгоритм регламентной обработки перепроведения. В модуле формы созданной обработки реализуем выборку документов за текущий день и их неоперативное перепроведение с полным расчетом партий:

    
    Процедура АвтоматическийПересчет()
        Перем Док;
        
        ДатаНачала = ТекущаяДата();
        ДатаОкончания = ТекущаяДата();
        
        Док = СоздатьОбъект("Документ.РасходнаяНакладная");
        
        Док.ВыбратьДокументы(ДатаНачала, ДатаОкончания);
        Пока Док.ПолучитьДокумент() = 1 Цикл
            Если Док.Проведен() = 1 Тогда
                Попытка
                    // Устанавливаем флаг проведения по партиям в контексте
                    глФлагПолногоСписанияПартий = 1;
                    
                    // Перепроводим документ
                    Док.Провести(1, ""); 
                    
                    глФлагПолногоСписанияПартий = 0;
                Исключение
                    Сообщить("Ошибка проведения документа: " + Док.ТекущийДокумент() + " - " + ОписаниеОшибки());
                КонецПопытки;
            КонецЕсли;
        КонецЦикла;
        
        // Завершаем сеанс робота
        ЗавершитьРаботуСистемы(0);
    КонецПроцедуры
    

Вариант 2. Кардинальная оптимизация списания с помощью прямых SQL-запросов (1С++)

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

Рассмотрим, как заменить построчные запросы к регистру одним пакетным запросом:

  1. Пакетное получение остатков. Вместо вызова Регистр.ПартииНаличие.Остаток(...) в цикле по строкам формируем один SQL-запрос, выбирающий все свободные партии для всей номенклатуры документа разом.
  2. Списание в оперативной памяти. Загружаем результат запроса в объект ИндексированнаяТаблица или ТаблицаЗначений. Алгоритм списания (FIFO или LIFO) выполняется в памяти за доли секунды.
  3. Формирование движений. Заполняем движения регистра на основе рассчитанной таблицы. Время проведения накладной на 300 строк сокращается с 40–90 секунд до 0.2–0.5 секунды.

Пример фрагмента запроса через ODBCRecordset для получения остатков партий по списку номенклатуры:


// Создание объекта прямого доступа к базе SQL
RS = СоздатьОбъект("ODBCRecordset");

ТекстЗапроса = "
|SELECT 
|   $Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
|   $Рег.Партия as [Партия $Справочник.Партии],
|   $Рег.ОстатокТовара as КоличествоОстаток,
|   $Рег.Стоимость as СтоимостьОстаток
|FROM 
|   $РегистрОстатки.ПартииНаличие(:ВыбДата~, ,
|       Номенклатура IN (SELECT Val FROM #СписокТоваров),
|       (Номенклатура, Партия),
|       (ОстатокТовара, Стоимость)) as Рег
|ORDER BY 
|   $Рег.Номенклатура,
|   $СпрП.ДатаДок ASC
|";

RS.УложитьТаблицу(ТЗТоварыДокумента, "#СписокТоваров");
ТаблицаПартий = RS.ВыполнитьИнструкцию(ТекстЗапроса);

Вариант 3. Регламентное обслуживание регистров и базы MS SQL Server 2008

Проанализируем обязательные сервисные действия на уровне базы данных и SQL-сервера, которые устраняют скрытые торможения 1С 7.7:

  1. Закрытие периода и сдвиг точки актуальности. Убедимся, что бухгалтерские и оперативные итоги рассчитаны на актуальную дату. Если граница рассчитанных итогов отстает от текущей даты более чем на месяц, расчет остатков будет критически замедлен.
  2. Удаление нулевых итогов. Для очистки таблиц итогов от записей с нулевыми остатками рекомендуется периодически запускать специализированные обработки очистки или выполнять свертку базы.
  3. Настройка уровня совместимости базы данных. Платформа 1С 7.7 разрабатывалась под оптимизатор MS SQL 2000. В свойствах базы на MS SQL Server 2008 рекомендуется проверить параметр Compatibility Level (рекомендуется режим 80 или 90 для исключения некорректных планов выполнения вложенных запросов платформы).
  4. Регламентные задания в SQL Server Management Studio:

    — Регулярное обновление статистик базы данных (UPDATE STATISTICS WITH FULLSCAN).

    — Еженедельная дефрагментация и реиндексация таблиц (ALTER INDEX ALL REBUILD).

    — Размещение базы tempdb на быстрых NVMe/SSD накопителях с разделением на несколько файлов данных по количеству ядер CPU.

Комбинация очистки итогов, автоматического ночного расчета либо внедрения прямых запросов позволяет полностью ликвидировать задержки при проведении расходных документов любого объема.

← На главную