Обсуждение накопленного

Автор Харлампий Дымба, 14 октября 2025, 01:31

« назад - далее »

Злоп

Еще если помните - почему UCHOICE падал с закрытием 1С при задании даты в условие отбора?

cr

Цитата: Харлампий Дымба от 01 ноября 2026, 02:07Не знаю как лучше классифицировать этот баг 1С
Что тут не понятного?
Эта форма подбора работает в специфическом режиме. ПриЗакрытии() отрабатывает процедуру переноса ТЗ подобранного в форму из которой вызван подбор. Если открыты оба окна (и сама форма и подбор), то Окна-Закрыть все окна сначала закрывает "родительскую" форму, вызвавшую подбор, а потом саму форму подбора, которая при закрытии пытается заполнить реквизиты "родительской" формы и неожиданно "обнаруживает", что "родительская" форма уже отсутствует и система валится, пытаясь заполнить не существующий реквизит не существующей формы.

Харлампий Дымба

Цитата: cr от 02 ноября 2026, 09:05Что тут не понятного?
В  точку. Именно так я и думал, и именно так же ошибся. Поэтому и не мог долгое время надежно воспроизвести глюк - он то появлялся, то исчезал. Так что - очень правдоподобно, но нет. Механизм проявления сложнее, поэтому и причина возникновения для меня теперь не столь очевидна.
Я же написал - для складов и фирм глюк не возникает, а для товаров и контрагентов - возникает. И ключевое различие там - п.3

Цитата: Злоп от 02 ноября 2026, 06:45почему UCHOICE падал с закрытием 1С при задании даты в условие отбора
Не увидел. Как воспроизвести? Попробовал из типовой обработку "ПодборОбъектов" (полный аналог UChoice), сделал подбор по документам с отбором по нескольким датам - всё нормально прошло.
Но вангую, что если ошибка есть, то она скорее всего связана с некорректным синтаксисом построенного запроса (там же UChoice пытается данные именно с помощью черного запроса получить. Мы разбирались здесь с подобной ерундой, возможно и с датой похожее.



Злоп

Цитата: cr от 02 ноября 2026, 09:05
Цитата: Харлампий Дымба от 01 ноября 2026, 02:07Не знаю как лучше классифицировать этот баг 1С
Что тут не понятного?
Эта форма подбора работает в специфическом режиме. ПриЗакрытии() отрабатывает процедуру переноса ТЗ подобранного в форму из которой вызван подбор. Если открыты оба окна (и сама форма и подбор), то Окна-Закрыть все окна сначала закрывает "родительскую" форму, вызвавшую подбор, а потом саму форму подбора, которая при закрытии пытается заполнить реквизиты "родительской" формы и неожиданно "обнаруживает", что "родительская" форма уже отсутствует и система валится, пытаясь заполнить не существующий реквизит не существующей формы.

Здесь при переносе надо видимо сделать просто проверку существования родительского контекста...

Злоп

Цитата: Злоп от 02 ноября 2026, 06:45Еще если помните - почему UCHOICE падал с закрытием 1С при задании даты в условие отбора?

Не, тут падает не всегда... Как-то выборочно\специфически тоже...

Харлампий Дымба

Цитата: Злоп от 03 ноября 2026, 03:45надо видимо сделать просто проверку существования родительского контекста.
Да, не чего-то не получается ничего. Ну то есть интересно придумать латку, чтоб избегать такой ситуации, но пока у меня решения нет.

Кстати, выяснилась ещё одна деталь - обязательное условие:

п.6 в форме подбора должна быть процедура ПриЗакрытии()

на ней и валится. Пустая она или там есть код не важно - валится от её наличия. Если этой процедуры нет, то падения не происходит. Всё чудесатее и чудесатее.

cr

Чё как дети?
Есть 2 способа организации подбора. Обычный и специальный.
Можно просто ОткрытьПодбор() и здесь же (в "родительской" форме) в предопределенной процедуре ОбработкаПодбора() задать действия с выбранной строкой из списка подбора. Так чаще всего и делается, при этом если режим НЕполноэкранный и сделать видимыми в окне обе формы (и "родительскую" и форму списка), видно как при выборе строки в форме подбора, она сразу "попадает" в "родительскую" форму. В каком порядке эти формы будут закрываться - по барабану.
А можно иначе. Если в форме подбора в ПриОткрытии() установить ОбработкаВыбораСтроки() в 1, ОбработкаПодбора() в "родительской" форме срабатывать не будет, зато в форме подбора начнет срабатывать предопределенная процедура ПриВыбореСтроки(), в которой и задаются действия с выбранной строкой. В этом варианте подобранные значения из формы подбора автоматически "отправляются" в "родительскую" форму из ПриЗакрытии() (- а как еще-то?). 1С валится из ПриЗакрытии() формы подбора, когда совершает там недопустимую операцию с закрытой "родительской" формой.

Злоп

для начала надо выяснить валится на ПриЗакрытии() - на каком этапе? вход в процедуру успешен, валится на завершении? или как? если выяснится что вход в ПриЗакрытии успешен - то дальше можно пытаться играться с контекстом родительской формы, которую передавать через параметры при вызове подбора

Харлампий Дымба

Цитата: cr от 03 ноября 2026, 19:49Чё как дети?
Не, ОбработкаВыбораСтроки() тут тоже не причём.
Но и у меня чё-то поплыли все рассуждения тоже. Многоуровневость оказывается не обязательна, проблема возникает если форму подбора дернуть из родительской формы после ОткрытьПодбор() по любому поводу, а в форме подбора (обычная форма списка справочника) есть процедура ПриЗакрытии.

Стенд:
Справочник.Новый1 - все установки по умолчанию, форма списка со следующим модулем:
Процедура ПриЗакрытии() //если нет этой процедуры - ошибки не будет
//код есть или кода нет - не важно
КонецПроцедуры
Отчет.Новый1 - все установки по умолчанию, модуль формы:
Процедура Сформировать()
    Перем ФормаПодбора;
    ОткрытьПодбор("Справочник.Новый1",,ФормаПодбора,1);//если 0 - ошибки не будет
    ФормаПодбора.Сортировка("Код"); //если нет обращения к форме - ошибки не будет                                    
КонецПроцедуры

Запускаем Отчет.Новый1, нажимаем Сформировать, выводим форму отчета на передний план, Окна-Закрыть все, падаем.

Цитата: Злоп от 03 ноября 2026, 21:57если выяснится что вход в ПриЗакрытии успешен - то дальше можно пытаться играться с контекстом родительской формы
Вход-то успешен, только вот родительской формы уже не существует, так что играться не с чем и мы в любом случае свалимся в ошибку. Есть вариант избежать, но абсолютно некрасивый.


cr

Если в форме подбора есть ПриЗакрытии(), то после захода в неё, курсор вернется обратно в "родительскую" форму (скорее всего, на строку "родительской" формы следующую после ОткрытьПодбор(), но может, еще куда-то, ПриПовторномОткрытии(), например), а если "родительской" формы уже нет, курсору некуда вернуться и он роняет 1С.
Отладчик в руки и вперед ...

Харлампий Дымба

Цитата: cr от Вчера в 00:20Отладчик в руки и вперед
Сообщением выше - тестовый стенд. Там ровно 8 строчек на 2 модуля, из них только две строчки выполняют инструкцию. В какую строку нужно поставить точку останова и какой параметр отследить? Да и как это поможет?

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

Универсальная заглушка на ошибку - с помощью Formex + недокументированного КонтекстПодбора:
Процедура Глобальная_ПриЗакрытии(Конт)
	Если ТипЗначения(Конт.КонтекстПодбора) = 100 Тогда // может быть стоит обернуть в Попытку
		Если Конт.КонтекстПодбора.Форма.РежимВыбора() = 2 Тогда
			СтатусВозврата(0);
		КонецЕсли;	
	КонецЕсли;	
КонецПроцедуры



cr

Цитата: Харлампий Дымба от Вчера в 22:14В какую строку нужно поставить точку останова
Да, ёклмн!
Конечно в строку
еклмн=1;
в ПриЗакрытии() в форме побора.
Затем руками закрываешь форму подбора и по F8 смотришь куда она (когда не падает) пойдет после ПриЗакрытия()
В "родительской" форме тоже нужно создать всякие предопределенные процедуры с заглушками
а=1;
И тогда в том месте, куда она уходит в "родительской" форме можно поставить ловушку из переменной, объявленной в "родительской" форме:

Перем КонтекстФормы;

Процедура Сформировать()

    ОткрытьПодбор(<Объект>,<ИмяФормы>,КонтекстФормы,<ФлагМножВыбора>,<ТекЗнач>):
    а=1;

 //   ОткрытьПодбор("Справочник.Новый1",,ФормаПодбора,1);//если 0 - ошибки не будет
 //   ФормаПодбора.Сортировка("Код"); //если нет обращения к форме - ошибки не будет                                    
КонецПроцедуры

Процедура ПриЗакрытии() 
     Если 0+ТипЗначения(КонтекстФормы) = 100 Тогда
         СтатусВозврата(0);
     КонецЕсли;
КонецПроцедуры

Чтобы при первой попытке Окна - закрыть все , форма подбора закрылась, а "родительская" форма осталась открытой. И ничего не упадет. Со второй попытки Окна - закрыть все, "родительская форма тоже закроется без падения.
Все пункты с условиями - в топку! Они не при делах. Все формексы, попытки-исключения и недокументированные возможности - туда же, куда и условия.

Харлампий Дымба

Цитата: cr от Сегодня в 00:02смотришь куда она (когда не падает) пойдет после ПриЗакрытия()
НИКУДА. Зачем 3 раза отправлять меня в Отладчик, если можно убедиться, что там нечего ловить?

Цитата: cr от Сегодня в 00:02Чтобы при первой попытке Окна - закрыть все , форма подбора закрылась, а "родительская" форма осталась открытой
Цитата: Харлампий Дымба от 03 ноября 2026, 23:40Есть вариант избежать, но абсолютно некрасивый.
Вот именно этот вариант со СтатусомВозврата(0) в ПриЗакрытии родительской формы мне и не понравился, поэтому и приводить не стал.
Не понравился по многим причинам:
Ты не закроешь родительскую форму обычным способом, если открыта дочерняя (крестиком, кнопкой Закрыть, Окна-Закрыть). Надо будет обязательно закрыть дочернюю, хотя раньше этого не требовалось - это неудобно.
То же самое касается и всех других вариантов открытия дочерней формы: в режиме одиночного подбора, без обращения к контексту дочерней формы.
Пользователь может спокойно ткнуть в несколько подборов в одном отчете в той же типовой ТиС (склад, номенклатура), а "Перем ФормаПодбора" на всех одна.
В той же типовой ТиС вызов идёт в глобальной процедуре - там ещё больше вариантов налететь на протухшую переменную.
И самое главное: этот код надо вставлять в ПриЗакрытии() во все модули, где есть ОткрытьПодбор(), а в случае типовой ТиС - всюду, где возможен вызов глРаботаСТаблицейМФ - т.е. во все отчеты.

Ну собственно первое и последнее - определяющее.
С другой стороны, использование ванильной 1С - это плюсик.

Условия возникновения глюка перечислены, заглушки придуманы.
Механизм возникновения сам больше ковырять не буду - знаний не хватает.