Форум Кладовочки АЛьФ`а

Общие вопросы => 7.7 => Тема начата: Харлампий Дымба от 14 октября 2025, 01:31

Название: Обсуждение накопленного
Отправлено: Харлампий Дымба от 14 октября 2025, 01:31
Вот Сергей копит в копилку (https://forum.dorex.pro/index.php?topic=191.0), а обсуждать там не разрешает.  Пусть будет тема для небольшого полуфлуда - обо всём и ни о чём. Шепотом.
Не только для копилки - потому что иногда натыкаешься на какую-нибудь интересную неожиданную ерунду, забавный пустяк, а может кому пригодится.

Вот про то, что Записать недокументировано возвращает значение (https://forum.dorex.pro/index.php?topic=191.46), если применяется к элементу / документу локального контекста (а не созданному через СоздатьОбъект), оказалось интересно. Даже никогда не задумывался, что будет, если не заморачиваться с
Если Форма.ТолькоПросмотр() = 1 Тогда
 Форма.КнопкаОК.Доступность(0);
КонецЕсли;
А оказалось, что ничего не будет. Если форма открыта в режиме чтения (только на просмотр), то и Записать() и #Записать будут проигнорированы.  Так что использование Доступность(0) - просто способ показать пользователю, что нажимать кнопку бесполезно.

Ну и кстати #Записать и Записать() неравнозначны, вопреки тому что написано в als (там так: "данный метод отрабатывает те же действия, что и интерактивное нажатие пользователем кнопки с формулой ''#Записать''")
Записать() не вызывает ПриЗаписи() и игнорирует некоторые установки записи, типа СохранениеПериодическихРеквизитов(). Но вот ПриЗаписиПерепроводить(1) и АвтоВремя..(), а также регистрацию события в "Журнале регистрации" оба варианта отрабатывают одинаково. Ещё раз акцентирую, что Записать() - именно в локальном контексте, а не к созданному через СоздатьОбъект().

Записать() возвращает ноль не только, если форма открыта в режиме чтения, но и при нарушении уникальности кода. Правда, в этом случае всё равно выдаётся интерактивное окошко предупреждения "Код не уникальный", поэтому использовать Записать() для программной проверки возможности записи - не очень хорошо.
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 14 октября 2025, 10:45
Написал, перечитал, задумался. Если ПриЗаписиПерепроводить(1) действует на Записать() локального контекста, то, значит я всё это время неправильно делал запись с перепроводением из формы документа:
Записать();
Если Проведен() = 1 Тогда
 Провести();
КонецЕсли;
В этом коде две проблемы:
1) двойное перепроведение, если ПриЗаписиПерепроводить() было установлено в единичку;
2) надо городить огород с единой транзакцией, чтобы не получилось, что реквизиты в документ записаны новые, а проведение документа, в случае неудачи, осталось по старым.
Подобную реализацию можно увидеть в процедуре ПечатьЧека() в ПКО и РКО в типовой Тис, например.

Правильный код для записи с перепроведением из модуля формы документа такой:
ЗапомнимПриЗаписиПерепроводить = ПриЗаписиПерепроводить(1);
Результат = Записать();//записывает и при необходимости перепроводит
ПриЗаписиПерепроводить(ЗапомнимПриЗаписиПерепроводить);
В этом случае документ будет при необходимости перепроведён, а в случае неудачного перепроведения - запись не состоится. И, что замечательно, Записать() вернёт 0 в случае неудачного перепроводения, а не только в случае неудачной записи.
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 22 октября 2025, 10:23
Наткнулся у себя на баг 1С, про который не слышал раньше: итог по колонке может быть у нечисловой колонки.
Воспроизведение:
При втором сохранении получаем сообщение, что изменено построение итогов по колонке, в диалоговой форме реквизита галка "Итог по колонке" визуализирована сброшенной. Но - это не так: в описании структуры метаданных "ИтогПоКолонке" равен 1, а проблемный реквизит присутствует в заголовочной таблице документа DH*.DBF. То есть итоги продолжают "считаться".

Лечение: поменять что-нибудь (идентификатор) в реквизите и вернуть назад - при сохранении будет выполнена уже нормальная реструктуризация.

Код для проверки на наличие проблемных реквизитов:
Для СчДокументов = 1 По Метаданные.Документ() Цикл
    МетаДок = Метаданные.Документ(СчДокументов);
    Для СчРеквизитов = 1 По МетаДок.РеквизитТабличнойЧасти() Цикл
        МетаРекв = МетаДок.РеквизитТабличнойЧасти(СчРеквизитов);
        Если (МетаРекв.Тип <> "Число") и (МетаРекв.ИтогПоКолонке = 1) Тогда
            Сообщить(МетаДок.Идентификатор + "." + МетаРекв.Идентификатор);
        КонецЕсли;
    КонецЦикла;
КонецЦикла;
   
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 22 октября 2025, 13:46
Мсье знает толк в извращениях!
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 22 октября 2025, 17:08
Цитата: Злоп от 22 октября 2025, 13:46Мсье знает толк в извращениях!
Согласен. Описал так, как будто это было намеренное издевательство над конфигуратором и здравым смыслом. Но всё было наоборот, это 1С поиздевалось надо моим здравым смыслом:
Увидел опечатку в комментарии к реквизиту табличной части, ну типа "Поздразделение ЦФО" и решил поправить. При сохранении - сообщение "изменено построение итогов по колонке...". И меня стопарнуло: какой пересчет итогов, если у я лишь поменял Комментарий к реквизиту типа "Справочник.Подразделения"?!
Просто такие баги могут быть достаточно вредными, система тебе визуально показывает одно, а сама делает другое. Тратит ресурсы на сохранение и подсчет итогов, там где их отродясь не было и не будет.

Вот ещё одни вредный баг из этой же серии (показываю одно, делаю другое):
Думаю зачем мне две формы списка справочника "ФормаСпискаОсновная" и "ФормаСпискаДляВыбора"? Удаляю "ФормаСпискаДляВыбора", при этом галочка "основная форма для выбора" перескакивает на "ФормаСпискаОсновная". Сохраняюсь, всё отлично, теперь у меня единая форма для обоих режимов работы.
А вот и нет - "основная форма для выбора" не установлена и система рисует пользователям свою корявую форму "по умолчанию".

Ну а в целом изврат, правда. Просто иногда есть рабочее время и желание не работать. На днях чУдно провёл время разбираясь с багом, известным в основном, как "Перестал отображаться автор в общем журнале". Вылечить - 2 минуты, придумать отчетик, проверяющий базу на наличие проблемы - 2 часа, определить причину возникновения - 2 дня. Зато - кайф, раскрыл ещё один мало кому уже нужный секрет.
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 22 октября 2025, 17:30
И почему перестал отображаться автор в ОЖ?
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 22 октября 2025, 17:31
Я на ряд ошибок и граблей просто тупо не наступал. Просто потому что делал как надо, а как не надо - не делал...
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 22 октября 2025, 17:35
Кстати, а итог-то по нечисловым колонкам считает? По идее тупо суммировать должен и варианта два: либо рухнет в ошибку, либо проссуммирует и получит 0 если содержимое чисто текстовое или какое о число если колонка содержит строковый реквизит, в котором строки типа
123
Петров.
.
А вот как суммирует если агрегатный тип - это интереснее: либо по преобразованию в текстовое представление либо тупо значение ссылки, а там вполне возможно число может быть в начале ссылки...?
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 22 октября 2025, 18:21
Цитата: Злоп от 22 октября 2025, 17:35стати, а итог-то по нечисловым колонкам считает?
Похоже, что так же как и функция Итог() в локальном контексте документа - ставит ноль, если реквизит нечисловой, и считает сумму (кстати, независимо от галки "Итог по колонке" и длины числа). Т.е. для колонки "Мест" Число1.0 функция Итог("Мест") даст 5+5=10.
А вот .Итог() примененный к этому же документу, но полученному через СоздатьОбъект уже полезет в таблицу DH и вернет 5+5=9, либо ошибку, если галка "Итог по колонке" не установлена.

Цитата: Злоп от 22 октября 2025, 17:31...не наступал. Просто потому что делал как надо, а как не надо - не делал...
Враки. Иначе откуда бы ты узнал, как не надо ;) . Однажды наступив - долго обходишь стороной. Зачем разбираться с проблемой, если её можно обходить. Но, чтоб не получалось как в древнем баяне "Тут так принято" про обезьян, бананы и шланг с холодной водой, порой стоит вернуться и, при желании и наличии времени, разобраться: а что именно ты обходишь, надо ли это обходить, и каков радиус. Ну и интересно иногда походить по нехоженным дорожкам.

Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 22 октября 2025, 18:29
Ну и дополню: Итог() по таблице значений работает так:
Если тип значения колонки "Число" - суммирует независимо от заданной длины числа
Если тип значения не задан, то суммирует только если ВСЕ значения в колонке - явно заданные числа.
Во всех остальных случаях - ноль.
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 24 октября 2025, 14:15
Функции - "ложные друзья программиста":
.ОбратныйПорядок() - без параметра.
Для справочника и документа - не делает ничего, постоянно наступаю на эти грабли;
Для периодического - устанавливает обратный порядок текущей (а если нет текущей - то последующей) выборки;
Для регистра - устанавливает обратный порядок последующей выборки.

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

Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 31 октября 2025, 12:20
GComp. Может открою Америку, но как-то с легкой руки Фёдора всегда считал, что Container.Profile (https://1c.alterplast.ru/1cv7md/howto-less.html) - лишний мусор в мдшнике,  ну типа формы элемента для справочников, редактируемого только "в списке".
Оказалось, что это установки по работе с таблицей из диалоговой формы отчета/обработки (ну и пароли при необходимости) и бездумно удалять их не надо.

Состав Container.Profile:
Действия - Свойства формы
MoxelName (Использовать таблицу):
Пустую - "␁Blank"
Для ввода данных - Имя таблицы
MoxelPos (Положение):
0 - во всё окно (по умолчанию)
2 - снизу
3 - сверху
4 - справа
5 - слева
MoxelNextMode (Для ввода данных - Переход по строкам):
0 - нет
1 - по строкам (по умолчанию)
2 - по столбцам
Действия - Установить пароль
UUID:
"D41D8CD98F00B204E9800998ECF8427E" - пароль не установлен
Любые другие значения - хэш пароля?
Entry (Запрашивать пароль при исполнении):
0 - не запрашивать
1 - запрашивать (по умолчанию)

Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 01 ноября 2025, 13:45
Баг «Не показывается колонка общего реквизита в журналах» aka «Исчез автор в общем журнале»
Описание: В непонятное время по непонятным причинам у пользователей перестаёт отоборажаться колонка с общим реквизитом, в конфигураторе – всё чётко.
Лечение: Удалить проблемную колонку – Закрыть форму списка (ЭТО ВАЖНО) – Сохранить – Добавить колонку.
Код для проверки наличия проблемы (программно открываем и закрываем все журналы и смотрим: есть/нет?):
СписокДляПроверки = СоздатьОбъект("СписокЗначений");
Для СчЖурналов = 1 По Метаданные.Журнал() Цикл
    МетаЖурнал = Метаданные.Журнал(СчЖурналов);
    ИдЖурнала = МетаЖурнал.Идентификатор;
    Для СчФорм = 1 По МетаЖурнал.ФормаСписка() Цикл
        ИдФормы = МетаЖурнал.ФормаСписка(СчФорм).Идентификатор;
        СписокДляПроверки.УдалитьВсе();
        Для СчОбщихРеквизитов = 1 По Метаданные.ОбщийРеквизитДокумента() Цикл
            СписокДляПроверки.ДобавитьЗначение(Метаданные.ОбщийРеквизитДокумента(СчОбщихРеквизитов).Идентификатор);
        КонецЦикла;   
        Для СчГраф = 1 По МетаЖурнал.Графа() Цикл
            СписокДляПроверки.ДобавитьЗначение(МетаЖурнал.Графа(СчГраф).Идентификатор);
        КонецЦикла;   
        Конт = "";
        ОткрытьФорму("Журнал."+ИдЖурнала+"."+ИдФормы+"#",Конт);
        Если ТипЗначения(Конт) = 100 Тогда
            Для Сч = 1 По СписокДляПроверки.РазмерСписка() Цикл
                ИмяКолонки = СписокДляПроверки.ПолучитьЗначение(Сч);
                Попытка
                    Конт.Форма.ПолучитьАтрибут(ИмяКолонки);
                Исключение
                    Продолжить;
                КонецПопытки;
                Конт.Форма.ПолучитьАтрибут(ИмяКолонки).Видимость(1);
                Конт.Активизировать(ИмяКолонки,1);
                Если Конт.Форма.ТекущаяКолонка() <> ИмяКолонки Тогда
                    Сообщить("Проблема отображения: "+"Журнал."+ИдЖурнала+"."+ИдФормы+"."+ИмяКолонки);
                КонецЕсли;
            КонецЦикла;
            Конт.Форма.Закрыть(0);
            Конт="";
        КонецЕсли;   
    КонецЦикла;
КонецЦикла;
Сообщить("Проверка завершена.");   

Пространно: заморочка с этим глюком в том, что он появлялся как бы из ниоткуда и в неизвестный момент времени. Юзеры не знают, что в журнале должен быть этот столбец, а программист не знает, что его там не стало. Первый раз, когда столкнулся, списал на рудимент от 7.5, потому что конфа была типовая комплексная 3, в которой осталось 4 журнала, перекочевавших, видимо, через преобразование из 7.5 из первого релиза Комплексной. А недавно, с удивлением, обнаружил этот глюк в своей нетленке. Поэтому, взяв ежедневные бэкапы баз за 23 года, установил день, когда исчез столбец, и проанализировав два соседних мдшника, понял механизм возникновения глюка.
Исходная конфигурация (ИК), два параллельных прямых потомка (П1 и П2). В П1 добавляем любой объект. В П2 добавляем общий реквизит и выводим его в форму списка журнала. Загружаем в П1 через объединение конфигурации. Готово: в П1 битый журнал. В форме списка журнала в конфигураторе столбец виден, а в режиме «1С: Предприятие» не показывается.
Тестовый стенд в пустой пробной: создать документ, журнал, форму списка журнала, разделить на 2 потомка, в первом создать константу, во втором - общий реквизит документов и добавить его в форму списка журнала, накатить мдшник на первый потомок через объединение - баг проявился.
Если разложить проблемный мдшник, то в столбце в значении ИдентификаторМетаданных будет содержать мусорный id (а если «повезёт», то существующий, но от другого объекта).
С какого-то релиза разработчики о глюке узнали, но механизм его возникновения не поняли, и в момент открытия журнала стали просто делать проблемный столбец невидимым. А может и поняли, но по сумме характеристик, решили, что проще так, чем исправлять.
Возникновение глюка вполне укладывается в распространённый механизм обновления типовых, когда свои изменения (и в их числе, например, общий реквизит «Автор», которого так не хватало в типовой бухии) переносишь в новый релиз типовой через объединение, а потом накатываешь на рабочую базу.
То есть причина - в некорректной работе объедения конфигурации: когда замещаешь форму списка журнала документа, то ИдентификаторМетаданных не изменяется вслед за изменением Идентификатора исходного объекта (например, общего реквизита «Автор»), а остаётся как был в накатываемой конфигурации.
Лечение историческое: добрый Ёпрст gcompом(?) менял страждущим ИдентификаторМетаданных на правильный;
Лечение хирургическое: убрать столбец вообще: «вам это не надо»;
Лечение паллиативное: делать такие столбцы текстовыми;
Лечение правильное: в шапке. Но – зараза – если форму списка после удаления не закрыть, то столбец 1С вставит обратно проблемный - из кэша. Обо что многие и спотыкались. И это ещё одна, другая, багофича.
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 01 ноября 2025, 17:50
Вот этого не понял

 ИдентификаторМетаданных не изменяется вслед за изменением Идентификатора исходного объекта (например, общего реквизита «Автор»), а остаётся как был в накатываемой конфигурации.

В П1 реквизита автор не было. В П2 - есть, общий реквизит, в П2 положили общий реквизит на журнал. Объединили с П1. Теперь в П1 столбец Автор в журнале в конфигураторе есть ИлентификаторМетаданных "автор" ?), но в базе в нем лежит кривой ид ?

Что за упомянутый "идентификатор исходного объекта"???

ИдентификаторМетаданных - это имя реквизита в конфиге или id в пользовательском режиме? Идентификатор исходного объекта - это в конфигураторе или id в пользовательском режиме?
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 01 ноября 2025, 17:52
По идее трабла не должно быть если в обновляемой конфиге (НА которую накатываем) в базе нет документов. По мере создания документов в уже обновленной базе - все должно быть ок
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 01 ноября 2025, 22:40
8000 копий для анализа и уйма времени  - чтобы принести это бесполезное хрустальное знание :)  Спасибо за интерес, без дураков.

Смотри, дело вообще не в данных. Дело в том, что в результате обычного объединения получается битый мдшник.
Возьми свою лучшую конфу, просто чистый мдшник, и разложи в две папки.
1) В конфе 1 добавь константу и сохрани.
2) В конфе 2 добавь общий реквизит документа и выведи его в колонку в любом журнале.
3) Накати на конфу 1 мдшник от конфы 2 стандартным объединением и сохрани.
А теперь "Джентльмены, подходим ближе: вот он есть (в конфигураторе ты колонку в журнале видишь) , а вот его нет (в режиме "1С: Предприятия" ты колонку не видишь).

Вообще у фокуса есть продолжение: если теперь удалить константу, и попробовать объединять конфигурации, то 1С будет говорить, что "Конфигурации идентичны". При этом конфа 1 будет битая (колонка пользователям не видна), а конфа 2 нормальная (колонка пользователям видна).

PS ИдентификаторМетаданных - это внутренний id реквизита в конфигураторе.


Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 01 ноября 2025, 23:26
Цитата
PS ИдентификаторМетаданных - это внутренний id реквизита в конфигураторе.
Лучше так:
ИдентификаторМетаданных - это внутренний id объекта метаданных в конфигурации.
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 02 ноября 2025, 08:04

 ИдентификаторМетаданных не изменяется вслед за изменением Идентификатора исходного объекта (например, общего реквизита «Автор»), а остаётся как был в накатываемой конфигурации
.
Накатываемая конфигурация - п2.
Что такое Идентификатор исходного объекта? - это есть идентификатор метаданных общего реквизита "автор" в п2? В П2 все в порядке с мд, он небитый? "Идентификатормптаданных" - в твоем приложении - он где, в П1? Если он не меняется и остается как был в П2 - откуда в п1 битый мд?
Твое предложение для меня набор каких-то несвязных слов, который вообще не склеивается с описанием воспроизводства проблемы... Можешь это свое предложение перефразировать как-то по-другому, понятнее...?
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 02 ноября 2025, 11:02
Любой объект, который ты создаёшь в конфигурации получает внутренний id (идентификатор метаданных) - число от 1 и далее:
...
         1   Задача
       475   ОбщийРеквизитДокумента.Комментарий
     66404   ОбщийРеквизитДокумента.новый1
       476   ГрафаОтбора.Контрагент
       471   Нумератор.АктОС1
       472   Нумератор.ПриходныйОрдерМ4
     58672   Нумератор.СчетаФактуры
        12   Константа.ДатаРегистрации
        13   Константа.НазваниеОрганизации
...

Упрощенно:
Пусть у тебя в исходной конфигурации 1000 объектов.
Когда ты создал в П1 константу (пусть "ОГРН")она получила id = 1001.
Когда ты создал в П2 общий реквизит документа (пусть "Автор") он тоже получит id = 1001
Когда ты накатываешь на П1 объединением конфигурацию П2, то id добавляемого общего реквизита уже занят (он присвоен константе ОГРН) и общий реквизит "Автор" получает новый id = 1002.
И вот тут упущение - в колонке журнала ссылка не изменяется (а должна!) и остается - id 1001. Т.е в колонке журнала вместо Автора будет выводится Константа.ОГРН. Но в качестве заплатки 1С в таком случае просто не показывает эту колонку вообще.

Ну это же проще 1 раз увидеть, чем 7 раз услышать. Поэтому
Цитата
...возьми свою лучшую конфу, просто чистый мдшник, и разложи в две папки..

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

Название: Re: Обсуждение накопленного
Отправлено: Злоп от 02 ноября 2025, 12:26
Сразу бы так написать... ;-)
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 10 декабря 2025, 15:35
Цитата: amo|obs от 16 ноября 2025, 17:22Не добавляется в список значений значение неопределенного типа данных!
Действительно, ДобавитьЗначение и ВставитьЗначение ничего не делают с пустотой.
Но если очень хочется, то можно:
Список = СоздатьОбъект("СписокЗначений");
Список.ДобавитьЗначение("займём местчеко");
Список.УстановитьЗначение(Список.РазмерСписка,);
Сообщить(ЗначениеВСтрокуВнутр(Список));//список из одного пустого элемента

Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 10 декабря 2025, 15:41
Недокументированное поведение метода СписокЗначений::Установить(<Строка>, <Знач>)
Если опустить параметр <Знач>, то:
если в списке есть элемент с представлением <Строка>, то он будет удален из списка
если в списке нет элемента с представлением <Строка>, то будет добавлено пустое значение с представлением <Строка>.
Код для иллюстрации:
Список = СоздатьОбъект("СписокЗначений");
Список.Установить("Процент",100);
Сообщить(Список.РазмерСписка()); //1 элемент - значение с представлением "Процент" - добавлено
Список.Установить("Процент");
Сообщить(Список.РазмерСписка()); //0 - значение с представлением "Процент" было найдено и удалено
Список.Установить("Процент");
Сообщить(Список.РазмерСписка()); //1 - значение с представлением "Процент" не было найдено и поэтому добавлено
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 10 декабря 2025, 17:30
СЗ неисчерпаем. Как атом.
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 10 декабря 2025, 17:40
Цитата: Харлампий Дымба от 10 декабря 2025, 15:35Но если очень хочется, то можно:

Интересно, что даст ПустоеЗначение(Список)

;-)
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 10 декабря 2025, 17:40
Фичи с СЗ - перенес в Копилку
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 16 июня 2026, 23:30
Битый час пытался воткнуть, что сломалось в Отладчике - оказалось багофича 1с:
Отладчик не видит локальные переменные глобального модуля в глобальных процедурах и функциях, вызванных из других мест.
При попытке вычислить выражение даёт ошибку типа:
"ЛокальнаяПеременнаяГлобальногоМодуля = Ошибка в выражении!"
При этом всё нормально работает, переменная имеет значение. Но вот Отладчик её отказывается показывать.

Чтоб было понятнее - глобальный модуль такой:
Перем ЛокальнаяПеременнаяГлобальногоМодуля;
Процедура Проверка() Экспорт
    ЛокальнаяПеременнаяГлобальногоМодуля = 1;
КонецПроцедуры
ЛокальнаяПеременнаяГлобальногоМодуля = 0;

Вызов из обработки такой:
Процедура Сформировать()
    Проверка()
КонецПроцедуры

Похожая фишка, насколько помню, есть и объекта "Запрос", но вот на такой каприз Отладчика до сего дня не натыкался.


Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 12 октября 2026, 18:44
Ещё одна багофича 1С, связанная с функциями УчетПоКоличеству() и УчетПоВалютнойСумме() - флаги учета по "По количеству" и "По сумме" по указанному виду субконто:
КолУчетПоСубконто1...3 = СчетПоКоду("26").УчетПоКоличеству(1...3);// = 1, хотя количественного учета по аналитике сч.26 отродясь не было
ВалУчетПоСубконто1...3 = СчетПоКоду("26").УчетПоВалютнойСумме(1....3);//  = 1, хотя валютного учета по аналитике сч.26 отродясь не было
Это происходит потому, что 1Ска ленится скидывать неиспользуемые флаги при редактировании метаданных (такое много где встречается и приводит к разным багам). Типа если по счету в целом нет количественного учета, то неважно состояние флагов "Учет по количеству" для всех субконто этого счета, поэтому не будем с ними ничего делать и оставим их как были. Пользователю эти флаги видны как неустановленные и недоступны для редактирования, при этом на самом деле флаги установлены. Можно в любой типовой конфе с планом счетом убедиться, что по неколичественным счетам у субконто флаг снят (т.е. "НЕТ"), но при выводе "Описания структуры метаданных" для всех субконто счета значение реквизита "УчетПоКоличеству" будет равно "ЕСТЬ". С валютой аналогично.
Так что правильное использование этих функций - с использованием атрибутов счета "Количественный" и "Валютный":
КолУчетПоСубконто1...3 = ?(Счет.Количественный = 0, 0, Счет.УчетПоКоличеству(1...3));
ВалУчетПоСубконто1....3 = ?(Счет.Валютный = 0, 0, Счет.УчетПоВалютнойСумме(1...3));

Можно было бы назвать это не багом, а особенностью - так как в описании функции именно такое поведение функций и задекларировано: "Функция возвращает значение флага ...".
Но во-первых даже в вылизанной за десятилетия ОСВ по счету в типовой бухии есть именно эта ошибка - использование функции "УчетПоКоличеству" без оглядки на сам счёт. Ошибка незначительная по последствимя - из-за неё выводятся лишние пустые секции в печатной форме, но всё же.
А во-вторых возможно, что и в других местах 1С будет смотреть на флаг по субконто, игнорируя флаг по счету.
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 01 ноября 2026, 02:07
Не знаю как лучше классифицировать этот баг 1С, долго ловил и, думаю, поймал.
При некоторых условиях использование "Окна-Закрыть все окна" приводило к появлению окошка "Ошибка при выполнении модуля! Закрыть?" и последующему падению 1С независимо от ответа пользователя.

Проблема возникает, если выполняются следующие условия:
1. Открыта форма подбора;
2. В форме подбора установлен флаг множественного выбора;
3. В форме подбора установлен флаг выбора групп и справочник многоуровневый;
4. Форма подбора находится на заднем плане относительно вызвавшой формы;
5. Пользователь выбирает пункт меню "Окна - Закрыть все  окна".
Если любой из этих пунктов убрать - всё гладко.

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

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

Название: Re: Обсуждение накопленного
Отправлено: Злоп от 01 ноября 2026, 23:04
Это не баг, а извращение ;-)
Держать форму подбора, да еще на заднем плане и при этом закрыть все окна - мусье знает толк... ;-)
Однако сколько времени потратилось чтобы воспроизвести...
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 02 ноября 2026, 02:18
Цитата: Злоп от 01 ноября 2026, 23:04мусье знает толк
Воу-воу, стопэ! :)
Абсолютно типовой сценарий обычной быстрой работы:
Открыл любой отчет, подобрал несколько групп товаров или контрагентов, сразу ткнул "Сформировать" (незакрытая форма подбора отъехала на задний план), при последующей работе понаоткрывал ещё кучу других форм - отчеты, документы и т.д. и закрыл все окна одной командой - 1С упала.

Нет, я верю, что:
1. большинство пользователей будут добавлять элементы через форму одиночного подбора - именно она откроется если ткнуть в название отбора ("По номенклатуре", например)
и
2. большинство пользователей обязательно закроют крестиком форму множественного подбора после последнего выбора
и
3. большинство пользователей будут крестиками закрывать все открытые окна, вместо того чтобы чохом закрыть.
и
именно поэтому большинство пользователей с этой ошибкой никогда не встретятся.

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

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


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

Здесь при переносе надо видимо сделать просто проверку существования родительского контекста...
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 03 ноября 2026, 03:46
Цитата: Злоп от 02 ноября 2026, 06:45Еще если помните - почему UCHOICE падал с закрытием 1С при задании даты в условие отбора?

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

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

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

на ней и валится. Пустая она или там есть код не важно - валится от её наличия. Если этой процедуры нет, то падения не происходит. Всё чудесатее и чудесатее.
Название: Re: Обсуждение накопленного
Отправлено: cr от 03 ноября 2026, 19:49
Чё как дети?
Есть 2 способа организации подбора. Обычный и специальный.
Можно просто ОткрытьПодбор() и здесь же (в "родительской" форме) в предопределенной процедуре ОбработкаПодбора() задать действия с выбранной строкой из списка подбора. Так чаще всего и делается, при этом если режим НЕполноэкранный и сделать видимыми в окне обе формы (и "родительскую" и форму списка), видно как при выборе строки в форме подбора, она сразу "попадает" в "родительскую" форму. В каком порядке эти формы будут закрываться - по барабану.
А можно иначе. Если в форме подбора в ПриОткрытии() установить ОбработкаВыбораСтроки() в 1, ОбработкаПодбора() в "родительской" форме срабатывать не будет, зато в форме подбора начнет срабатывать предопределенная процедура ПриВыбореСтроки(), в которой и задаются действия с выбранной строкой. В этом варианте подобранные значения из формы подбора автоматически "отправляются" в "родительскую" форму из ПриЗакрытии() (- а как еще-то?). 1С валится из ПриЗакрытии() формы подбора, когда совершает там недопустимую операцию с закрытой "родительской" формой.
Название: Re: Обсуждение накопленного
Отправлено: Злоп от 03 ноября 2026, 21:57
для начала надо выяснить валится на ПриЗакрытии() - на каком этапе? вход в процедуру успешен, валится на завершении? или как? если выяснится что вход в ПриЗакрытии успешен - то дальше можно пытаться играться с контекстом родительской формы, которую передавать через параметры при вызове подбора
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 03 ноября 2026, 23:40
Цитата: cr от 03 ноября 2026, 19:49Чё как дети?
Не, ОбработкаВыбораСтроки() тут тоже не причём.
Но и у меня чё-то поплыли все рассуждения тоже. Многоуровневость оказывается не обязательна, проблема возникает если форму подбора дернуть из родительской формы после ОткрытьПодбор() по любому поводу, а в форме подбора (обычная форма списка справочника) есть процедура ПриЗакрытии.

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

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

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

Название: Re: Обсуждение накопленного
Отправлено: cr от 04 ноября 2026, 00:20
Если в форме подбора есть ПриЗакрытии(), то после захода в неё, курсор вернется обратно в "родительскую" форму (скорее всего, на строку "родительской" формы следующую после ОткрытьПодбор(), но может, еще куда-то, ПриПовторномОткрытии(), например), а если "родительской" формы уже нет, курсору некуда вернуться и он роняет 1С.
Отладчик в руки и вперед ...
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 04 ноября 2026, 22:14
Цитата: cr от Вчера в 00:20Отладчик в руки и вперед
Сообщением выше - тестовый стенд. Там ровно 8 строчек на 2 модуля, из них только две строчки выполняют инструкцию. В какую строку нужно поставить точку останова и какой параметр отследить? Да и как это поможет?

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

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


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

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

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

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

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

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

Чтобы при первой попытке Окна - закрыть все , форма подбора закрылась, а "родительская" форма осталась открытой. И ничего не упадет. Со второй попытки Окна - закрыть все, "родительская форма тоже закроется без падения.
Все пункты с условиями - в топку! Они не при делах. Все формексы, попытки-исключения и недокументированные возможности - туда же, куда и условия.
Название: Re: Обсуждение накопленного
Отправлено: Харлампий Дымба от 05 ноября 2026, 01:30
Цитата: cr от Сегодня в 00:02смотришь куда она (когда не падает) пойдет после ПриЗакрытия()
НИКУДА. Зачем 3 раза отправлять меня в Отладчик, если можно убедиться, что там нечего ловить?

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

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

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