Свершилось!
Данный материал посвящен всем, кто достаточно много времени проводит в работе с системой, и нацелен на максимально быструю и удобную работу с продуктом.
В данном материале речь пойдет о значениях в полях типа Справочник. Точнее, об удобном выборе значений в этих полях. Не секрет, что в процессе работы с системой часто бывает так, что Вам приходится выбирать в поле, например, Ответственный, часто повторяющиеся значения. Таких часто выбираемых значений обычно несколько, но каждый раз нажимать на значок лупы и выбирать нужное в окне выбора, наверное, не совсем оптимально. Особенно, если учесть, что выбирать приходится из большого списка, с использованием поиска и фильтров. Особенно часто это встречается при работе с Задачами и Запросами на изменение (но в общем случае это зависит от специфики работы предприятия).
Предлагаемая функциональность позволяет реализовать следующее: практически в любом LookupDataControl'е любой карточки редактирования системы рядом со значком лупы появится новая кнопка, по нажатию на которую (первый клик мышью) всплывает меню со списком недавно введенных значений в поле:
Выбрав мышью нужный пункт (второй клик) пользователь может осуществить ввод указанного значения в поле.
В итоге пользователь экономит как минимум 1 клик мышью, а также существенно ускоряется процесс заполнения поля и производительность системы - нет дополнительных запросов, порожденных окном выбора, нет самих окон выбора. В итоге получаем значительно более удобную работу с карточкой и экономию времени на рутинных, часто повторяющихся операциях (заполнение расписания, работа с запросами на изменение и т.д.).
Удобство от использования данной возможности уже оценили пользователи внутренней рабочей версии компании Террасофт.
Как же это работает и что нужно сделать, чтобы включить в своем проекте данную функцию? Обо всем по порядку.
Начнем с подходящей версии приложения. Данный механизм будет работать на версиях начиная с 3.2.0.х. Это связано с появившейся в 3.2.0 возможностью отображения рядом с большинством DataControl'ов набора кнопок с меню. Итак, по шагам.
1. Берем файл scr_SmartLookupUtilsForX25.rar, распаковываем, загружаем в TSAdmin файл scr_SmartLookupUtils.xml. Это основной скрипт с функциями Smart Lookup Feature.
2. В скрипте scr_BaseDBEditUtils добавляем скрипт scr_SmartLookupUtils в список Use Scripts.
3. В скрипт scr_BaseDBEdit добавляем следующие строки:
function SmartLookupOnDataChange(DataField) {
ProcessSmartLookupOnDataChange(DataField, Self);
}
function SmartLookupSetValueOnExecute(ActionMenuItem) {
SetSmartLookupValue(ActionMenuItem);
}
function wnd_BaseDBEditOnProfileDeserialize(Window, Node) {
ReadSmartLookupDataFromProfile(Window, Node);
}
function wnd_BaseDBEditOnProfileSerialize(Window, Node) {
ProcessSaveSmartLookupValuesToProfile(Window, Node);
}
function wnd_BaseDBEditOnShow(Window) {
LoadSmartLookupValues(Window);
}
Это обработчики событий, используемых для работы функций.
4. В окне wnd_BaseDBEdit переключаемся на вкладку События и для событий OnProfileDeserialize, OnProfileSerialize, OnShow двойными щелчками добавляем обработчики событий (сам код обработчиков мы уже добавили в п.3). Сохраняем окно, открываем заново и убеждаемся, что все указанные обработчики успешно сохранены (это важно, и шансы здесь ошибиться есть).
5. Вносим изменения в скрипт scr_Utils. Добавляем новую функцию:
function GetIndexOfItemInArray(SearchValue, SearchArray) {
for (var i = 0; i < SearchArray.length; i++) {
if (SearchValue == SearchArray[i]) {
return i;
}
}
return -1;
}
Можно было бы предложить полностью скрипт scr_Utils, но есть большой риск, что в Ваших проектах в этом скрипте есть нужные Вам функции, и проще просто добавить в него новую, чем заниматься слиянием текста двух скриптов и поиском измененных и добавленных участков кода. Это особенно актуально, если Вы захотите добавить Smart Lookup Feature в проект версии ниже 3.3.0 (разработка велась именно на этой версии). По этой же причине пункты 2, 3, 4, 6 и 7 выглядят именно таким образом, а не предлагаются в виде готовых сервисов.
6. Теперь включаем данную функцию, например, в окне Задач. Для этого открываем окно wnd_TaskEdit, устанавливаем UseProfile = True, сохраняем окно.
7. Если бы в окне (в нашем случае wnd_TaskEdit) не было обработчика события OnDatasetDataChange для компонента dlData, на этом изменения и закончились бы (функции в состоянии подписаться на необходимые события самостоятельно, без участия разработчика). Однако, если данное событие обрабатывается (в нашем случае в скрипте scr_TaskEdit), придется внести небольшие коррективы в обработчик:
Последней строчкой в функции dlDataOnDatasetDataChange(DataField) скрипта scr_TaskEdit необходимо вставить строку:
...
SmartLookupOnDataChange(DataField);
}
8. Запускаем приложение. Открываем карточку задачи. Изменяем значение в поле, например, Ответственный. Закрываем карточку задачи. Закрываем приложение. Все это, видимо, нужно для корректной инициализации профиля карточки редактирования. Необходимость этого шага выявлена в ходе испытаний, но все еще под сомнением.
9. Запускаем приложение. Открываем карточку задачи. Изменяем значение в поле, например, Ответственный. Наблюдаем следующую картину (sorry за англоязычный скриншот, экспериментировал с применением функции на версиях, которые были под рукой):
На данный момент скрипты реализованы таким образом, что позволяют включить данную возможность в указанном списке окон редактирования для указанного списка элементов управления типа LookupDataControl. При желании пункты 6-9 можно проделать с другими окнами редактирования. В скрипте scr_SmartLookupUtils в массивах SmartLookupEnabledWindowsArray и SmartLookupEnabledControlNamesArray можно настроить перечень кодов доступных окон и имен компонентов в этих окнах соответственно. Либо поступить более рискованно и радикально, и переписать функции ReadSmartLookupDataFromProfile и ProcessSaveSmartLookupValuesToProfile таким образом, чтобы они работали с любым окном и любым LookupDataControl'ом. В первых альфа-версиях скрипта так и было, но решили все-таки ограничиться фиксированным списком окон и элементов управления.
Пару слов о том, как это работает. Необходимые списки значений сохраняются в профиле окна. Построение списков происходит при показе окна. При необходимости чтение из профиля выполняется принудительно (это актуально для окон, поднятых из программного кэша). Подписка на событие OnDatasetDataChange датасетлинка окна редактирования (или ручной вызов обработчика, как в примере с Задачами) нужна для анализа изменений значения в поле и пополнения списка. Список пополняется сверху вниз (свежие значения вверху, чтобы пользователю было ближе к ним мышь двигать). Первые разы, пока список не заполнен, все-таки придется использовать лупу для выбора значений, затем эти значения будут доступны в списке Smart Lookup. Сохранение списков производится в момент закрытия окна. Все необходимые компоненты (ActionMenu, ActionMenuItem) создаются динамически в режиме выполнения. Максимальное количество элементов в списке равно 7.
Надеюсь, вы найдете Smart Lookup Feature удобным и полезным механизмом.
Также надеюсь, что этот механизм будет включен в базовую версию продукта версии 3.3.1, по крайней мере все для этого готово.
Повторюсь, список поддерживаемых окон и компонентов можно очень легко расширить. Код специально написан универсальным образом, чтобы не зависеть от специфики конкретного окна редактирования.
Отзывы и комментарии приветствуются.