Способ обхода ошибки "В данной транзакции уже происходили ошибки"

20.08.26

Разработка - Рефакторинг и качество кода

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

Бесплатные

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

Узнавайте о новых бесплатных решениях в нашей телеграм-группе Инфостарт БЕСПЛАТНО

Наименование Скачано Бесплатно
Обход "В данной транзакции уже происходили ошибки"
.cf 44,26Kb
7 Скачать бесплатно

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Столкнулся в практике со случаем, когда при записи одного документа в некоторых ситуациях автоматически формируется другой, и этот другой в 95% случаев записывается и проводится штатным способом, а в остальных - проведение приводит к ошибке. Но 95% нельзя игнорировать и глупо отказываться от получения готового документа там, где только 5% неуспешны, ведь это явная экономия времени и небесконечной энергии сотрудников! Проблема в том, что если второстепенный документ записан, но не проведен, то в основном документе выскакивает ошибка "В данной транзакции уже происходили ошибки". Некоторые подробности:

1. При этом процесс записи основного документа не выполняется, так как транзакция полностью отменена

2. успешно записанный второстепенный документ также теряется вместе с неявной транзакцией записи

3. ошибка может указывать на определенную строчку в коде либо быть общей с предложением завершить работу (в примере есть переключатель для выведения ошибки - что характерно, если обращений к базе при записи больше не было, то будет общая ошибка) 

4. ситуация также осложнялась тем, что нарушался принцип идемпотентности, поскольку повторная запись уже не приводила к записи второстепенного документа - такое бывает.

Что я испробовал, прежде чем сдаваться перед этой ошибкой:

1. Выделить процедуру простой записи второстепенного документа в отдельную транзакцию - она тоже отменялась

2. При ошибке в проведении пытаться еще раз записать второстепенный документ, но в отдельной транзакции - получил ту же ошибку "В данной транзакции..."

3. Выделять проведение в отдельную транзакцию со своей попыткой - основная транзакция также остается сбойной!

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

Так что же делать? Отказываться от проведения второстепенного документа? Но экономия времени и сил на 95% документов... Нет. Тут и встали на помощь фоновые задания, ведь известно, что они выполняются в отдельном сеансе, а значит, и текущая транзакция на них не распространяется! Осталось только решить несколько вопросов:

1. как передать в функцию текущее состояние еще не записанного объекта

2. как получить результаты выполнения второстепенной задачи

3. как вообще вызвать функцию, которую не хочется помещать дальше модуля менеджера объекта

4. как не потерять полезных сообщений при работе с функцией

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

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

Если Не ЗначениеЗаполнено(ДокументОснование) Или ДокументОснование.ПолучитьОбъект() = Неопределено Тогда
    СлужебнаяЗаписка = Документы.СлужебнаяЗаписка.СоздатьДокумент();
    СлужебнаяЗаписка.Дата = ТекущаяДатаСеанса();
    СлужебнаяЗаписка.УстановитьНовыйНомер();
    СлужебнаяЗаписка.Комментарий = Комментарий;
    СлужебнаяЗаписка.СуммаДокумента = СуммаДокумента;
    Попытка
        СлужебнаяЗаписка.Записать(РежимЗаписиДокумента.Запись);
        ДокументЗаписан = Истина;
        СлужебнаяЗаписка.Записать(РежимЗаписиДокумента.Проведение);
    Исключение
        Если ДокументЗаписан = Истина Тогда
            Сообщить("Служебное основание записано, не проведено", СтатусСообщения.Важное);
            ЗаписьЖурналаРегистрации("Доработки.Отлавливание ошибок", УровеньЖурналаРегистрации.Ошибка,
                Метаданные.Документы.СлужебнаяЗаписка, СлужебнаяЗаписка.Ссылка,
                "Не удалось провести служебную записку. Причина: " + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        Иначе
            Отказ = Истина;
            Сообщить("Не удалось ни записать, ни провести служебную записку", СтатусСообщения.ОченьВажное);
            ЗаписьЖурналаРегистрации("Доработки.Отлавливание ошибок", УровеньЖурналаРегистрации.Ошибка,
                Метаданные.Документы.СчетНаОплату, Ссылка, "Не удалось записать служебную записку. Причина: "
                + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        КонецЕсли;
    КонецПопытки;
    ДокументОснование = СлужебнаяЗаписка.Ссылка;
КонецЕсли;

Ожидая таким образом, что если документ не будет проведен, то хотя бы запишется и сотрудник сможет провести его вручную, выполнив условия. Каково же было его удивление, когда он увидел в журнале транзакций такое:

 

 

То есть очевидно, что запись оказалась отменена вместе с проведением! А у пользователя вышла ошибка "В данной транзакции уже происходили ошибки" и ничего!

Но этому программисту повезло, и он был хорошо знаком с механизмом фоновых заданий, поэтому быстро набросал процедуру для выполнения того же в фоновом задании:

Результат = Новый Структура("Успешно, Отказ, Ссылка", Ложь, Ложь);
Если ОписанияОбъекта.Количество() <> 1 Тогда
    ВызватьИсключение "Передано больше одного описания объекта";
КонецЕсли;
ОписаниеОбъекта = ОписанияОбъекта[0];
СлужебнаяЗаписка = Документы.СлужебнаяЗаписка.СоздатьДокумент();
СлужебнаяЗаписка.Дата = ТекущаяДатаСеанса();
СлужебнаяЗаписка.УстановитьНовыйНомер();
СлужебнаяЗаписка.Комментарий = ОписаниеОбъекта.Комментарий;
СлужебнаяЗаписка.СуммаДокумента = ОписаниеОбъекта.СуммаДокумента;
Попытка
    СлужебнаяЗаписка.Записать(РежимЗаписиДокумента.Запись);
    ДокументЗаписан = Истина;
    Результат.Ссылка = СлужебнаяЗаписка.Ссылка;
    СлужебнаяЗаписка.Записать(РежимЗаписиДокумента.Проведение);
    Результат.Успешно = Истина;
Исключение
    Если ДокументЗаписан = Истина Тогда
        Сообщить("Служебное основание записано, не проведено", СтатусСообщения.Важное);
        ЗаписьЖурналаРегистрации("Доработки.Отлавливание ошибок", УровеньЖурналаРегистрации.Ошибка,
            Метаданные.Документы.СлужебнаяЗаписка, СлужебнаяЗаписка.Ссылка,
            "Не удалось провести служебную записку. Причина: " + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    Иначе
        Результат.Отказ = Истина;
        Сообщить("Не удалось ни записать, ни провести служебную записку", СтатусСообщения.ОченьВажное);
        ЗаписьЖурналаРегистрации("Доработки.Отлавливание ошибок", УровеньЖурналаРегистрации.Ошибка,
            Метаданные.Документы.СчетНаОплату, ОписаниеОбъекта.Ссылка, "Не удалось записать служебную записку. Причина: "
            + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    КонецЕсли;
КонецПопытки;
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);

, где ОписаниеОбъекта - это структура со всеми реквизитами и табличными частями ЭтогоОбъекта из модуля объекта. Как его получить, да просто:

Функция ОписаниеОбъекта(Знач Объект, ТипЗначения = Неопределено) Экспорт

	ОписаниеОбъекта = Новый Структура;
	Если ТипЗнч(Объект) = Тип("ДанныеФормыСтруктура") Тогда
		Если ТипЗнч(ТипЗначения) <> Тип("Тип") Или СтрНайти(ВРег(ТипЗначения), "ОБЪЕКТ") = 0 Тогда
			ВызватьИсключение "Тип реквизита формы должен быть указан явно как ...Объект";
		КонецЕсли;
		Объект = ДанныеФормыВЗначение(Объект, ТипЗначения);
	КонецЕсли;
	
	МетаданныеОбъекта = Объект.Метаданные();
		
	Для Каждого Реквизит Из МетаданныеОбъекта.СтандартныеРеквизиты Цикл
		ОписаниеОбъекта.Вставить(Реквизит.Имя, Объект[Реквизит.Имя]);
	КонецЦикла;
	
	Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл
		ОписаниеОбъекта.Вставить(Реквизит.Имя, Объект[Реквизит.Имя]);
	КонецЦикла;
	
	Для Каждого ТабличнаяЧасть Из МетаданныеОбъекта.ТабличныеЧасти Цикл
		ОписаниеОбъекта.Вставить(ТабличнаяЧасть.Имя, Объект[ТабличнаяЧасть.Имя].Выгрузить());
	КонецЦикла;
	
	Возврат ОписаниеОбъекта;
	
КонецФункции

Теперь осталось только запустить процедуру в фоновом задании и получить результат:

ОписаниеОбъекта = ДлительныеОперацииСервер.ОписаниеОбъекта(ЭтотОбъект);
НастройкиВыполнения = ДлительныеОперацииСервер.НастройкиВыполнения(1, 1, , Истина);
МассивДанных = Новый Массив;
МассивДанных.Добавить(ОписаниеОбъекта);
РезультатыВыполнения = ДлительныеОперацииСервер.ВыполнитьФункциюПорциями(МассивДанных,
	"Документы.СчетНаОплату.СоздатьСчетОснование", Новый Массив, НастройкиВыполнения);
Если РезультатыВыполнения.Количество() Тогда
	Если РезультатыВыполнения[0] = Неопределено Или РезультатыВыполнения[0].Отказ Тогда
		Отказ = Истина;
	Иначе
		ДокументОснование = РезультатыВыполнения[0].Ссылка;
	КонецЕсли;
Иначе
	Отказ = Истина;
КонецЕсли;

На этом все поставленные задачи решены:

 

 

"А был бы я бедный?" - подумал программист, - "Сколько кода мне пришлось бы написать?". И быстро набросал код, необходимый для вызова фонового задания вручную:

ОписаниеОбъекта = ДлительныеОперацииСервер.ОписаниеОбъекта(ЭтотОбъект);
ПараметрыФункции = Новый Массив;
ПараметрыФункции.Добавить(ОписаниеОбъекта);
АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор);
ПараметрыФункции.Добавить(АдресРезультата);

ПараметрыВызова = Новый Массив;
ПараметрыВызова.Добавить("Документы.СчетНаОплату.СоздатьСлужебноеОснование");
ПараметрыВызова.Добавить(ПараметрыФункции);
Задание = ФоновыеЗадания.Выполнить("ОбщегоНазначения.ВыполнитьМетодКонфигурации", ПараметрыВызова);
Задание.ОжидатьЗавершенияВыполнения();
Для Каждого Сообщение Из Задание.ПолучитьСообщенияПользователю() Цикл
	Сообщение.Сообщить();
КонецЦикла;
РезультатыВыполнения = ПолучитьИзВременногоХранилища(АдресРезультата);
Если РезультатыВыполнения = Неопределено Тогда
	Отказ = Истина;
Иначе
	Если РезультатыВыполнения.Отказ Тогда
		Отказ = Истина;
	Иначе
		ДокументОснование = РезультатыВыполнения.Ссылка;
	КонецЕсли;
КонецЕсли;

Как обычно - зная, что хочешь сделать, можно написать не намного сложнее, но зачем? Код функции создания служебки также немного изменил.

Вывод. Здесь был показан конкретный пример ошибки, но он может быть и любым другим. Главное, чтобы была возможность выделить в отдельный метод и передать сериализуемые параметры (легко ищется в синтакс-помощнике по слову "Сериализуется"). Сериализуется не все, что можно передать с клиента на сервер - например, нельзя сериализовать ДанныеФормыСтруктура, то есть реквизит "Объект" формы, как и саму форму, конечно. Результат также должен быть сериализуемым, если он нужен. В остальном ограничений быть не должно, единственное, что нужно учитывать при реализации прямого алгоритма вызова фонового задания, так это что, ВыполнитьМетодКонфигурации может устанавливать безопасный режим, соответственно, например, никаких HTTPСоединение, если у вас это работает:

ПрофильБезопасностиИБ = СтандартныеПодсистемыСервер.ПрофильБезопасностиДляВыполнитьВычислить();
Если ЗначениеЗаполнено(ПрофильБезопасностиИБ) Тогда
	УстановитьБезопасныйРежим(ПрофильБезопасностиИБ);
КонецЕсли;

С ВыполнитьФункциюПорциями такого ограничения нет, там код считается безопасным только потому, что вызывается из базы (раньше в БСП было так).

И ВСЕГДА записывайте в журнал регистрации ошибки, пойманные блоком Попытка, чтобы поиск причины "В данной транзакции уже происходили ошибки" не превращался в пытку! Иначе зачем он вообще нужен)

Совместимость 8.3.25 - из-за паузы, ее переделал на совместимую с файловыми базами. Если у вас клиент-серверная, хватайте Паузу-Оптовик для легаси кода из статьи, она совместима с более низкими версиями. Главное, не используйте за основу паузу отрицания - в контексте данной статьи это то, что совсем нельзя!

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

Транзакция фоновые задания ошибка

См. также

Инструментарий разработчика Рефакторинг и качество кода Программист 1С 8.3 Абонемент ($m)

Обработка читает исходники других внешних обработок и отчётов прямо из базы и отвечает на два вопроса: с какой из них начинать смотреть и что именно в ней смотреть. На выходе HTML-отчёт: индекс качества от 0 до 100, светофор, оценка технического долга в минутах и находки с номером строки, фрагментом кода и подсветкой синтаксиса. Двадцать восемь правил: запрос в цикле, транзакция без отката, небезопасное выполнение строки, тяжёлые схемы компоновки. Считается всё на чистом BSL, без интернета, внешних компонент и отдельного сервиса рядом, поэтому анализируемый код не покидает машину. Прогон по двум десяткам обработок выстраивает их по индексу качества, худшие сверху, и сразу видно, с чего начинать разбор.

10 стартмани

вчера в 10:20    228    1    nedomolkov.ivan    2    

2

Рефакторинг и качество кода Программист 1С 8.3 Бесплатно (free)

Библиотека из 6 слоев анализа, от внешней обработки до готового отчёта. Каталог из двадцати восьми правил, у каждого свой уровень и вес. И всё это крутится на чистом BSL, без Java, без git, без какого-то внешнего сервера анализа и без отправки чужого кода наружу. Разбираю, как устроен этот анализатор внешних обработок и по каким признакам он решает, что код плохой. Почему запрос в цикле получает шестьдесят баллов, как правило вообще проходит фильтр перед релизом и почему часть правил у меня помечена как сломанные. Проверял я его на себе: взял семнадцать своих обработок, которые лежат на площадке и продаются. Получил 239 замечаний и пятнадцать рабочих дней технического долга. У самой худшей индекс качества - 20 из 100 и красный светофор. А ещё расскажу, где у инструмента границы, за которые он не заходит, и про грабли - самая дорогая из них молчала.

вчера в 10:00    284    nedomolkov.ivan    0    

1

Рефакторинг и качество кода Нейросети Программист Бесплатно (free)

Передача двух модулей BSL в Cursor AI для классического сравнения без использования искусственного интеллекта (ИИ) и для проведения code review с помощью ИИ.

12.08.2026    2405    ScaNNer    0    

5

Рефакторинг и качество кода Обновление 1С Программист 1С 8.3 1С:ERP. Управление холдингом Бесплатно (free)

К нам на проект сложного обновления пришла конфигурация «1С:ERP УХ» с доработанным отчетом, построенным на базе типового «Задолженность поставщикам по срокам». После обновления целевая форма открывалась без учета переданных данных.

05.08.2026    772    1c-izh    4    

4

Инструментарий разработчика Рефакторинг и качество кода Программист 1С 8.3 1С 8.5 1С:Документооборот 1С:Бухгалтерия 3.0 1С:Управление нашей фирмой 3.0 Россия Абонемент ($m)

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

2 стартмани

08.07.2026    842    8    NikolayMaerov    0    

4

Рефакторинг и качество кода Обновление 1С Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Бесплатно (free)

На проекте сложного обновления 1С:ERP 2.4.14.181 до версии 2.5.22.106 нам было нужно уложить обновление в технологическое окно 48 часов (выходные). Исходный замер, с учетом промежуточных релизов 2.5.8.443, 2.5.12.270, 2.5.17.234, 2.5.22.106, показал требуемое время в 659 часов…

07.07.2026    5193    1c-izh    20    

21

Рефакторинг и качество кода Обновление 1С Программист 1С 8.3 Бесплатно (free)

Обновление ролей в расширении 1С отличается от аналогичного процесса в основной конфигурации. Ситуация осложняется, когда доработки вносятся не в «обычное», а в поставляемое расширение.

26.06.2026    2245    1c-izh    3    

5

Рефакторинг и качество кода Программист Россия Бесплатно (free)

Code review в 1С часто превращается в спор вкусов: “мне не нравится”, “переделай”, “так не делают”. В статье разбираю другой подход: проверять не разработчика, а риск для системы. Показываю, как формулировать замечания без токсичности, где заканчивается личное предпочтение и начинается реальная проблема, почему ревью должно развивать разработчика, а не только исправлять код

24.06.2026    1411    NikolayMaerov    4    

6
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. gybson 13 20.08.26 10:53 Сейчас в теме
Как из проблемы сделать пять и нагадить на 5 лет вперед - практическое руководство.
2. n_mezentsev 161 20.08.26 12:19 Сейчас в теме
(1) Поясните, в чем нагадить? Использовать фоновые задания нельзя что ли? Это моветон?
3. gybson 13 20.08.26 12:49 Сейчас в теме
(2) Самая простая ситуация - ошибка в коде при записи записки. Моментально получаем ту же самую проблему, которая была. Или ошибка уже после создания записки - куча записок без созданного документа. Или проблема в коде фонового задания и оно возвращает строку "Спасибо за вызов". Или проблема в коде, который вызывается из этого кода. Неопределенность множится кратно и 5% проблем растет кратно. Диагностика затруднена, мы смотрим журнал и не видим единой картины.

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

Т.е. вот взять создание с-ф, например, автоматически при загрузке в БУХ. Ой чё может быть.
4. n_mezentsev 161 20.08.26 13:24 Сейчас в теме
(1)
(3)
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
	ГСЧ = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
	Решка = ГСЧ.СлучайноеЧисло(1, 10);
	Если Решка > 5 Тогда
		ВызватьИсключение "Вам выпала решка";
	КонецЕсли;
КонецПроцедуры

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
	ВызватьИсключение "Что-то пошло не так";
КонецПроцедуры
Показать

Да, при записи служебки иногда происходит ошибка, тогда идет отказ при записи счета, только и всего. А у вас сплошные фантазии, не нужно бояться фоновых заданий, они точно также возвращают хоть отказ, хоть любое другое сериализуемое значение. Да, бывают очень-очень редкие случаи, когда фоновое задание таки вернет Неопределено, но тогда тоже Отказ, если вы не заметили.
P.S. начальник не злой, просто пример дурацкий привел, наверное
5. gybson 13 20.08.26 13:42 Сейчас в теме
(4) Так он и раньше происходил. Если документ записать 10 раз, сколько записок создастся?

Вы создали подписку на неприятности. Очень много вариантов что пойдет не так и чего не хватит. При неумелом использовании, да еще внутри команды, можно будет год или два блох ловить.
6. n_mezentsev 161 20.08.26 14:20 Сейчас в теме
(5) Фоновое задание запускается и выполняется в процессе записи (не в фоне), поэтому создастся в любом случае только одна записка - то есть до момента, когда поле не будет заполнено. Так что все нормально, мы просто передаем работу в другой сеанс и ждем, пока он доделает свою работу и четко отчитается о результатах!
9. gybson 13 21.08.26 11:10 Сейчас в теме
(6) Сейчас, судя по коду, при ошибке записи основного документа, записка будет все-равно создана. Т.е. нужен еще второй вызов фонового задания, который удалит лишний документ. Это еще более усложнит код и дальнейшее его развитие. Если вы что-то пишете в журнал, вам нужен +1 человек в штат, который будет контролировать журнал, иначе вам придется это делать, а у вас своей работы полно и значит все-равно нужен еще человек. Плюс накладные расходы на "ловлю блох", когда в неделю раз-два спрашивают откуда взялся документ или наоборот не взялся. Если применить этот механизм еще 2-3 раза, то проще будет уволиться, чем разгребать последствия. И не дай Бог кто-то массово перезапишет документы за год и тогда всплывет ошибка.
10. n_mezentsev 161 21.08.26 12:07 Сейчас в теме
(9) Зачем вызов, поле ДокументОснование запишется независимо от успешности проведения, а значит лишний он будет только если человек откажется от создания счета вовсе - тогда уже вопрос к человеку, почему он записал служебную записку (он понимает это) и не пометил ее как ненужную. Но я так понимаю, вам заходит транзакционность события записи, да осознанно от нее отходим, потому что она начинает мешать своей строгостью. Журнал мониторю постоянно, это обычно минут 5-10 максимум в день при какой-то сотне пользователей, ну а если серьезная ошибка, то да включаюсь в работу до победного (зато бывают случаи, вот сегодня последний, когда ко мне приходят с ошибкой, а я уже ее исправил - говорю "Перезапустите 1С")
7. bulpi 218 20.08.26 16:39 Сейчас в теме
Нужно устранить те 5% ошибок, а не городить целую подсистему, чтобы их обойти. Какой-то треш.
8. n_mezentsev 161 20.08.26 16:51 Сейчас в теме
(7) Ох, не цените вы простоту обращения к фоновым заданиям, если для вас это городить систему. А в том, что касается 5% легко сказать, да трудно сделать (в оригинале я сократил этот процент, но не думаю, что до 0, потому что некоторые вещи без человеческого участия не решить)))
Для отправки сообщения требуется регистрация/авторизация