Парочка интересных багов.

Баги, обнаруженные на платформе 8.3 после перехода с 8.2.

Добрый день, друзья!

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

Пояснения: переход осуществлялся с версии платформы 8.2.19.130 на 8.3.13.1690. И конфигурация написана на обычных формах (на самом деле там всё смешано, но большая часть на обычных), то есть все случаи будут затрагивать работу в обычном приложении. Ладно, поехали.

Случай 1.

Предисловие.

Мы все хорошо знаем, что при автоподборе текста стандартный алгоритм такой: ищутся первые 50 записей, найденных по реквизитам, указанным в параметре "Ввод по строке" объекта вот здесь:

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

Теперь посмотрим, как происходит автоподбор текста на разных платформах:

 — 8.2. Всё как обычно.

  — 8.3. После автоподбора курсор переносится в конец подобранной строки.

Для тех, кто смотрит в монитор или пишет быстрее того момента, когда срабатывает обработчик, это, может быть, и не проблема. У остальных же это вызвало, мягко говоря, недовольство. Что поделать, придется переписывать стандартную обработку…

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

Процедура ПолеВвода1АвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ТекстЗапросаПоле = "";
ТекстЗапросаУсловие = "";
КоличествоПолейВводаПоСтроке = Метаданные.Справочники.НомераГТД.ВводПоСтроке.Количество();
Для ТекСтрока = 1 По КоличествоПолейВводаПоСтроке Цикл

ПолеВводПоСтроке = Метаданные.Справочники.НомераГТД.ВводПоСтроке.Получить(ТекСтрока - 1);

ТекстЗапросаПоле = ТекстЗапросаПоле + "
|  КОГДА НомераГТД." + ПолеВводПоСтроке.Имя + " ПОДОБНО &Текст
|   ТОГДА НомераГТД." + ПолеВводПоСтроке.Имя;

ТекстЗапросаУсловие = ?(ТекСтрока = 1, "(", "") + ТекстЗапросаУсловие + "
| НомераГТД." + ПолеВводПоСтроке.Имя + " ПОДОБНО &Текст" + ?(ТекСтрока = КоличествоПолейВводаПоСтроке, ")", Символы.ПС + "ИЛИ ");

КонецЦикла;


Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Текст", Текст + "%");
Запрос.Текст =
"ВЫБРАТЬ
| ВЫБОР"
+ ТекстЗапросаПоле + "
| КОНЕЦ КАК ТекстАвтоПодбора,
| НомераГТД.Представление,
| НомераГТД.Ссылка
|ИЗ
| Справочник.НомераГТД КАК НомераГТД
|ГДЕ " + ТекстЗапросаУсловие;
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
КоличествоЗаписей = Выборка.Количество();
Если Выборка.Количество() = 1 Тогда
Выборка.Следующий();
ТекстАвтоПодбора = Выборка.ТекстАвтоПодбора;
ИначеЕсли Выборка.Количество() <= 50 Тогда
СписокВыбора = Новый СписокЗначений;
Пока Выборка.Следующий() Цикл
СписокВыбора.Добавить(Выборка.Ссылка,
?(Выборка.ТекстАвтоПодбора = Выборка.Представление, СокрЛП(Выборка.ТекстАвтоПодбора), СокрЛП(Выборка.ТекстАвтоПодбора) + " (" + СокрЛП(Выборка.Представление) + ")"));
КонецЦикла;
ВыбранноеЗначение = ВыбратьИзСписка(СписокВыбора, Элемент);
Если ВыбранноеЗначение <> Неопределено Тогда
Элемент.Значение = ВыбранноеЗначение.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры

Можно было бы не париться и просто обратиться с поиском по коду. С другой стороны, мы хотим повторить полный функционал платформы и нам нельзя игнорировать настройки, указанные в метаданных. После формирования запроса проверяем количество записей результата: если запись одна, то просто приравниваем результат к параметру ТекстАвтоПодбора. Интересно, что, если вручную установить этот параметр, то баг пропадет. Если записей не больше пятидесяти, то формируем список значений и формируем выбор из списка. Для оптимизации запроса можно, конечно, вписать "ВЫБРАТЬ ПЕРВЫЕ 51", но я подумал, что это может выжечь кому-нибудь глаза, поэтому не стал:)

Вроде готово, смотрим результат:

 — когда найденная запись только одна;

  — когда записей несколько;

Также, когда записей несколько, но они найдены не по полю основного представления, то представление элемента нужно также внести в скобки в списке выбора. Для теста специально добавил в поля ввода ещё один реквизит. Процесс добавления:

 -внес в индекс

  — добавил в поля ввода по строке.

Результат автоподбора текста:

Вот так в итоге получилось.

 

Случай 2.

Предисловие.

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

Итак, вот какой жук нашелся. Для наглядности создам обработку с двумя строчками кода при изменении поля ввода: первая строчка очищает значение элемента, вторая устанавливает свойство ТекущийЭлемент = Элемент. Смотрим:

 — 8.2 всё ок;

 — 8.3 вторая строчка кода не срабатывает…

Окей. Конечно, от этого никто не помрёт, но эмоций, поверьте, много, особенно у тех, кто пользуется сканером штрих-кода… Как это исправить? Что только ни пытался сделать. Пробовал в конце обработчика ставить строчку Элемент.ВыделенныйТекст = " ". В каком-то смысле это помогло, однако, в поле ввода красовался пробел, что совсем нам не нужно.

Нашелся выход из данной ситуации не сказать, что прямо идеальный, но другого выхода не нашлось. С выходом платформы 8.3 на форме появился новый обработчик ОбновлениеОтображения. Хотя в методичке по этому обработчику говорится, что так делать нельзя из-за возможности падения производительности системы, как я уже говорил, другого выхода не нашлось. Итак, пишу листинг:

Перем ЭтоИзменениеНужногоПоля;

Процедура ПолеВводаПостояннымКурсоромПриИзменении(Элемент)
Элемент.Значение = "";
КонецПроцедуры

Процедура ОбновлениеОтображения()
Если ЭтоИзменениеНужногоПоля Тогда
ТекущийЭлемент = ЭлементыФормы.ПолеВводаПостояннымКурсором;
КонецЕсли;
КонецПроцедуры

Процедура ПолеВводаПостояннымКурсоромОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
Если ЗначениеЗаполнено(Элемент.Значение) Тогда
ЭтоИзменениеНужногоПоля = Истина;
КонецЕсли;
КонецПроцедуры

ЭтоИзменениеНужногоПоля = Ложь;

Итак, создаю глобальную переменную формы ЭтоИзменениеНужногоПоля. Она нужна для того, чтобы возврат в нужный элемент формы происходил только после нужного мне события. При окончании ввода текста в нужном поле ввода при заполненном значении устанавливаю значение моей переменной в Истина. После всех обработчиков срабатывает обработчик ОбновлениеОтображения. Там я проверяю, что, если изменено нужное поле, то ставлю ТекущийЭлемент в нужный элемент формы. Вуаля. Результат:

 — норм.

Вроде бы косяки и мелкие, но пришлось достаточно попотеть, чтобы их устранить. После всего я подумал, что на 8.3 лучше работать на управляемых формах… Может, я здесь, конечно, и не прав. В любом случае хочу сказать, что в таких ситуациях, когда перестают работать привычные для тебя методы работы и приходится в быстром порядке придумывать новые, получаешь наибольший опыт. Такой выход из зоны комфорта помогает взглянуть на привычные вещи с другой стороны и ещё это весело. Но это не точно:)

22 Comments

  1. YanTsys

    С багом из статьи пока не встречался, но зато очень мешает когда при копировании в строку поиска текста например из Excel кроме искомого текста в конце строки подставляется еще и знак переноса строки ¶ и 1с в итоге ничего не находит пока его не удалишь…

    Reply ↓
  2. Senator_I

    Зачем старую перепиленную базу на 8.3 переводить?

    Reply ↓
  3. YannikAlx

    (3) А чтоб повеселиться? Скучно ведь, когда все нормально работает….

    Reply ↓
  4. fromlion

    (3) как вариант чтоб избежать зоопарка платформ, т.к. может стоять параллельно БП и ЗУП которые просят новую платформу.

    Reply ↓
  5. Senator_I

    (5) да, вполне вероятно, когда есть базы, требующие платформы 8.3

    Reply ↓
  6. RomanCrow13

    (3)

    1) Внедрение БСП,

    2) JSON

    3) SSL

    4) Все базы на одной платформе

    5) Подсветка кода наконец!

    Reply ↓
  7. Senator_I

    (7) а, ну это аргумент конечно. Чтобы построить новое надо сломать старое.

    Reply ↓
  8. Dream_kz

    (1)

    Использовать обычные формы на 8.3 в 2019

    Деловые линии на обычных формах, и ч0?

    Reply ↓
  9. VmvLer

    (9) я не помню не знаю никаких деловых линий и прочего некрофильского 1С-софта и ч0?

    Reply ↓
  10. RocKeR_13
    чтобы сработал обработчик ПриИзменении приходится после сканирования вставлять символ переноса каретки, после это поле очищается и курсор переносится туда же

    У вас сканер не прописан в подключаемом оборудовании что ли? И в целом непонятен пример: зачем очищать поле после сканирования?

    Reply ↓
  11. bulpi

    Замечание:

    Вместо ОбновлениеОтображения() в типовых используют однократный запуск обработчика ожидания с таймаутом 0.1 сек

    Reply ↓
  12. genayo

    (12) Зачем так делают в типовых?

    Reply ↓
  13. genayo

    А так да, не буду, пожалуй, на 8.2 с 8.3 специализированную конфу переводить…

    Reply ↓
  14. RomanCrow13

    (11)

    В УТ 10.2 нет библиотеки подключаемого оборудования.

    Я сделал очистку для наглядности, срабатывает ли команда ТекущийЭлемент = Элемент. А в целом, в поле ввода юзер вбивает штрих-код, при изменении происходит обработка данных в соответствии с введённым штрих-кодом. После обработки поле ввода должно очищаться и текущим элементом должен снова стать элемент ввода кода, чтобы снова вбивать новые штрих-коды.

    Reply ↓
  15. stepan_s

    (1) 🙂 я тут на днях в розничном магазине АРМ 1С77 встретил…. Согласно Вашей логике, они должны были давно в розницу на 8.3 убежать… Только зачем?

    А вот перейти на 8.3 с обычными формами не претит, т.к.вендор сказал что наследуется и все хорошо…..

    Reply ↓
  16. user710334_koshil.v

    Спасибо! Один в один ситуация описанная в п. 2. Только это не баг 8.2 — 8.3. У меня это проявилось при переходе с 8.3.10 на 8.3.13.1690. Есть две самописки одна на обычных, одна полностью на УФ. Теперь именно из за неизвестных багов на ОФ я боюсь обновлять платформу на 14-15.

    Reply ↓
  17. bulpi

    (13)

    Чтобы перевести курсор на нужное поле (например)

    Reply ↓
  18. hasp_x

    (16) тоже 77 еще используем

    Reply ↓
  19. SlavaKron

    (5) Для этого есть режим совместимости.

    Reply ↓
  20. fromlion

    (20) Для чего есть режим совместимости?

    Reply ↓
  21. SlavaKron

    (21)

    чтоб избежать зоопарка платформ, т.к. может стоять параллельно БП и ЗУП которые просят новую платформу
    Reply ↓
  22. fromlion

    (22)видимо я потерял мысль, т.к. я отвечал своим 5 постом на вопрос 3 поста.

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *