Добрый день!

В коробке в карточке "Сотрудник" есть поле "Подразделение" типа Справочник.

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

Есть ли возможность в отдельном поле типа Справочник создать аналогичный формат поиска записи?

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

Нравится

4 комментария
Лучший ответ

Добрый день!

Нужно на странице объявить атрибут:

"OrgStructureUnit": {
	"lookupConfig": {
		"hierarchical": true
	},
	"lookupListConfig": {
		"columns": ["FullName", "Head", "Parent.Head"]
	}
},

И ваш справочник должен поддерживать иерархичность: иметь ссылку Parent на себя.

Подробнее можно посмотреть на странице EmployeePage

Добрый день!

Нужно на странице объявить атрибут:

"OrgStructureUnit": {
	"lookupConfig": {
		"hierarchical": true
	},
	"lookupListConfig": {
		"columns": ["FullName", "Head", "Parent.Head"]
	}
},

И ваш справочник должен поддерживать иерархичность: иметь ссылку Parent на себя.

Подробнее можно посмотреть на странице EmployeePage

Сидоров Александр В.,

Попробовал в карточке "Сотрудник" сделать кастомное поле, которое ссылается туда же, что и поле "Подразделение".

Выбор система предлагает делать в виде дерева. Это заработало. 

Только в результате в поле указывается не "FullName", а "Name".

Требуется ли прописывать дополнительный код или FullName должно заполняться сразу?

Вот пример кода (по сути тут указаны все те же настройки, что и для коробочного поля):

"UsrDep": {

                    "lookupConfig": {

                        "hierarchical": true

                    },

                    "lookupListConfig": {

                        "columns": ["FullName", "Head", "Parent.Head"]

                    }

                }

Можно попробовать на уровне схемы справочника сменить первичное поле для отображения.

Коллеги, спасибо!

Вопрос решен. Ранее уже про правку кода нашел примеры в логике, на которую Сидоров Александр ссылался.

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

Мы часто пользуемся быстрым фильтром и привыкли к такой удобной функциональности. Но при работе в деревом такой функциональности нет.
Привожу пример, как, с моей точки зрения, возможна реализация функциональности быстрого фильтра в дереве. Это только один из возможных вариантов. Вы можете предложить большее.

Мельникова Екатерина на эту тему даже создала идею: community.terrasoft.ua/node/3032.
Главная идея - дерево может находится в двух режимах - дерево и список. При работе с деревом фильтрация невозможно. При работе со списком - мы можем осуществлять поиск нужной нам записи, и при переключении обратно в режим дерева мы позиционируемся на найденной записи.

Основа - режим переключения из дерева в список. В приведенном примере переключение между деревом и списком осуществляется по горячей клавише Ctrl-Q. Включение / отключение фильтра осуществляются по горячей клавише Ctrl-S.

Открываем окно с DataTreeGrid (в данном примере отображены все папки из директория "Program Files", Вы можете загрузить подобную структуру по кнопке "Загрузить папки из директория"):
Дерево для поиска

Допустим, в дереве Вам необходимо найти библиотеку картинок программы Skype. В поле ввода быстрого фильтра набираем текст "Skype" и нажатием Ctrl-S включаем бытрый фильтр, который будет включен при переходе в режим отображения список.
Ввод параметров быстрого фильтра

Переключение просмотра в режим "Список" нажатием Ctrl-Q, после чего можно выбрать необходимую запись:
Переключение в режим

После того, как Вы нашли искомую запись - переключаемся в режим просмотра "Дерево" (Ctrl-Q):
Переключение в режим дерево и позиционирование на найденной записи

Пример сервисов для работы быстрого фильтра в дереве Вы можете найти в присоединенном архиве TreeQuickFilter_Example.rar.

Основные моменты реализации:

Переключение режима "Дерево / Список" осуществляется подстановкой значения свойства "ParentDataFieldName" компонента DataTreeGrid поля "ParentID" если мы хотим видеть дерево или "ID", если нам нуже список (в данном случае возможно переключение без перезапроса данных в базе данных):

function SwitchTreeListViewType() {
        var ParentDataFieldName = grdData.ParentDataFieldName;
        if (ParentDataFieldName == 'ParentID') {
                grdData.ParentDataFieldName = 'ID';
                cbQuickFilter.IsEnabled = true;
        } else {
                grdData.ParentDataFieldName = 'ParentID';
                cbQuickFilter.IsEnabled = false;
        }
        UpdateQuickFilter();
}

Выбор директория для загрузки в таблицу структуры папок:

function LoadFoldersFromDirectory() {
        var FolderNameObject = System.CreateObject('TSObjectLibrary.Value');
        if ((System.SelectDirectory("Выберите папку", '', FolderNameObject))) {
                var FolderName = FolderNameObject.Value;
                var Dataset = dlData.Dataset;
                LoadDirectoryItemsFromFolder(FolderName, Dataset);
        }
}

Загрузка структуры директория осуществляется с помощью рекурсивной функции:

function LoadDirectoryItemsToDataset(Path, Dataset, ParentID) {
        try {
                var Folder = FileSearchGridArea.FSO.GetFolder(Path);
                var Folders = new Enumerator(Folder.SubFolders);
                for (Folders.moveFirst(); !Folders.atEnd(); Folders.moveNext()) {
                        var Item = Folders.item();
                        var Name = Item.Name;
                        var Path = Item.Path;
                        var ID = AddFolderToDataset(Dataset, ParentID, Name, Path);
                        LoadDirectoryItemsToDataset(Path, Dataset, ID);
                }
        } catch(e) {
                ShowErrorDialog(e.message);
        }
}

Обработка горячих клавиш осуществляется в событии OnKeyDown DataTreeGrid:

function DoKeyDown(Control, Key, Shift) {
        var CtrlDown = (Shift & 4) > 0;
        if (CtrlDown) {
                var QKeyCode = 81;
                if (Key.Value == QKeyCode) {
                        SwitchTreeListViewType();
                }
                var SKeyCode = 83;
                if (Key.Value == SKeyCode) {
                        cbQuickFilter.IsChecked = !cbQuickFilter.IsChecked;
                }
        }
}

Данный вариант работы с деревом имеет свои ограничения:

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

Конечно, реализовывать такое в конфигурации трудоемко, но можно. Лучшим решением было бы реализовать быстрый фильтр в ядре в компоненте DataTreeGrid.

Используйте на здоровье.

Нравится

Поделиться

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

Автору - спасибо!
Разработчикам - быстрый фильтр в ядре для компоненты DataTreeGrid!

--
γνῶθι σεαυτόν

А в чем сложности при организации подгрузки узлов дерева по требованию? И с большими объемами бы тогда работалось нормально.

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

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

В данном примере такая задача не решается. Это я и поразумевал фразой "Вы можете предложить большее".

Спасибо. Пригодилось!

Мне тоже пригодилось. Спасибо :smile:

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