При переходе с платформы 1С 7.7 на 1С 8.3 (особенно при работе с конфигурациями на обычных формах, такими как УТП 1.2 или УПП 1.3) программисты часто сталкиваются с тем, что привычные механизмы работы интерфейса ведут себя иначе. Одной из типовых задач является создание поля ввода для быстрого поиска и открытия документа по его номеру прямо из формы списка, а также программное управление порядком отображения документов.
В этой статье мы подробно разберем, почему стандартные события поля ввода могут «игнорировать» повторное нажатие клавиши Enter, и как правильно настроить программную сортировку и фильтрацию в динамических списках документов.
Рассмотрим ситуацию: на форме списка заказов создано поле ввода. Оператор вводит номер заказа, нажимает Enter, и система открывает нужный документ. Однако при попытке повторно нажать Enter в том же поле (например, если документ был случайно закрыт), ничего не происходит. Это связано с тем, что основное событие ПриИзменении срабатывает только в том случае, если значение в поле ввода действительно изменилось по сравнению с предыдущим. Если номер остался прежним, платформа не считает это изменением и не запускает процедуру.
Проанализируем исходный код, который часто используют новички:
Процедура ПолеВвода1ПриИзменении(Элемент)
// Поиск по номеру заказа
Если Элемент.Значение > 0 Тогда
ДокТек = Документы.ЗаказПокупателя;
НайдДок = ДокТек.НайтиПоНомеру(Элемент.Значение);
Если НайдДок = ДокТек.ПустаяСсылка() Тогда
Сообщить("Заказа с таким номером не существует.");
Иначе
// Получение объекта и открытие формы
Док = НайдДок.ПолучитьОбъект();
Форма = Док.ПолучитьФорму("ФормаДокумента");
Форма.Открыть();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Чтобы заставить поиск работать при каждом нажатии Enter, даже если номер не менялся, мы можем применить несколько подходов.
Событие ОкончаниеВводаТекста генерируется платформой каждый раз, когда пользователь завершает редактирование (нажимает Enter или переводит фокус), независимо от того, изменился текст или нет. В этом событии мы можем анализировать параметр Текст.
Разберем реализацию этого метода:
ОкончаниеВводаТекста и создайте обработчик.Текст для поиска ссылки на документ.Важный нюанс: при использовании этого метода следует устанавливать СтандартнаяОбработка = Ложь, чтобы система не пыталась выполнить стандартные действия по окончании ввода.
Самый простой способ «обмануть» событие ПриИзменении — очищать поле ввода сразу после успешного (или неуспешного) поиска. Тогда при следующем вводе значение всегда будет считаться измененным.
Для этого достаточно в конце процедуры добавить строку:
Элемент.Значение = "";
Или установить свойство поля ввода "Очищать при завершении редактирования" в значение Истина в конфигураторе.
Если требования интерфейса позволяют, лучше всего разместить рядом с полем ввода кнопку (например, с иконкой лупы). Если установить у этой кнопки свойство КнопкаПоУмолчанию в значение Истина, то любое нажатие Enter на форме (когда фокус в поле ввода) будет приводить к нажатию этой кнопки и выполнению кода поиска.
Вторая проблема, с которой сталкиваются разработчики — игнорирование программной сортировки. Вы можете написать ДокументСписок.Порядок.Установить("НужныйРеквизит"), но список все равно будет упорядочен по дате. Выясним причины этого поведения.
В динамических списках (объект ДокументСписок) сортировка работает корректно только при соблюдении условий:
ДатаСП), должен иметь свойство "Индексировать" в метаданных документа. Без индекса СУБД не сможет эффективно упорядочить данные, и платформа откатится к стандартной сортировке по дате.ПриОткрытии.Часто задача "сортировки" на самом деле является задачей ограничения видимости данных. Если вам нужно показать документы за конкретный период по специфическому реквизиту даты (например, дате оплаты), эффективнее использовать механизмы Отбор.
Проанализируем пример кода, который позволяет установить интервал дат для произвольного реквизита при открытии формы:
Процедура ПриОткрытии()
// Разрешаем доступность настройки отбора для нужного реквизита
ЭлементыФормы.Список.НастройкаОтбора.ДатаОплаты.Доступность = Истина;
// Определяем границы периода (например, текущий месяц)
НачалоПериода = НачалоМесяца(ТекущаяДата());
КонецПериода = КонецМесяца(ТекущаяДата());
// Работаем с коллекцией отбора списка
ЭлементОтбора = ДокументСписок.Отбор.ДатаОплаты;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы;
ЭлементОтбора.ЗначениеС = НачалоПериода;
ЭлементОтбора.ЗначениеПо = КонецПериода;
КонецПроцедуры
Этот метод гарантирует, что в списке останутся только нужные документы, что значительно упрощает работу оператора и снижает нагрузку на базу данных.
В коде из первого сообщения используется метод НайдДок.ПолучитьОбъект(). Проанализируем ситуацию: получение объекта — это тяжелая операция, которая считывает все данные документа из базы в память сервера, а затем передает их на клиент. Если ваша цель — просто открыть форму для просмотра или редактирования, лучше передавать ссылку напрямую.
Рекомендуемый способ открытия формы в 1С 8:
ПараметрыФормы = Новый Структура("Ключ", НайдДок);
ОткрытьФорму("Документ.ЗаказПокупателя.Форма.ФормаДокумента", ПараметрыФормы);
Этот подход (использование параметра Ключ) является более современным и производительным, так как платформа сама оптимизирует процесс открытия формы по ссылке, не создавая лишних транзакционных нагрузок, которые возникают при явном вызове ПолучитьОбъект().
Подводя итог, можно сказать: чтобы интерфейс в 1С 8.3 был удобным для пользователей, привыкших к 7.7, необходимо комбинировать использование событий (таких как ОкончаниеВводаТекста) с правильной настройкой метаданных (индексирование) и программным управлением коллекциями Отбор и Порядок.