Доброго времени суток, коллеги.

Есть TerrasoftCRM 3.3.2.245.

При выборе значения фильтра из FilterBuilderControl вызывается стандартное окно wnd_MultiSelectData. Можно ли заменить его на свое? По аналогии с заданием свойства LookupWindowUSI в LookupControl.

Нравится

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

У компонента фильтра есть событие OnFiltersBuilderValueSelect. Возможно, логику можно прописать в его обработчике.

В конфигурации готовых примеров нет, но в 3.4.1 похожее событие OnFiltersBuilderItemSelect в скрипте wnd_IWTGraphWizardScript окна настройки графика переопределяется и в функции fbcFilterOnFiltersBuilderItemSelect задаётся своё окно:

function fbcFilterOnFiltersBuilderItemSelect(FilterBuilderControl, FiltersBuilderItem, AX, AY, DoHandled) {
	DoHandled.Value = false;
	var FiltersBuilder = FilterBuilderControl.FiltersBuilder;
	if (!GraphWizard.CustomDataset) {
		return;
	}
	var FBItemIndex = -1;
	var LastSelectedField;
 
	var CurrentSection = GraphWizard.CurrentSection;
	var SelectWindow = ShowSelectObjectByRelationWindow(CurrentSection.MainTableUSI, smField,
		tlmAllLinks, "Выбор поля фильтрации", null, null, true);
	if (!Assigned(SelectWindow)) {
		return;
	}
	var Results = SelectWindow.Attributes('Results');
	var Path, FBItemIndex, Column, FBItem, Result;
	for (var i = 0, Count = Results.length; i<Count; i++) {
		Result = Results[i];
		Path = Result.Column.FieldPath;
		FBItemIndex = -1;
		if (FiltersBuilderItem) {
			RemoveFilterItem(FiltersBuilderItem);
			FBItemIndex = FiltersBuilder.RootItems.GetIndexOfItem(FiltersBuilderItem);
			FiltersBuilder.RootItems.Remove(FiltersBuilderItem);
		}
		Column = AddFilterItem(Path, null);
		Column.Caption = Result.Column.Caption;
		var CustomDataset = CreateCustomDataset();
		GraphWizard.CustomDataset = CustomDataset
		FiltersBuilder.Dataset = System.EmptyValue;
		FiltersBuilder.Dataset = CustomDataset;
		var DataFields = CustomDataset.DataFields;
		var DataField = null;
		if ((Result.IsLookup != 0) && (Result.IsLookup != null)) {
			DataField = DataFields.ItemsByName(Column.ColumnAlias + 'ID')
		}
		if (!Assigned(DataField)) {
			DataField = DataFields.ItemsByName(Column.ColumnAlias);
		}
		FBItem = FiltersBuilder.RootItems.CreateItemByDataField(DataField);
		if (FBItemIndex < 0) {
			FiltersBuilder.RootItems.Add(FBItem);
		} else {
			FiltersBuilder.RootItems.InsertItem(FBItemIndex, FBItem);
		}
		FBItem.Enabled = true;
		FBItem.RefreshDisplayValue();
		FBItem.ValueNotSet = true;
		FilterBuilderControl.Refresh();
		AddFilterItem(Path, FBItem);
	}
	SetIsChanged();
}
 
function ShowSelectObjectByRelationWindow(MainTableUSI, Mode, TablesListMode,
	WindowCaption, LastSelectedField, ExceptDataTypes, IsHistoryVisible, LinksVisibility,
	OnlyLookupFieldsForTableUSI) {
	var SelectWindow = Services.GetNewItemByUSI('wnd_SelectObjectsByRelations');
	SetAttribute(SelectWindow, 'NotifyObject', Self);
	SetAttribute(SelectWindow, anMode, Mode);
	SetAttribute(SelectWindow, anMainTableUSI, MainTableUSI);
	SetAttribute(SelectWindow, anTablesListMode, TablesListMode);
	SetAttribute(SelectWindow, anDataTypes, ExceptDataTypes);
	if ((ExceptDataTypes) && (ExceptDataTypes.length > 0)) {
		SetAttribute(SelectWindow, anIsFieldDataTypeListIsExceptionList, true);
	}
	SetAttribute(SelectWindow, anLastSelected, LastSelectedField);
	SetAttribute(SelectWindow, anIsHighlightRelations, true);
	SetAttribute(SelectWindow, anOnlyLookupFieldsForTableUSI, 
		OnlyLookupFieldsForTableUSI);
	SetAttribute(SelectWindow, anWindowCaption, WindowCaption);
	SetAttribute(SelectWindow, 'HistoryPageName', "Поля графика");
 
	SetAttribute(SelectWindow, anIsColumnsHistoryVisible, IsHistoryVisible);
	if (!LinksVisibility) {
		SetAttribute(SelectWindow, anLinksVisibility, lvAll);
	} else {
		SetAttribute(SelectWindow, anLinksVisibility, LinksVisibility);
	}
	if (IsHistoryVisible) {
		var UserColumns = new Object();
		var Keys = new VBArray(GraphWizard.CurrentSection.Columns.Keys()).toArray();
		for (var i = 0; i < Keys.length; i++) {
			UserColumns[Keys[i]] = GetUserColumnByColumn(GraphWizard.
				CurrentSection.Columns(Keys[i]));
		}
		SetAttribute(SelectWindow, anColumnsHistory, UserColumns);
	}
 
	SelectWindow.Prepare();
	if (SelectWindow.ShowModal() != wmrOK) {
		return null;
	}
	return SelectWindow;
}

 

Зверев Александр,

Благодарю за помощь.

В коде создается окно wnd_SelectObjectsByRelations. У меня в конфигурации такого сервиса нет. Вы не можете посмотреть, в нем выбирается и поле, по которому будет производится фильтрация и значение фильтра?

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

Нет, там только поля. Значение в карточке настройки графика вводится как в обычном фильтре раздела.

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

У меня в 3.3.2 у FiltersBuilderControl нет события OnFiltersBuilderValueSelect. Только OnFiltersBuilderItemSelect и OnFiltersBuilderItemRemove 

 

 

 

 

 

 

 

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

Интересно вот это окно доступно как сервис конфигурации?

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

Окно больше похожее на генерируемое ядром.

Зверев Александр пишет:

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

Так и собирался сделать. Но мне нужен обработчик события, в котором я могу установить атрибуты для окна wnd_MultiSelectData. Но если примеров реализации толком нет, то не вижу смыла тратить время и просто добавлю LookupControl и в OnPrepareSelectWindow заполню все как мне нужно.

Еще раз благодарю за помощь.

Можно поступить, как во всех боле-менее нестандартных разделах (задачи, проекты): добавить в fmGroupsWindow выше wndGroups новый fg и туда добавить этот LookupControl. Он отобразится выше дерева групп. А логику дополнительной фильтрации привязать, как это сделано в указанных разделах.

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

Доброго времени суток, коллеги.

Система - TerrasoftCRM 3.3.2.245.

Имеется таблица со следующей структурой:

+------------+---------------+-------------+-------------+-------------+-------------+
| Контрагент | Ответственный | Показатель1 | Показатель2 | Показатель3 | Показатель4 |
+------------+---------------+-------------+-------------+-------------+-------------+

Задача такова: нужно в верхней части окна расположить сводные показатели по этой таблице, а в нижней части окна - саму эту таблицу. Сводные показатели считаются достаточно хитро для того, чтобы я их реализовал через вьюшку БД. Поэтому у меня получается два датасета: один для сводных данных, один для плоских.

Вопрос такой: возможно ли использовать один компонент FilterBuilder для установки фильтров на два датасета сразу? 

И если нельзя, то подскажите, как лучше хранить список значений для фильтров? Чтобы пользователь мог отобрать данные по нескольким контрагентам.

Нравится

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

У FiltersBuilderControl есть свойство Mode с двумя возможными значениями. Может, то, что Вы хотите, можно получить, выставив fbmMultiDataset. Но как именно реализовать всю логику, нужно искать похожие примеры или экспериментировать. В стандартной конфигурации свойство Mode нигде не меняли, так что гарантии, что свойство сделано именно для этого, нет.

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

Добрый день!
В отдельном окне реализовал сохранение фильтра через FilterBuilderControl. Фильтр сохраняется и отображается.
Теперь хочу в совершенно другом окне получить отфильтрованный этим фильтром датасет.
Ссылки на FilterDatasetLink и DatasetLink у меня есть.
Подскажите, пожалуйста, как можно применить сохраненный фильтр?

Нравится

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

Допоможіть будьласка розібратися, як в FilterBuilderControl додати встановлений по замовченню фільтр. Тільки не на основі DataField, як вказано нижче, а на основі фільтру користувача створеного в сервісі SelectQuery?

dlData.Dataset.Open();
var Dataset = fbcFilters.DatasetLink.Dataset;
var StateID = Dataset.DataFields.ItemsByName('StateID');
StateID.IsSimpleSelect = false;

var FBItem = fbcFilters.FiltersBuilder.RootItems. CreateItemByDataField(StateID);
FBItem.ValueNotSet = true;
   
fbcFilters.FiltersBuilder.RootItems.Add(FBItem);

У об'єкта RootItems ще є методи CreateItemByUserFilter() і CreateFiltersBuilderItems(). Але як користуватися ними, які створювати для них ввідні об'єкти? Не можу знайти інфо, допоможіть хто знає

Нравится

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

Попробуйте использовать CreateItemByUserFilter(UserFilter) в который надо передать UserFilter из запроса

Це зрозуміло,а от як це зробити? Як із SelectQuery отримати UserFilter?

SelectQuery.Filters.ItemsByCode(код пользовательского фильтра)

Пише Dataset.SelectQuery.Filters is null

Правильно Dataset.SelectQuery.Items(0).Filters.ItemsByCode(код пользовательского фильтра)
Але для метода CreateItemByUserFilter() даний об'єкт не підходить. Пише "Type mismatch"

Небольшая поправка: надо Dataset.SelectQuery.Items(0).Filters использовать.
Кроме того желательно перед этим выполнить Dataset.SelectQuery.LoadUserFilters()

Dataset.SelectQuery.LoadUserFilters() нажаль також не допоміг

Скоріше всього об'єкт UserFilter не із SelectQuery, а метод CreateItemByUserFilter() призначений для іншого якогось об'єкту

Точно для этого. Проблема оказалась в том что Dataset.SelectQuery.Items(0).Filters.ItemsByCode(код пользовательского фильтра) все равно не возвращает нужного пользовательского фильтра.
Пользовательские фильтры чаще всего "спрятаны" внутри Exists фильтров и поэтому для того что бы докопаться до нужного фильтра нужно проделать дополнительную работу

var ExistsFilter = Dataset.SelectQuery.Items(0).Filters.ItemsByCode(код EXISTS фильтра);
var UserFilter = ExistsFilter.TestExpression.ExpressionSelectQuery.Items(0).Filters.ItemsByCode(код пользовательского фильтра);
fbcFilters.FiltersBuilder.RootItems.CreateItemByUserFilter(UserFilter);

Код получився:

dlData.Dataset.Open();
var Dataset = fbcFilters.DatasetLink.Dataset;
var ExistsFilter = Dataset.SelectQuery.Items(0).Filters.ItemsByCode(код EXISTS фильтра);
var UserFilter = ExistsFilter.TestExpression.ExpressionSelectQuery.
Items(0).Filters.ItemsByCode(код пользовательского фильтра); 
var FBItem = fbcFilters.FiltersBuilder.RootItems.CreateItemByUserFilter(UserFilter);    
fbcFilters.FiltersBuilder.RootItems.Add(FBItem);  

При визові FilterWindow.Show() виникає "Разрушительный сбой"

Попередній код такого не викликав :(

У Вас dlData.Dataset и fbcFilters.DatasetLink.Dataset это один и тот же датасет? Если да то после открытия датасета получить пользовательские фильтры для SelectQuery проблематично.

Дійсно, dlData.Dataset і fbcFilters.DatasetLink.Dataset один й той же датасет.
Фільтр я отримую із SelectQuery, дякуючи Вам, тепер успішно. Новий код в Prepare() вікна ні одної помилки не викликає. І тип вказаного вище фільтра підходить методу CreateItemByUserFilter().

Але я думаю виникає нестиковка по якомусь параметру об'єкта UserFilter. Можливо якийсь параметр потрібно змінити?

Або те ж саме з FBItem

попробуйте создать фильтр до открытия датасета. Или при создании фильтра, датасет брать через GetSingleItemByCode.

Нажаль не те, не інше не допомогло
Тей самий "Разрушительный сбой" :(

Пример добавления фильтра в FilterBuilder по UserFilter (базовая версия, р. Контрагенты, фильтр Тип договора, см. прикрепленный файл):

var Dataset = dlData.Dataset;
	var SelectQuery = Dataset.SelectQuery;
	var Select = SelectQuery.Items(0);
 
	var FiltersBuilder = fbcFilters.FiltersBuilder;
	var FBItems = FiltersBuilder.RootItems;	
 
	var ExistFilter = Select.Filters('ContractType');
	var UserFilter = 
		ExistFilter.TestExpression.ExpressionSelectQuery.Items(0).Filters('ContractType');
 
	var FBItem = FBItems.CreateItemByUserFilter(UserFilter);
	FBItems.Add(FBItem);
	FBItem.ValueNotSet = true;
	fbcFilters.Refresh();	

Дякую за допомогу Алексей, Артём без тебе ніяк :)

Знайшов свою помилку, в мене фільтр був 3 рівневий. Додав ще один InnerExistsFilter.TestExpression.ExpressionSelectQuery.Items(0).Filters.ItemsByCode() і все запрацювало!!!

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