Загрузи кучу данных и подчисти хвосты

30.09.24

Разработка - Универсальные функции

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

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Конфигурация пример реализации
.cf 83,38Kb
0 2 500 руб. Купить
Схемы в исходном формате
.drawio 6,26Kb
0 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Сценарий

  • Имеется длинная транзакция, которая должна либо завершиться, либо полностью отмениться
  • Внутри транзакции создается большое количество объектов в БД
  • Необходимо собрать все возможные ошибки обрабатываемых объектов, а не падать на первой попавшейся ошибке

Описание приложенной конфигурации

  • Документ1 - документ, инициирующий длинную транзакцию. Служит для сохранения ошибок
  • Документ2 - документ, способный вызвать исключение:
    • вне транзакции - события модуля объекта ОбработкаПроверкиЗаполнения. Генерируем случайное число. Если не делится на 2, то вызываем исключение
    • в транзакции - событие модуля объекта ПриЗаписи. Генерируем случайное число. Если не делится на 3, то вызываем исключение
  • Команда Обработать в форме списка документа Документ1
    • Создает документ Документ1
    • Начинает длинную транзакцию
    • Создает 100 документов Документ2 в цикле
    • Для каждого документа проверяется заполнение и запись - соответственно будет исключение в транзакции или без
    • Сохраняет ошибки создания документов Документ2
    • Записывает документ Документ1

 

Классическая схема

  • Правила использования транзакций описаны на сайте ИТС: Транзакции: правила использования
  • Пример кода из приложенной конфигурации:
    • Создается документ Документ1 - служит для хранения ошибок обработки
    • Начинается длинная транзакция
    • Внутри транзакции создаются документы Документ2 (код будет ниже), которые могут вызывать исключения (в транзакции или без)
Процедура СоздатьДокумент1()

  Док = Документы.Документ1.СоздатьДокумент();
  Док.Дата = ТекущаяДатаСеанса();

  НачатьТранзакцию();
  Попытка
    СоздатьДокументы2(Док);

    ЗафиксироватьТранзакцию();
  Исключение
    ОтменитьТранзакцию();
    Сообщить(ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
  КонецПопытки;

  Док.Записать();

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

МИНУСЫ:

  • Первое исключение внутри транзакции останавливает дальнейшую обработку объектов
  • Нет возможности увидеть ошибки после исключения (картинка ниже)

 

Вариант 1. Добавляем попытку

  • Каждый обрабатываемый объект внутри длинной транзакции оборачиваем в попытку
  • В случае исключения длинная транзакция продолжается
  • Если в попытке есть своя транзакция (явная или неявная) и в ней произошло исключение (кружок №2 на картинке), то все последующие обращения к БД будут вызывать ошибку В данной транзакции уже происходили ошибки
Процедура СоздатьДокументы2(Док)
 
  БылиОшибки = Ложь;
 
  Для Индекс = 1 По 100 Цикл
    НоваяСтрока = Док.Данные.Добавить(); // Новая строка в документе 1 (для ошибки)
    
    Попытка
      СоздатьДокумент2(); // Тут возможны исключения в транзакции и без
      
      НоваяСтрока.Ошибка = НСтр("ru = 'Ошибок нет'");
    Исключение
      БылиОшибки = Истина;
      НоваяСтрока.Ошибка = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;
  КонецЦикла;
 
  Если БылиОшибки Тогда
    ВызватьИсключение НСтр("ru = 'В процессе обработки были ошибки, изменения не сохраняем'");
  КонецЕсли;
 
КонецПроцедуры

МИНУСЫ:

  • После первого исключения внутри "маленькой" транзакции все последующие ошибки будут неинформативными (картинка ниже)
  • И даже если в обрабатываемой строке не должно быть ошибки (но есть запись в БД), то все равно будет ошибка В данной транзакции уже происходили ошибки

 

Вариант 2. Находим сломанные транзакции

  • Выявляем момент, когда в транзакции уже происходили ошибки
  • Это можно сделать выполнив простейший запрос ВЫБРАТЬ 1 (решение предложено тут Безопасная работа с транзакциями на встроенном языке)
  • Если такой момент выявили, то отменяем транзакцию и тут же начинаем новую
  • Получается мы "режем" длинную транзакцию на части, давая возможность продолжить обращаться к БД и выявлять все последующие ошибки
  • Если во время длинной транзакции не произошло ни одной ошибки, то она успешно завершится
  • Если произошла хотя бы одна ошибка в конце обработчика отменяем транзакцию
Процедура СоздатьДокументы2(Док)
 
  БылиОшибки = Ложь;
 
  Для Индекс = 1 По 100 Цикл
    НоваяСтрока = Док.Данные.Добавить(); // Новая строка в документе 1 (для ошибки)
    
    Попытка
      Если ВТранзакцииПроисходилиОшибки() Тогда
        ОтменитьТранзакцию();
        НачатьТранзакцию();
      КонецЕсли;
    
      СоздатьДокумент2(); // Тут возможны исключения в транзакции и без
      
      НоваяСтрока.Ошибка = НСтр("ru = 'Ошибок нет'");
    Исключение
      БылиОшибки = Истина;
      НоваяСтрока.Ошибка = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;
  КонецЦикла;
 
  Если БылиОшибки Тогда
    ВызватьИсключение НСтр("ru = 'В процессе обработки были ошибки, изменения не сохраняем'");
  КонецЕсли;
 
КонецПроцедуры

Ожидаемый результат:

 

PS. Вариант без транзакций

  • Создаем объекты (каждый в своей попытке) и сохраняем на них ссылки (в массив)
  • Если произошла ошибка, то сохраняем её (в массив ошибок)
  • Если в процессе обработки произошла хоть одна ошибка, то помечаем объекты массива на удаление и затем физически удаляем, а пользователю выводим ошибки из массива ошибок

МИНУСЫ:

  • Появляется куча объектов, которые нужно корректно удалить
  • Если в процессе удаления произойдет сбой, то объекты останутся в системе и тут только ручное вмешательство
  • Если на созданные объекты будут ссылки в других объектах, то так же автоматически они не удалятся, опять ручное вмешательство

Именно от такого подхода избавлялся

Вступайте в нашу телеграмм-группу Инфостарт

Транзакция

См. также

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    3672    Abysswalker    9    

45

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    6866    DeerCven    15    

59

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    50063    dimanich70    83    

170

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    7429    6    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    62982    atdonya    31    

70

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    9276    ke.92@mail.ru    17    

68
Для отправки сообщения требуется регистрация/авторизация