Свершилось!
Данный материал посвящен всем, кто достаточно много времени проводит в работе с системой, и нацелен на максимально быструю и удобную работу с продуктом.
В данном материале речь пойдет о значениях в полях типа Справочник. Точнее, об удобном выборе значений в этих полях. Не секрет, что в процессе работы с системой часто бывает так, что Вам приходится выбирать в поле, например, Ответственный, часто повторяющиеся значения. Таких часто выбираемых значений обычно несколько, но каждый раз нажимать на значок лупы и выбирать нужное в окне выбора, наверное, не совсем оптимально. Особенно, если учесть, что выбирать приходится из большого списка, с использованием поиска и фильтров. Особенно часто это встречается при работе с Задачами и Запросами на изменение (но в общем случае это зависит от специфики работы предприятия).
Предлагаемая функциональность позволяет реализовать следующее: практически в любом 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, по крайней мере все для этого готово.
Повторюсь, список поддерживаемых окон и компонентов можно очень легко расширить. Код специально написан универсальным образом, чтобы не зависеть от специфики конкретного окна редактирования.
Отзывы и комментарии приветствуются.

Нравится

Поделиться

21 комментарий

Дима, спасибо за отличную функциональность.

Спасибо!

--
Cogito, ergo sum

Просто и со вкусом, спасибо!
Только насчет 3.3.1, может этот функционал лучше в ядре реализовать. А в LookupDataControl и LookupControl добавить признаки вроде UseSmartLookup и SmartLookupCount.

"Underscore a.k.a. _" написал:Только насчет 3.3.1, может этот функционал лучше в ядре реализовать.

Не стоит этого делать. Создание функциональности в конфигурации добавляет гибкости решению.
Дима, удобная штука! Спасибо!

А в ядре, я так понимаю, скорости :) Ну, нет так нет.

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

Дима, в целом, БОМБА!

"Underscore a.k.a. _" написал:Только насчет 3.3.1, может этот функционал лучше в ядре реализовать. А в LookupDataControl и LookupControl добавить признаки вроде UseSmartLookup и SmartLookupCount.

Может лучше SaveLookupHistory и LookupHistoryCount?

Ну названия я особо не выдумывал :) Второй вариант мне нравится, а вот в первом слово Save не смотрится. Он же не только Save но и Load потом :) Лучше Store.

Дмитрий, просьба прокомментировать дополнительно, в каких ситуациях может при внесении новой записи в список подставляется вместо нужного DisplayValue значение по-умолчанию:

   var DisplayValue = DataField.DisplayValue;
   if (DisplayValue == '') {
	var Dataset = LookupDataControl.DatasetLink.Dataset;
	// If it is DataChange during setting default       
        //values, then DisplayValues are empty
	// so we need to show something like default caption
	if (!Dataset.IsGettingDisplayValuesEnabled)	{
  	   DisplayValue = SmartLookupDefaultDisplayValue;
	}
   }

При заполнении поля "Инцидент" в задаче у менеджеров часто попадают в список именно "<Значение по умолчанию>", но происходит это далеко не всегда.
Комментарий есть ("If it is DataChange during setting default values, then DisplayValues are empty...") но хотелось бы лучше понять какие действия на практике приводят к смене атрибута IsGettingDisplayValuesEnabled для датасета

Добрый день, Александр!
Спасибо за Ваше замечание.
Базовая логика работы с карточкой такова, что перед установкой ряда значений по умолчанию у датасета выполняется метод DisableGettingDisplayValues(). Это нужно для того, чтобы быстрее выполнить присвоения в поля типа Справочник (устанавливаются только ID), а затем методом EnableGettingDisplayValues() выполнить чтение всех отображаемых значений в этих полях. Это чтение выполняется ядром, причем одним запросом. Разработчики продукта справедливо посчитали, что такой способ ускорит установку значений по умолчанию.
При использовании SmartLookup в этом случае отображаемого значения у DataField'а просто нет, и поэтому приходится выводить некоторый стандартный заголовок "Значение по умолчанию".

В итоге решили отказаться от использования SLF при установке значений по умолчанию вообще:

	var DisplayValue = DataField.DisplayValue;
	if (DisplayValue == '') {
		return;
		/* It is decided to turn off storing of SmartLookupValues during setting of default values
		var Dataset = LookupDataControl.DatasetLink.Dataset;
		// If it is DataChange during setting default values, then DisplayValues are empty
		// so we need to show something like default caption
		if (!Dataset.IsGettingDisplayValuesEnabled)	{
			DisplayValue = SmartLookupDefaultDisplayValue;
		}
		*/
	}

Дмитрий, спасибо за ответ!
Попробуем поступить аналогично))
Либо, я как понимаю, можно просто другим способом вытаскивать необходимое значение, ведь ID выбранной записи есть в любом случае (если не пустое, конечно), но это скажется на быстродействии.

Добрый день, товарищи.
Была сделана доработка (с согласия уважаемого автора) SmartLookup, сутью которой является поддержка данного механизма не только для LookupDataControl, но и для обычных LookupControl. Принцип работы механизма остался тот же. Инструкция по установке изменилась:

1. Берем файл scr_SmartLookupUtils.rar, распаковываем, загружаем в TSAdmin файл scr_SmartLookupUtils.xml. Это основной скрипт с функциями Smart Lookup Feature.

2. Если LookupControl или LookupDataControl находится в обычной карточке редактирования (основанной, на шаблоне wnd_BaseDBEdit):
2.1. В скрипте scr_BaseDBEditUtils добавляем скрипт scr_SmartLookupUtils в список Use Scripts.
2.2. В скрипт scr_BaseDBEdit добавляем следующие строки:

function SmartLookupOnDataChange(DataField) {
    ProcessSmartLookupOnDataChange(DataField, Self);
}
 
function SmartLookupDataSetValueOnExecute(ActionMenuItem) {
    SetSmartLookupDataValue(ActionMenuItem);
}
 
function SmartLookupOnChange(LookupControl) {
    ProcessSmartLookupOnChange(LookupControl);
}
 
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);
}

Это обработчики событий, используемых для работы функций.
2.3. В окне wnd_BaseDBEdit переключаемся на вкладку События и для событий OnProfileDeserialize, OnProfileSerialize, OnShow двойными щелчками добавляем обработчики событий (сам код обработчиков мы уже добавили в п.2.2). Сохраняем окно, открываем заново и убеждаемся, что все указанные обработчики успешно сохранены (это важно, и шансы здесь ошибиться есть).

3. Если LookupControl или LookupDataControl находится в окне, которое не основано на шаблоне wnd_BaseDBEdit:
3.1. В скрипт окна добавляем скрипт scr_SmartLookupUtils в список Use Scripts.
3.2. В скрипт окна добавляем следующие обработчики функции:

function SmartLookupOnDataChange(DataField) {
    ProcessSmartLookupOnDataChange(DataField, Self);
}
 
function SmartLookupDataSetValueOnExecute(ActionMenuItem) {
    SetSmartLookupDataValue(ActionMenuItem);
}
 
function SmartLookupOnChange(LookupControl) {
    ProcessSmartLookupOnChange(LookupControl);
}
 
function SmartLookupSetValueOnExecute(ActionMenuItem) {
    SetSmartLookupValue(ActionMenuItem);
}

3.3. В скрипт окна добавляем обработчики следующих событий:

OnProfileDeserialize:

function <Название_окна>OnProfileDeserialize(Window, Node) {
    ReadSmartLookupDataFromProfile(Window, Node);
}

OnProfileSerialize:

function <Название_окна>OnProfileSerialize(Window, Node) {
    ProcessSaveSmartLookupValuesToProfile(Window, Node);
}

OnShow:

function <Название_окна>OnShow(Window) {
    LoadSmartLookupValues(Window);
}

где <Название_окна> - это название окна, которое содержит LookupControl.

4. Вносим изменения в скрипт 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 выглядит именно таким образом, а не предлагаются в виде готовых сервисов.

5. Теперь включаем данную функцию, например, в окне Задач. Для этого открываем окно wnd_TaskEdit, устанавливаем UseProfile = True, сохраняем окно.

6. Если бы в окне (в нашем случае wnd_TaskEdit) не было обработчика события OnDatasetDataChange для компонента dlData, на этом изменения и закончились бы (функции в состоянии подписаться на необходимые события самостоятельно, без участия разработчика). Однако, если данное событие обрабатывается (в нашем случае в скрипте scr_TaskEdit), придется внести небольшие коррективы в обработчик:
Последней строчкой в функции dlDataOnDatasetDataChange(DataField) скрипта scr_TaskEdit необходимо вставить строку:

    ...
    SmartLookupOnDataChange(DataField);
}

Если в окне уже есть свой обработчик события OnChange для компонента LookupControl, то необходимо в этот обработчик вставить код:

    ...
    SmartLookupOnChange(LookupControl);
}

7. Находим сервис коллекции иконок il_ControlWarnings. Если в нем отсутствует иконка с кодом Wizard, то создаем элемент с таким именем, загружаем иконку из архива п. 1 и сохраняем сервис.

8. В скрипте scr_SmartLookupUtils в массив SmartLookupEnabledWindowsArray добавляем имена окон, в которых хотим иметь Lookup и LookupData контролы с поддержкой SmartLookup. В массив SmartLookupEnabledControlNamesArray добавляем соответствующие имена контролов. Например, если необходимо добавить поддержку SmartLookup для полей Основной контакт и Ответственный для карточки контрагента и Контакт и Контрагент для карточки задачи, необходимо заполнить массивы следующим образом:

var SmartLookupEnabledWindowsArray = 	['wnd_AccountEdit','wnd_TaskEdit'];
 
var SmartLookupEnabledControlNamesArray =
	// wnd_AccountEdit controls
	[['edtPrimaryContact', 'edtOwner'], 
	 // wnd_TaskEdit controls
	['edtContact', 'edtOwner']]

Артем, спасибо за ценное дополнение! Теперь в ряде мест в системе можно существенно повысить удобство и скорость работы. Это оценят те пользователи, для которых приложение на платформе Terrasoft - основной рабочий инструмент.

Спешу обрадовать всех поклонников данной ветки - готова версия Smart Lookup Feature v2.1!

Добавлено:

- Реализован пункт "Настройка..." в выпадающем меню, теперь список запоминаемых значений можно редактировать и сортировать. Это удобно, если запоминаемых значений достаточно много, и среди них есть уже неиспользуемые.

Исправлено:

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

Инструкция по установке немного изменена и находится внутри приложенного архива.

Буду рад замечаниям и пожеланиям. Желаю приятного использования!

Спасибо, Дима! Отчизна тебе благодарна!

Дима, спасибо, многие уже оценили!

Добавлю, что данная функциональность уже включена в следующую версию 3.4.0!

Здравствуйте!
Наши клиенты высказали пожелание в реализации подобного функционала. Начала действовать по инструкции и поняла, что в этой (3.3.2.193) версии уже все как будто есть. То есть никаких изменений вносить не нужно.
Но при этом у нужного поля "волшебной палочки" не наблюдается. Что может быть не так?

Единственное, что меня смущает - это "Если в окне уже есть свой обработчик события OnChange для компонента LookupControl, то необходимо в этот обработчик вставить код:". Не совсем понимаю как это проверить, поскольку не вижу у LookUp'а события "OnChange".

_____
Проблема решена! Оказывается, волшебный значок появляется только после того, как будет выбрано хотя бы одно значение! :)

Дмитрий, обновите, пожалуйста, шапку актуальной версией SmartLookup.
Когда ваша паства может рассчитывать на новые версии?

божественная идея и реализация!
Спасибо !

Показать все комментарии

задача:
для договора формируется отчет, пользователю необходимо выбрать период как параметр для отчета

использую
var SelectDataWindow = Services.GetNewItemByUSI('wnd_SelectData');
var Dataset = Services.GetNewItemByUSI('ds_Period');
SetAttribute(SelectDataWindow, 'Dataset', Dataset);
SetAttribute(SelectDataWindow, 'DisplayFieldNames', 'Name');
SetAttribute(SelectDataWindow, 'SearchFieldNames', 'Name');
SetAttribute(SelectDataWindow, 'KeyFieldName', 'ID');
SetAttribute(SelectDataWindow, 'KeyValue', '');
SetAttribute(SelectDataWindow, 'SearchFieldName', 'Name');
SetAttribute(SelectDataWindow, 'SearchValue', '');
SetAttribute(SelectDataWindow, 'NotifyObject', Self);
SetAttribute(SelectDataWindow, 'Tag', 'Tag');
SelectDataWindow.Prepare();
SelectDataWindow.ShowModal();
// точка 1

для обработчика
function wnd_XXXOnNotify(ScriptableService, Sender, Message, Data) {
if() {
// другой код
} else if (Sender.Caption == 'wnd_SelectData' && Message == MSG_OK){
// точка 2
// здесь пытаюсь получить результат выбора
debugger;
} else
scr_BaseWorkspace.wnd_BaseWorkspaceOnNotify(
ScriptableService, Sender, Message, Data);
}

в каком атрибуте представлен результат выбора?
можно ли в данном случае (SelectDataWindow.ShowModal) не использовать обработчик а получить значения от экземпляра окна на позиции "точка 1"?

Нравится

3 комментария

на данный момент использую

var SelectDataWindow = Services.GetNewItemByUSI('wnd_SelectData');
var Dataset = Services.GetNewItemByUSI('ds_Period');
SetAttribute(SelectDataWindow, 'Dataset', Dataset);
SetAttribute(SelectDataWindow, 'DisplayFieldNames', 'Name', 'ID');
SetAttribute(SelectDataWindow, 'SearchFieldNames', 'Name');
SetAttribute(SelectDataWindow, 'KeyFieldName', 'ID');
SetAttribute(SelectDataWindow, 'KeyValue', '');
SetAttribute(SelectDataWindow, 'SearchFieldName', 'Name');
SetAttribute(SelectDataWindow, 'SearchValue', '');
SetAttribute(SelectDataWindow, 'Tag', 'Tag');
SelectDataWindow.Prepare();
SelectDataWindow.ShowModal();
var PeriodID = SelectDataWindow.ComponentsByName('dlData').Dataset.KeyDataField.Value;

но это совсем коряво

Здравствуйте!

Атрибуты окна выбора Вы можете просмотреть в скрипте scr_SelectData, а именно в функции ReturnSelectedValue:

{
function ReturnSelectedValue(Window) {
var Dataset = SelectData.Dataset;
SelectData.SearchValue =
GetFieldValueFromDisabledField(Dataset, SelectData.SearchFieldName);
SelectData.KeyValue =
GetFieldValueFromDisabledField(Dataset, SelectData.KeyFieldName);
SelectData.KeyValues = grdData.SelectedIDs;
SetAttribute(Window, 'SearchFieldName', SelectData.SearchFieldName);
SetAttribute(Window, 'SearchValue', SelectData.SearchValue);
SetAttribute(Window, 'KeyValue', SelectData.KeyValue);
SetAttribute(Window, 'IsKeyValueNull',
(SelectData.KeyValue == null ? true : false));
SetAttribute(Window, 'KeyValues', SelectData.KeyValues);
}

Если же Вам необходимо использовать в модальном режиме, то Вы можете напрямую считывать значения атрибута окна ('KeyValue').

Terrasoft Support Team

к сожалению после вызова окна в моей реализации для всех атрибутов Attributes.Values(X) - null
тогда как в SelectDataWindow.ComponentsByName('dlData').Dataset.KeyDataField.Value я получаю необходимое значение
спасибо за ответ
попробую выполнить отладку непосредственно в функции ReturnSelectedValue

Показать все комментарии

Здравствуйте.

Можно ли как-то реализовать следующую задачу?

Продукты организованы с помощью древовидной структуры на основе групп. То есть, есть дерево групп, по которым разбросаны продукты (также как сделано в 1С).

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

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

Нравится

15 комментариев

Добрый день, Алексей!

Реализовать выбор продуктов, используя информацию о дереве групп, можно.
Для этого можно, например, создать окно - наследник от wnd_SelectData, в нем добавить древовидный реестр, реализовать заполнение реестра группами продуктов, а при выборе некоторой записи в дереве реализовать наложение фильтров по группе на набор данных продуктов.
Для того, чтобы в поле Продукт выбирать значение с помощью нового окна, необходимо указать окно выбора значения в поле типа LookupDataControl окна редактирования Продукта в Счете. В свойстве SelectWindowUSI компонента edtOfferingName окна wnd_OfferingDetailEdit необходимо указать код созданного окна выбора.

Второй способ - использовать для выбора значения окно wnd_SelectWorkspaceData, однако его придется доработать, чтобы оно смогло стать полноценным окном выбора значения для LookupDataControl. Этот способ более трудоемкий, но даст более наглядный результат - пользователь будет выбирать продукт в окне, которое является разделом Продукты.
Если возникнут вопросы по реализации, буду рад помочь.

Спасибо, скорее всего буду работать над вторым вариантом. По результатам отпишусь.

Схожий вопрос.
Хочу в детали "Группы" в любом разделе, чтобы при нажатии на добавить возникало окно не с списком групп, а с древом.
Создал окно wnd_GroupsTree, установил TemplateWindow - wnd_SelectData.
При попытке добавить в окно элемент DataTreeGrid возникает Разрушительный сбой. Что я делаю не так?

Добрый день, Константин!
Для создания собственного окна выбора, но с древовидным отображением списка, придется создавать его с нуля. Использовать в качестве шаблона окно wnd_SelectData не получится, т.к. в его основе лежит DataGrid, а нужно TreeDataGrid. Также под вопросом использование поиска в таком окне, т.к. при включении каких-либо фильтров возможно нарушение структуры дерева.
Основная задача такого окна - отображение списка записей и при нажатии на кнопку ОК считывать значение ID текущей записи, установка значений в атрибутах окна и посылка сообщения Notify окну, которое вызвало окно выбора (пример см. скрипт scr_SelectData функция btnOkOnClick())
Желаю успехов!

Здравствуйте.
А что значит тогда:
Реализовать выбор продуктов, используя информацию о дереве групп, можно.
Для этого можно, например, создать окно - наследник от wnd_SelectData, в нем добавить древовидный реестр, реализовать заполнение реестра группами продуктов, а при выборе некоторой записи в дереве реализовать наложение фильтров по группе на набор данных продуктов.
?

Если я создаю новое окно, не указываю TemplateWindow,
то при попытке добавить элементы DataGrid или TreeDataGrid возникает Разрушительный сбой.
Как же создать это окно с нуля?

Через наследование от wnd_SelectData сделать можно, но придется скрывать уже существующий компонент DataGrid и добавлять новый DataTreeGrid, а также существенно изменять код, в общем, при более детальном рассмотрении сформирован вывод, что наследование от этого окна в данном случае пользы не дает.
Вообще создать новое окно с нуля можно (добавлять фрейм, затем фреймгруппы и компоненты, не забывать почаще сохранять), но в Вашем случае можно воспользоваться шаблоном wnd_BaseEdit - содержит только два фрейма, во втором две кнопки и невизуальный компонент dlData.
Внутрь компонента frmData можно добавить DataTreeGrid, настроить выравнивание и т.д.
Бороться с "разрушительным сбоем" можно следующим образом: загрузить сохраненную версию окна и аккуратно добавить элементы.
Желаю успехов!

Так я так и пытался делать.
Создаю новое окно, пишу TemplateWindow - wnd_BaseEdit.
Сохраняю, закрываю. Открываю снова.
В frmData создаю DataGrid.
Разрушительный сбой.

Укажите, пожалуйста, полную версию приложения.
Возможно, проблема решится использованием последней версии бинарных файлов.

Воспроизвел, убедился. Зафиксировал запрос на изменение и сообщил разработчикам.
Проверил, на версии 3.0.4.85 DataGrid еще добавляется, в Вашем случае рекомендую создать окно в 3.0.4.85 (взять бинарные файлы этой версии можно в службе поддержки), остальную конфигурацию делать в 3.0.4.112.

P.S. Почему так получилось, что Вы используете такую старую версию системы?

Ок. Попробую более старый дистрибутив. У меня он есть, но версию не помню. Если не получиться, то запрошу.

Решение о покупке CRM принималось ещё в прошлом году.
Тогда и закупили 3.0.4
Когда ж реально приступили к внедрению (этим занимаюсь я несколько месяцев), то оказалось, что 3.0.4 дальше не развивается, а переход на 3.2 (а скоро, я полагаю, на 3.3) требует доплаты за обновление лицензий. Тогда как даже старые себя не оправдали на данный момент...
К тому же ещё и конфигурацию заново придется переписывать или платить за адаптацию.

Здравствуйте.
Разработчики патч ещё не сделали?

Добрый день, Константин!
На данный момент запланированы работы по исправлению, думаю, будет готово в середине ноября.

Хорошо.
Будем ждать.

Показать все комментарии