Загадочное исполнение кода

1. botokash 396 31.07.19 10:47 Сейчас в теме
Коллеги, столкнулся с необычной ситуацией, которую не могу понять.

Ниже привожу полный код процедуры, которая должна выгрузить данные по правилам КД2, разбив сами данные на пакеты.

&НаСервере
Процедура ВыгрузитьДанные()
    
    ВсеПакетыВыгружены = Ложь;
    
    Пока НЕ ВсеПакетыВыгружены Цикл
        
        Обработка = ВнешниеОбработки.Создать(Объект.ПутьККаталогуВыгрузки + "УниверсальныйОбменДаннымиXML.epf", Ложь); 
        //Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();
    
        Обработка.РежимОбмена = "Выгрузка";
        Обработка.ИмяФайлаПравилОбмена = Объект.ПутьКФайлуПравил;
        Обработка.ЗагрузитьПравилаОбмена();

        СтрокаДатаВыгрузки = Обработка.ТаблицаНастройкиПараметров[0];
        СтрокаДатаВыгрузки.Значение = Объект.ДатаВыгрузки;

        СтрокаКодПервый = Обработка.ТаблицаНастройкиПараметров[1];
        СтрокаКодПоследний = Обработка.ТаблицаНастройкиПараметров[2];
    
        Обработка.ИмяФайлаОбмена = Объект.ПутьККаталогуВыгрузки + "пакет_" + Формат(Объект.ТекКодПервый, "ЧДЦ=0; ЧГ=") + "_" + Формат(Объект.ТекКодПоследний, "ЧДЦ=0; ЧГ=") + ".xml";
        
        СтрокаКодПервый.Значение = Объект.ТекКодПервый;
        СтрокаКодПоследний.Значение = Объект.ТекКодПоследний;
        
        Обработка.ВыполнитьОбменДаннымиВОптимизированномФормате = Истина;
        Обработка.ВыполнитьВыгрузку();

        Обработка = Неопределено;
        
        //
        Если Объект.ТекКодПоследний = Объект.МаксимальныйНомер Тогда
            
            ВсеПакетыВыгружены = Истина;
            
            Прервать;
            
        КонецЕсли;
        
        //
        Объект.ТекКодПервый = Объект.ТекКодПоследний + 1;
        Объект.ТекКодПоследний = Объект.ТекКодПоследний + Объект.ШагПакета;
        
        Если Объект.ТекКодПоследний >= Объект.МаксимальныйНомер Тогда
            Объект.ТекКодПоследний = Объект.МаксимальныйНомер;    
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры
Показать


Процедура вызывается из обычной команды формы, никаких нестандартов нет. А проблема следующая - после 5-6 итераций цикла, отладка явно показывает что идет выполнение строки кода Обработка.ВыполнитьВыгрузку();, в настройках отладки стоит остановка по ошибке, но она не срабатывает, а срабатывает точка останова на самой первой строчке процедуры ВсеПакетыВыгружены = Ложь;. Т.е. начинается опять выгрузка с первого пакета, сам наблюдаю что запущенный обработчик создал несколько файлов и гоняет в них выгрузку по кругу. Не могу понять, как может исполнение кода выйти из цикла заново начаться с начала процедуры.

Прикрепил стек вызова такого выхода из цикла, но мне он ничего не дал.
Прикрепленные файлы:
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
8. lefthander 31.07.19 11:13 Сейчас в теме
(1)А где определяется Объект.максимальныйНомер
10. botokash 396 31.07.19 11:16 Сейчас в теме
(8) При создании формы, запросом вытягиваю.
2. VmvLer 31.07.19 10:51 Сейчас в теме
прочел три строки кода

ВсеПакетыВыгружены = Ложь;
    
    Пока НЕ ВсеПакетыВыгружены Цикл
        
        Обработка = ВнешниеОбработки.Создать(Объект.ПутьККаталогуВыгрузки + "УниверсальныйОбменДаннымиXML.epf", Ложь); 


понял, что объект обработки создается в цикле всякий раз и больше не стал читать бред .
в средние века за такое вели на костер без апелляций.
3. botokash 396 31.07.19 10:53 Сейчас в теме
(2) Это уже 3я или 4я попытка хоть как-то изменить и понять ситуацию, в первоначальном варианте все было как надо. Если нечего сказать по существу - лучше промолчать.
4. VmvLer 31.07.19 10:58 Сейчас в теме
(3) в первоначальном варианте тоже было недопонимание, что такое объект внешней обработки и как он регистрируется в системе.

ключ неполадки в непонимании физики процесса, а он очень простой если почитать хотя бы СП и подумать чуть глубже.
5. YannikAlx 28 31.07.19 10:59 Сейчас в теме
Стесняюсь спросить...
Ставили на эти строчки точку останова?
            ВсеПакетыВыгружены = Истина;
            
            Прервать;


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

И все же вернитесь к исходному варианту , где создается выгрузка не в цикле а перед ним, ибо ваш теперешний вариант точно еще бредовее,
поскольку именно по этой причине в цикле создается новый объект и снова запускается эта же процедура с нуля
6. lefthander 31.07.19 11:12 Сейчас в теме
(5)Итак по коду видно, и по описанию что туда ни разу не попадает ;)
13. botokash 396 31.07.19 11:22 Сейчас в теме
(5) Подключать внешнюю обработку или использовать встроенную - вопрос лишь быстродействия, а у меня другая проблема. Если вы не поняли, запущенная процедура вызывается лишь раз, в команде формы, она должна прокрутить цикл и завершиться, а у меня она начинается с самого начала даже когда не завершился ее же цикл.
17. VmvLer 31.07.19 11:40 Сейчас в теме
(13) (16) Суть неполадки именно в непонимании физики подключения внешней обработки.

я могу написать это еще пару раз пока вы будете искать причину в другом.
20. botokash 396 31.07.19 11:51 Сейчас в теме
(17) Я уже приводил тот код, где вызывается встроенная обработка. Результат один и тот же.
7. botokash 396 31.07.19 11:13 Сейчас в теме
&НаСервере
Процедура ВыгрузитьДанные()
    
    ВсеПакетыВыгружены = Ложь;
    
    ТекКодПервый = 1;
    ТекКодПоследний = Объект.ШагПакета - 1;
    
    Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();
    
    Обработка.РежимОбмена = "Выгрузка";
    Обработка.ИмяФайлаПравилОбмена = Объект.ПутьКФайлуПравил;
    Обработка.ВыполнитьОбменДаннымиВОптимизированномФормате = Истина;
    Обработка.ЗагрузитьПравилаОбмена();
 
    СтрокаДатаВыгрузки = Обработка.ТаблицаНастройкиПараметров[0];
    СтрокаДатаВыгрузки.Значение = Объект.ДатаВыгрузки;
    
    СтрокаКодПервый = Обработка.ТаблицаНастройкиПараметров[1];
    СтрокаКодПоследний = Обработка.ТаблицаНастройкиПараметров[2];
    
    Пока НЕ ВсеПакетыВыгружены Цикл
        
        Обработка.ИмяФайлаОбмена = Объект.ПутьККаталогуВыгрузки + "пакет_" + Формат(ТекКодПервый, "ЧДЦ=0; ЧГ=") + "_" + Формат(ТекКодПоследний, "ЧДЦ=0; ЧГ=") + ".xml";
        
        СтрокаКодПервый.Значение = ТекКодПервый;
        СтрокаКодПоследний.Значение = ТекКодПоследний;
        
        Обработка.ВыполнитьВыгрузку();
        
        Если ТекКодПоследний = Объект.МаксимальныйНомер Тогда
            ВсеПакетыВыгружены = Истина;
        КонецЕсли;
        
        ТекКодПервый = ТекКодПоследний + 1;
        ТекКодПоследний = ТекКодПоследний + Объект.ШагПакета;
        
        Если ТекКодПоследний >= Объект.МаксимальныйНомер Тогда
            ТекКодПоследний = Объект.МаксимальныйНомер;    
        КонецЕсли;
        
    КонецЦикла;
    
    Обработка = Неопределено;
    
КонецПроцедуры

Показать


Вот первоначальный вариант. Выгрузка в цикле нужна что бы разбить данные на пакеты, т.е. в ПВД предусмотрены необходимые параметры, которые отбирают данные. УниверсальныйОбменДаннымиXML это штатная обработка, если ей выгружать вручную никаких проблем нет, просто отнимает много времени что бы все пакеты выгрузить, а стоит задача сделать автомат и ночью формировать пакеты.
9. lefthander 31.07.19 11:16 Сейчас в теме
(7)
Объект.МаксимальныйНомер
где задается это значение? Потому как на него завязана остановка цикла
11. botokash 396 31.07.19 11:18 Сейчас в теме
(9) При создании формы запросом вытягиваю, значение явно заполняется, но до его границ даже близко не доходит.
12. YannikAlx 28 31.07.19 11:22 Сейчас в теме
(7) Это условие очень не красивое!

Если ТекКодПоследний = Объект.МаксимальныйНомер Тогда

Должно быть >=
Равенство вещь скользкая, тем более , что вы Шаг задаете где-то и он может отличаться от 1...
starjevschik; +1 Ответить
14. botokash 396 31.07.19 11:26 Сейчас в теме
(12) Сколько же вас, ценителей красоты) а код прочитать?)

Если ТекКодПоследний >= Объект.МаксимальныйНомер Тогда
       ТекКодПоследний = Объект.МаксимальныйНомер;    
КонецЕсли;



ТекКодПоследний всегда будет равен Объект.МаксимальныйНомер в конце цикла. Проблема в другом, цикл до конца даже не отрабатывает. Из 39 необходимых итераций проходят только 5-6, и процедура, а не цикл, начинаются заново.
15. YannikAlx 28 31.07.19 11:32 Сейчас в теме
(14)Дело не в красоте а в неоднозначности вашего кода (По вашему же утверждению!)
Так может писать просто и однозначно?

 ТекКодПервый = ТекКодПоследний + 1;
   ТекКодПоследний = ТекКодПоследний + Объект.ШагПакета;

   Если ТекКодПоследний > Объект.МаксимальныйНомер Тогда
            ВсеПакетыВыгружены = Истина;
            ТекКодПоследний = Объект.МаксимальныйНомер; 
            Прервать;
        КонецЕсли;
       
        
    КонецЦикла;

Показать
16. botokash 396 31.07.19 11:35 Сейчас в теме
(15) Если не поняли, объясняю еще раз. Проблема не с тем, что я не могу придумать нормальное условие выхода из цикла, десятки вариантов, которые будут работать, тут без разницы. Проблема в том, что ПРОЦЕДУРА начинается с самого начала, когда цикл еще не завершен.
18. YannikAlx 28 31.07.19 11:45 Сейчас в теме
(16) ну так поставьте точку останова ПЕРЕД входом в свою процедуру

Процедура ВыгрузитьДанные(),
вот и увидите когда происходит вход в нее...
19. botokash 396 31.07.19 11:49 Сейчас в теме
(18) Я с самого начала приложил скрин стека вызова, в том-то и дело, что вызов процедуры происходит из обработчика команды формы на клиенте, та точка останова срабатывает один раз, а вот точка останова внутри начала процедуры 2 и более.
21. YannikAlx 28 31.07.19 11:56 Сейчас в теме
(19) Попробуйте банально переименовать
Процедура ВыгрузитьДанные()....
Уж коли бред , и надо самому бредить...
22. RustamZz 31.07.19 11:56 Сейчас в теме
(19) Очевидно же что проблема не с этим кодом, а с тем который мы не видим. Не может процедура вместо выхода из цикла начать выполнение заново сама по себе. Или всю обработку выкладывайте или ищите сами.
YannikAlx; +1 Ответить
23. YannikAlx 28 31.07.19 11:59 Сейчас в теме
(22) Пожтому и предложил переименовать Процедуру, чтобы отмахнуться от невидимого кода...
Мы видим ВыгрузитьДанные() в команде, а кто его знает, может она еще где вызывается.....
24. botokash 396 31.07.19 12:06 Сейчас в теме
(23) Обработка УниверсальныйОбменДаннымиXML есть в любой типовой. Моя обработка просто программно ее вызывает. Вот модуль формы моей обработки, там кода кот наплакал, что бы в нем что-то подозревать. Кстати, попробовал переименовать, не помогло.

&НаСервере
Процедура ВыгрузитьДанные111()
    
    ВсеПакетыВыгружены = Ложь;
    
    ТекКодПервый = 1;
    ТекКодПоследний = Объект.ШагПакета - 1;
    
    Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();
    
    Обработка.РежимОбмена = "Выгрузка";
    Обработка.ИмяФайлаПравилОбмена = Объект.ПутьКФайлуПравил;
    Обработка.ВыполнитьОбменДаннымиВОптимизированномФормате = Истина;
    Обработка.ЗагрузитьПравилаОбмена();
 
    СтрокаДатаВыгрузки = Обработка.ТаблицаНастройкиПараметров[0];
    СтрокаДатаВыгрузки.Значение = Объект.ДатаВыгрузки;
    
    СтрокаКодПервый = Обработка.ТаблицаНастройкиПараметров[1];
    СтрокаКодПоследний = Обработка.ТаблицаНастройкиПараметров[2];
    
    Пока НЕ ВсеПакетыВыгружены Цикл
        
        Обработка.ИмяФайлаОбмена = Объект.ПутьККаталогуВыгрузки + "пакет_" + Формат(ТекКодПервый, "ЧДЦ=0; ЧГ=") + "_" + Формат(ТекКодПоследний, "ЧДЦ=0; ЧГ=") + ".xml";
        Обработка.ИмяФайлаПротоколаОбмена = Объект.ПутьККаталогуВыгрузки + "протокол_" + Формат(ТекКодПервый, "ЧДЦ=0; ЧГ=") + "_" + Формат(ТекКодПоследний, "ЧДЦ=0; ЧГ=") + ".txt";
        
        СтрокаКодПервый.Значение = ТекКодПервый;
        СтрокаКодПоследний.Значение = ТекКодПоследний;
        
        Обработка.ВыполнитьВыгрузку();
        
        Если ТекКодПоследний = Объект.МаксимальныйНомер Тогда
            ВсеПакетыВыгружены = Истина;
        КонецЕсли;
        
        ТекКодПервый = ТекКодПоследний + 1;
        ТекКодПоследний = ТекКодПоследний + Объект.ШагПакета;
        
        Если ТекКодПоследний >= Объект.МаксимальныйНомер Тогда
            ТекКодПоследний = Объект.МаксимальныйНомер;    
        КонецЕсли;
        
    КонецЦикла;
    
    Обработка = Неопределено;
    
КонецПроцедуры

&НаКлиенте
Процедура ВыгрузитьОстатки(Команда)
    ВыгрузитьДанные111();
КонецПроцедуры

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Объект.ПутьКФайлуПравил = "тут путь\ПравилаОбменаДаннымиУТ_ТТ.xml";
    Объект.ПутьККаталогуВыгрузки = "тут путь\";
    Объект.ШагПакета = 100000;
    Объект.ДатаВыгрузки = Дата(2019, 06, 30);
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    МАКСИМУМ(ТД_БалансовыеСчетаУчастниковПЛ.Код) КАК Код
    |ИЗ
    |    Справочник.ТД_БалансовыеСчетаУчастниковПЛ КАК ТД_БалансовыеСчетаУчастниковПЛ";
    
    ВыборкаПоиск = Запрос.Выполнить().Выбрать();
    
    Если ВыборкаПоиск.Следующий() Тогда
        Объект.МаксимальныйНомер = ВыборкаПоиск.Код;
    КонецЕсли;
    
КонецПроцедуры

Показать
25. VmvLer 31.07.19 12:07 Сейчас в теме
примерно так я выполняю внешние отчеты программно в потоках или итерациях

...
// Создание экземпляра внешего отчета объекта штатным методом ВнешниеОтчеты.Подключить()
ОбъектОписанияЗащиты = Новый ОписаниеЗащитыОтОпасныхДействий;
ОбъектОписанияЗащиты.ПредупреждатьОбОпасныхДействиях = Ложь;  // Отключает предупреждения защиты при работе с COMОбъект и т.д. независимо от настроек пользователя и информационной базы

//ОтчетИмя = ВнешниеОтчеты.Подключить(ОтчетАдрес,,Ложь);      // Будет использовано имя, содержащееся в самом отчете
ОтчетИмя = ИмяОбъекта+"_"+СтрЗаменить(Строка(ТекущаяУниверсальнаяДатаВМиллисекундах()), Символы.НПП,""); // Например, получим строку вида "ОтчетПоАкциямСКД_63636735405379", где число - это количество миллисекунд текущей даты строкой
ВнешниеОтчеты.Подключить(ОтчетАдрес, ОтчетИмя, ОтчетСсылка.БезопасныйРежим, ОбъектОписанияЗащиты);  // Благодаря уникальному имени в системе будет зарегистрирован уникальный объект для итерации или потока
ОтчетОбъект = ВнешниеОтчеты.Создать(ОтчетИмя, ОтчетСсылка.БезопасныйРежим);

...
ОтчетОбъект.СкомпоноватьРезультат(ДокументРезультат, ДанныеРасшифровкиОбъект);
Показать


может комментарии вызовую у вас работу мысли.
26. botokash 396 31.07.19 12:23 Сейчас в теме
(25) Спасибо за пример, но я уже выше приводил код, где использовалась встроенная в конфигурацию обработка, а не подключалась внешняя.
Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();

Результат один и тот же.
27. VmvLer 31.07.19 12:50 Сейчас в теме
(26) экземпляр обработки один и тот же посему и результат один и тот.
28. botokash 396 31.07.19 12:56 Сейчас в теме
(27)

ОбработкаМенеджер.<Имя обработки> (DataProcessorManager.<Имя обработки>)
Создать (Create)
Синтаксис:

Создать()
Возвращаемое значение:

Тип: ОбработкаОбъект.<Имя обработки>.

Описание:

Создает новый экземпляр обработки.

Доступность:

Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Пример:

ОбработкаДокументов = Обработки.ОбработкаДокументов.Создать();
Показать


СП говорит что экземпляр создается новый. Или вы имеете ввиду что-то другое?
29. VmvLer 31.07.19 13:02 Сейчас в теме
(28) в ваших примерах кода он один - это все равно, что пытаться приготовить в одной кастрюле борщ, пельмени и компот.
как бы ни крутили конфорку все равно будет борщ)
30. botokash 396 31.07.19 13:08 Сейчас в теме
(29) Я делал создание обработки и внутри цикла. Т.е. каждая новая итерация это новый экземпляр обработки. Это тоже не помогало.
31. VmvLer 31.07.19 13:19 Сейчас в теме
(30) отладчик в руки и проверять вдумчиво - у вас уже есть все вводные для получения результата.
я тоже раньше думал, что все работает как написано)
32. Bit_Man 31.07.19 13:39 Сейчас в теме
Создал внешнюю обработку на подобии, только меняю период в цикле. Всё норм
33. Bit_Man 31.07.19 13:46 Сейчас в теме
Код под твою обработку
&НаСервере
Процедура УстановитьСчетчики(ТекКодПервый, ТекКодПоследний, ШагПакета, МаксимальныйНомер)
    
    ТекКодПервый = ТекКодПоследний + 1;
    ТекКодПоследний = МИН(ТекКодПоследний + ШагПакета - 1, МаксимальныйНомер);
    
КонецПроцедуры

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

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

&НаСервере
Процедура ВыгрузитьДанныеПоПакетам(Обработка, ТекКодПервый, ТекКодПоследний)    
    
    СтрокаКодПервый = Обработка.ТаблицаНастройкиПараметров[1];
    СтрокаКодПоследний = Обработка.ТаблицаНастройкиПараметров[2];
    СтрокаКодПервый.Значение = ТекКодПервый;
    СтрокаКодПоследний.Значение = ТекКодПоследний;
        
    Обработка.ИмяФайлаОбмена = Объект.ПутьККаталогуВыгрузки + "пакет_" + Формат(ТекКодПервый, "ЧДЦ=0; ЧГ=") + "_" + Формат(ТекКодПоследний, "ЧДЦ=0; ЧГ=") + ".xml";    
    Обработка.ВыполнитьВыгрузку();
    
КонецПроцедуры
Показать
user1145086; +1 Ответить
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот