Как обойти табличную часть с условием и обработать данные пакетами по 100 строк?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

Анализ задачи и возможные ошибки при обходе

Рассмотрим структуру типового процесса и выделим ключевые нюансы, о которых важно помнить:

  1. Потеря «хвоста» выборки: если общее число подходящих строк не делится нацело на 100 (например, всего 245 строк), после завершения основного цикла останется неполный пакет (45 строк). Если не предусмотреть отдельную проверку после цикла, эти данные не будут отправлены.
  2. Управление выделением и сбросом: при прямом обходе по индексам важно корректно адресовать только те строки, которые вошли в текущий пакет.
  3. Интерактивность интерфейса: в обычных формах при выполнении длительных сетевых вызовов форма может визуально «зависать», а флажки не успевают перерисовываться на экране.

Вариант 1. Использование массива-буфера (рекомендуемый способ)

Наиболее надежный и простой в поддержке способ — использование массива в качестве временного буфера текущего пакета. Мы последовательно перебираем строки табличной части через цикл Для каждого, добавляем подходящие строки в массив и выставляем им признак. Как только размер массива достигает требуемого лимита (100 элементов), мы выполняем целевое действие, сбрасываем флажки только у строк из массива и очищаем сам буфер.

Посмотрим на пример кода процедуры:


Процедура ОбработатьТабличнуюЧастьПакетами()

    БуферСтрок = Новый Массив;
    ЛимитПакета = 100;
    
    Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть Цикл
        
        // Проверяем условие отбора
        Если ЗначениеЗаполнено(СтрокаТЧ.Данные) Тогда
            
            СтрокаТЧ.Флажок = Истина;
            БуферСтрок.Добавить(СтрокаТЧ);
            
            // Проверяем заполнение пакета
            Если БуферСтрок.Количество() = ЛимитПакета Тогда
                
                ОтправитьПакетДанных(БуферСтрок);
                СброситьФлажкиВПакете(БуферСтрок);
                БуферСтрок.Очистить();
                
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
    // Обязательно обрабатываем остаток данных (неполный пакет)
    Если БуферСтрок.Количество() > 0 Тогда
        ОтправитьПакетДанных(БуферСтрок);
        СброситьФлажкиВПакете(БуферСтрок);
        БуферСтрок.Очистить();
    КонецЕсли;

КонецПроцедуры

Процедура ОтправитьПакетДанных(МассивСтрок)
    
    // Здесь размещается логика отправки данных в веб-сервис
    // Входящий параметр содержит ровно ту пачку строк, которую нужно передать
    
КонецПроцедуры

Процедура СброситьФлажкиВПакете(МассивСтрок)
    
    Для Каждого СтрокаПакета Из МассивСтрок Цикл
        СтрокаПакета.Флажок = Ложь;
    КонецЦикла;
    
КонецПроцедуры

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

Вариант 2. Пакетная обработка по индексам с явным счетчиком

Рассмотрим альтернативный способ, когда для отслеживания текущего положения используется индекс последней обработанной строки. В этом случае мы запоминаем позицию начала текущего пакета и позицию конца, что позволяет выполнить сброс флажков в диапазоне индексов.

Разберем пример реализации:


Процедура ОбойтиТЧПоИндексам()

    СчетчикФлажков = 0;
    ВсегоСтрок = Объект.ТабличнаяЧасть.Количество();
    ИндексНачалаПакета = 0;
    
    Для Индекс = 0 По ВсегоСтрок - 1 Цикл
        
        СтрокаТЧ = Объект.ТабличнаяЧасть[Индекс];
        
        Если ЗначениеЗаполнено(СтрокаТЧ.Данные) Тогда
            СтрокаТЧ.Флажок = Истина;
            СчетчикФлажков = СчетчикФлажков + 1;
        КонецЕсли;
        
        Если СчетчикФлажков = 100 Тогда
            
            ВыполнитьДействие(ИндексНачалаПакета, Индекс);
            СброситьФлажкиДиапазона(ИндексНачалаПакета, Индекс);
            
            СчетчикФлажков = 0;
            ИндексНачалаПакета = Индекс + 1;
            
        КонецЕсли;
        
    КонецЦикла;
    
    // Досылаем остаток, если набралось меньше 100 строк
    Если СчетчикФлажков > 0 Тогда
        ВыполнитьДействие(ИндексНачалаПакета, ВсегоСтрок - 1);
        СброситьФлажкиДиапазона(ИндексНачалаПакета, ВсегоСтрок - 1);
    КонецЕсли;

КонецПроцедуры

Процедура СброситьФлажкиДиапазона(НачалоИндекс, КонецИндекс)
    
    Для Позиция = НачалоИндекс По КонецИндекс Цикл
        СтрокаТЧ = Объект.ТабличнаяЧасть[Позиция];
        Если СтрокаТЧ.Флажок Тогда
            СтрокаТЧ.Флажок = Ложь;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Обеспечение отзывчивости интерфейса в обычных формах

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

  1. Прерывание пользователем: вызов метода ОбработкаПрерыванияПользователя() на каждой итерации цикла позволяет системе обрабатывать системные события ОС и дает возможность прервать процесс клавишами Ctrl + Break.
  2. Индикация прогресса: использование встроенной функции Состояние(...) для информирования пользователя о текущем номере пакета и проценте выполнения.
  3. Обновление формы: принудительный вызов метода ЭлементыФормы.ТабличнаяЧасть.ОбновитьСтроки() или обновление отображения данных перед выполнением сетевого запроса.

Отказоустойчивость при сетевом обмене

Обращение к внешним веб-сервисам сопряжено с рисками разрыва соединения или ошибок валидации пакета. При выполнении интеграционных процедур рекомендуется:

  1. Оборачивать вызов веб-сервиса в конструкцию Попытка ... Исключение.
  2. В случае ошибки не сбрасывать флажки на отправляемых строках, а записывать описание ошибки в отдельную текстовую колонку таблицы, чтобы пользователь мог сразу увидеть проблемные позиции.
← На главную