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