В процессе эксплуатации конфигурации «1С:Комплексная автоматизация 7.7» (а также «Торговля и Склад 9.2») пользователи часто сталкиваются с тем, что документы денежных средств, такие как РКО (Расходный кассовый ордер) или ПКО (Приходный кассовый ордер), начинают проводиться крайне медленно. Проблема прогрессирует со временем: если раньше документ проводился секунду, то теперь это может занимать минуты. Проанализируем ситуацию, выясним причины и рассмотрим способы оптимизации на основе практического опыта разработчиков.
Для начала проанализируем замер производительности. В большинстве случаев 97% времени выполнения занимает типовая процедура глДвижениеДолгов, а именно — метод Сортировать для объекта ТаблицаЗначений. Рассмотрим фрагмент кода, который становится критическим:
ВремВзаим.ВыгрузитьИтоги(ТаблИтогов, 1, 1);
// Здесь ТаблИтогов содержит десятки тысяч записей
ТаблИтогов.Сортировать("+КредДокумент", 1); // Погашаем долги по ФИФО
Если ТаблицаЗначений (в данном примере — ТаблИтогов) содержит 30–40 тысяч строк, встроенный алгоритм сортировки 1С 7.7 начинает работать крайне медленно. Но главный вопрос не в скорости сортировки, а в том, почему по одному договору и одной фирме система «вытягивает» такой объем данных.
Разберем, откуда берутся эти тысячи строк. В 1С 7.7 итоги регистров хранятся в разрезе измерений. Для регистров «Покупатели» или «Поставщики» это обычно: Фирма, Контрагент, Договор и КредДокумент (документ-основание). Если учет ведется аккуратно, то при оплате указывается документ отгрузки, и остаток по этой аналитике «схлопывается» в ноль. Однако на практике часто возникают ситуации, когда:
КредДокумент).С точки зрения бухгалтера — баланс по контрагенту нулевой. Но с точки зрения базы данных в таблице итогов (файл RG*.dbf или таблица в SQL) теперь живут две строки: «+100 руб. по Реализации №1» и «-100 руб. по пустому документу». Система 1С 7.7 при вызове метода ВыгрузитьИтоги честно выгружает все эти «виртуальные» долги. За годы работы таких пар «плюс-минус» накапливаются десятки тысяч. Метод Сортировать вынужден перерабатывать весь этот «мусор», что и вызывает колоссальные задержки.
Это самый правильный путь. Нам необходимо убрать из регистра записи, которые в сумме дают ноль. Рассмотрим шаги для реализации этого метода:
1. Автоматическое закрытие долгов. Проанализируем базу и создадим обработку, которая найдет по каждому договору все незакрытые остатки. Если сумма положительных и отрицательных остатков позволяет произвести взаимозачет, программа должна программно создать документ (например, Корректировка долга или технический ПКО/РКО), который закроет суммы в разрезе конкретных документов-оснований.
2. Использование пустого документа-основания. Если детальный учет по документам не важен, можно разово «схлопнуть» все остатки на пустой КредДокумент. Как только записи с конкретными документами обнулятся, они перестанут попадать в таблицу итогов, и ВыгрузитьИтоги вернет всего одну строку вместо 38 000.
3. Регулярная свертка. Рекомендуется выполнять процедуру закрытия регистров ежемесячно, чтобы не допускать накопления «хвостов».
Если почистить данные невозможно или требуется мгновенный технический результат, рассмотрим, как изменить код. Проанализируем альтернативные способы работы с итогами:
Использование ВыбратьИтоги вместо ВыгрузитьИтоги. Метод ВыгрузитьИтоги копирует все данные из памяти сервера/диска в таблицу значений. Это ресурсоемко. Можно попробовать перебор:
ВремВзаим.УстановитьЗначениеФильтра("Фирма", Фирма, 1);
ВремВзаим.УстановитьЗначениеФильтра("Договор", Договор, 1);
ВремВзаим.ВыбратьИтоги();
Пока ВремВзаим.ПолучитьИтог() = 1 Цикл
// Обрабатываем только значимые суммы, игнорируя мусорные записи
// Здесь мы можем программно ограничить количество итераций
КонецЦикла;
Использование прямых запросов (1C++). Если база работает на SQL-версии, это самый эффективный метод. Прямой SQL-запрос к таблице итогов сгруппирует данные и отсеет нулевые суммы еще на стороне сервера БД. В 1С вернется уже готовый «чистый» результат. Это сокращает время выполнения с минут до миллисекунд.
Проанализируем ситуацию: если в вашей компании никто никогда не смотрит отчеты по взаиморасчетам в разрезе конкретных накладных, то измерение КредДокумент в регистрах является избыточным. Рассмотрим, что можно сделать:
Поставщики).КредДокумент или переносим его в реквизиты (если информация нужна только для справки, но не для итогов).Внимание: это действие необратимо изменит логику работы типовой конфигурации и лишит возможности использовать ФИФО при зачете авансов автоматически. Используйте этот метод только в крайнем случае, если учет ведется «по договору в целом».
Для решения проблемы долгого проведения документов в 1С 7.7 рекомендуем придерживаться следующего алгоритма:
RG*.dbf файл регистра взаиморасчетов весит сотни мегабайт — проблема точно в «незакрытых» остатках.1C++ и перепишите критические узлы на прямые запросы.УстановитьЗначениеФильтра всегда передаются корректные и полные значения, чтобы максимально сузить выборку до вызова ВыгрузитьИтоги.Такой комплексный подход позволит не только ускорить проведение документов РКО и ПКО, но и повысит общую стабильность работы системы 1С 7.7.