Многие разработчики сталкиваются с ситуацией, когда даже при небольшом количестве строк в табличной части документа (например, 30 строк), процесс проведения занимает неоправданно много времени. Замеры производительности часто указывают на «узкое место» — вызов метода Свернуть(). Давайте разберем, почему это происходит и как оптимизировать работу кода.
Первое, что необходимо осознать: метод Свернуть() в 1С 7.7 работает как перебор всей таблицы значений. Если в таблице содержится огромное количество записей, процесс поиска дублей и суммирования становится линейно зависимым от размера таблицы. Даже если на выходе вы получаете компактный список из 30 строк, при входе в процедуру таблица может содержать десятки или сотни тысяч записей, накопленных в процессе выборки из регистров.
Основные причины замедления:
ТаблицаЗначений перед сверткой.Прежде чем грешить на метод Свернуть(), давайте проанализируем этап подготовки данных. Зачастую разработчики используют типовые функции выгрузки из регистров, которые забирают все имеющиеся записи, а не только те, что относятся к текущему документу. Рассмотрим подробнее этот процесс.
Если вы работаете с регистром партий или остатков, убедитесь, что выборка ограничена необходимым фильтром. Вместо того чтобы «схлопывать» огромный массив данных в конце операции, попробуйте оптимизировать алгоритм так, чтобы в ТаблицаЗначений попадали только релевантные строки. Проверьте, какие данные передаются в процедуру проведения: возможно, там выполняется ВыгрузитьИтоги(), которая уже содержит свернутые данные, и повторная свертка не имеет смысла.
Вместо использования универсальных процедур попробуйте создать специализированные методы для конкретных видов документов. Это позволит исключить лишние операции:
ТаблицаЗначений на использование механизмов запросов, если это возможно в рамках текущей конфигурации. Запросы 1С позволяют выполнить группировку данных на уровне движка базы данных, что работает значительно быстрее.ТаблицаЗначений, попробуйте предварительно отсортировать её методом Сортировать() по колонкам группировки. Хотя в 7.7 нет встроенного объекта ИндексированнаяТаблица, предварительная сортировка позволит вам при обходе таблицы сравнивать текущую строку только с предыдущей, что избавляет от необходимости сканировать всю таблицу для поиска дублей.Рассмотрим, как можно подойти к оптимизации процесса:
// Вместо глобального метода, который перебирает все итоги,
// реализуем локальную логику для конкретного документа
ТЗ = СоздатьОбъект(\"ТаблицаЗначений\");
ТЗ.НоваяКолонка(\"Номенклатура\");
ТЗ.НоваяКолонка(\"Количество\", \"Число\");
// Заполняем ТЗ только тем, что нужно для текущего документа
// ... (логика заполнения)
// Если данные уже отсортированы, свертка пройдет быстрее
ТЗ.Сортировать(\"Номенклатура\");
// Ручная свертка при необходимости может заменить стандартную
// или существенно ускорить процесс за счет предварительной подготовки
Помните, что лучший способ ускорить выполнение метода Свернуть() — это не допускать попадания в него «мусорных» данных. Изучите состав таблицы перед вызовом этого метода с помощью отладчика. Если вы видите там тысячи строк, которые не должны иметь отношения к текущей задаче, значит, проблема кроется в условиях выборки данных (например, отсутствие фильтра по фирме, складу или конкретному периоду).
Проанализируйте, действительно ли вам нужно сворачивать весь регистр. Часто бывает достаточно выборки по конкретным значениям измерений. Оптимизированный алгоритм, написанный специально для конкретного вида документов внутри модуля проведения, всегда будет работать эффективнее, чем «универсальные» методы, написанные для общего случая.
В заключение, советуем не пытаться ускорить сам «движок» метода, так как это системная функция. Сосредоточьтесь на том, чтобы минимизировать объем данных, подаваемых на вход. Это «хлеб» каждого программиста 1С — умение видеть, что именно тормозит выполнение алгоритма, и вовремя отсекать лишнее на этапе запроса или подготовки массива данных.