Вопрос

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

В разделе создал пользовательские фильтры Улица, Дом , Квартира. Значения в фильтре Дом зависят от Улицы, а значения в фильтре Квартира от значения Дом.

Если нажимать на "лупу" то фильтрация успешно отрабатывает. Но если вводить значения в поле - фильтр в выпадающем списке не срабатывает.

Как реализовать фильтрацию выпадающего списка в разделе?

Код схемы раздела:

define("VcApartments1Section", ["BaseFiltersGenerateModule", "css!VcMyFilterStyle"], 
function(BaseFiltersGenerateModule) {
	return {
		entitySchemaName: "VcApartments",
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "MyFilterGroupContainer",
				"parentName": "LeftGridUtilsContainer",
				"propertyName": "items",
				"index": 0,
				"values": {
					"id": "MyFilterGroupContainer",
					"itemType": this.Terrasoft.ViewItemType.CONTAINER,
					"items": []
				}
			},
			{
				"operation": "insert",
				"name": "MyFilterContainer",
				"parentName": "MyFilterGroupContainer",
				"propertyName": "items",
				"index": 0,
				"values": {
					"id": "MyFilterContainer",
					"itemType": this.Terrasoft.ViewItemType.CONTAINER,
					"items": []
				}
			},
			{
				"operation": "insert",
				"parentName": "MyFilterContainer",
				"propertyName": "items",
				"name": "VcStreetFilter",
				"values": {
					"bindTo": "VcStreetFilter",
					"caption": "Улица"
				}
			},
			{
				"operation": "insert",
				"name": "MyFilterContainer2",
				"parentName": "MyFilterGroupContainer",
				"propertyName": "items",
				"index": 1,
				"values": {
					"id": "MyFilterContainer2",
					"itemType": this.Terrasoft.ViewItemType.CONTAINER,
					"items": []
				}
			},
				{
				"operation": "insert",
				"parentName": "MyFilterContainer2",
				"propertyName": "items",
				"name": "VcHouseFilter",
				"values": {
					"bindTo": "VcHouseFilter",
					"caption": "Дом"
					// "controlConfig": {
					// 	"prepareList": {
	    //                         "bindTo": "VcHouseFilter"
	    //                     }
					// // "contentType": Terrasoft.ContentType.ENUM
					// }
				}
			},
			{
				"operation": "insert",
				"name": "MyFilterContainer3",
				"parentName": "MyFilterGroupContainer",
				"propertyName": "items",
				"index": 2,
				"values": {
					"id": "MyFilterContainer3",
					"itemType": this.Terrasoft.ViewItemType.CONTAINER,
					"items": []
				}
			},
			{
				"operation": "insert",
				"parentName": "MyFilterContainer3",
				"propertyName": "items",
				"name": "VcNameFilter",
				"values": {
					"bindTo": "VcNameFilter",
					"caption": "Квартира"
				}
			}
			]/**SCHEMA_DIFF*/,
		attributes: {
			"VcStreetFilter": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				isLookup: true,
				caption: "VcStreet",
				referenceSchemaName: "VcStreet"
			},
			"VcHouseFilter": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"lookupListConfig": {
					// Массив фильтров, применяемых к запросу для формирования данных поля-справочника.
					"filters": [
						function() {
							var filterGroup = Ext.create("Terrasoft.FilterGroup");
							var VcStreetFilter = this.get("VcStreetFilter");
							if (VcStreetFilter && VcStreetFilter.value) {
							filterGroup.add("VcStreetFilter",Terrasoft.createColumnFilterWithParameter
							(Terrasoft.ComparisonType.EQUAL, "[VcHouses:Id].VcStreet", VcStreetFilter.value));
							} else {
								filterGroup.removeByKey("VcStreetFilter");
							}
							return filterGroup;
						}
					]
				},
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				isLookup: true,
				caption: "VcHouse",
				referenceSchemaName: "VcHouses"
			},
			"VcNameFilter": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"lookupListConfig": {
					// Массив фильтров, применяемых к запросу для формирования данных поля-справочника.
					"filters": [
						function() {
							var filterGroup = Ext.create("Terrasoft.FilterGroup");
							var VcHouseFilter = this.get("VcHouseFilter");
							if (VcHouseFilter && VcHouseFilter.value) {
							filterGroup.add("VcHouseFilter",Terrasoft.createColumnFilterWithParameter
							(Terrasoft.ComparisonType.EQUAL, "[VcApartments:Id].VcHouse", VcHouseFilter.value));
							} else {
								filterGroup.removeByKey("VcHouseFilter");
							}
							return filterGroup;
 
						}
					]
				},
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				isLookup: true,
				caption: "VcName",
				referenceSchemaName: "VcApartments"
			}
		},
		mixins: {
			LookupQuickAddMixin: "Terrasoft.LookupQuickAddMixin"
		},
		methods: {
			onLookupChange: function(newValue, columnName) {
				this.callParent(arguments);
				if (columnName === "VcStreetFilter") {
					this.set("VcStreetFilter", newValue);
					this.onVcStreetFilterChanged();
				}
				if (columnName === "VcHouseFilter") {
					this.set("VcHouseFilter", newValue);
					this.onVcHouseFilterChanged();
				}
				if (columnName === "VcNameFilter") {
					this.set("VcNameFilter", newValue);
					this.onVcNameFilterChanged();
				}
			},
 			// Обновляет грид
			onVcStreetFilterChanged: function() {
				this.reloadGridData();
			},
 
			onVcHouseFilterChanged: function() {
				this.reloadGridData();
			},
 
 			onVcNameFilterChanged: function() {
				this.reloadGridData();
			},
			// Инициализирует фиксированные фильтры
			initQueryFilters: function(esq) {
				this.callParent(arguments);
			// Фильтр по Улице
				var VcStreetFilter = this.get("VcStreetFilter");
 
				if (VcStreetFilter && VcStreetFilter.value) {
					esq.filters.add("VcStreetFilter", this.Terrasoft.createColumnFilterWithParameter(
						this.Terrasoft.ComparisonType.EQUAL, "[VcApartments:Id].VcStreet", VcStreetFilter.value));
				} else {
					esq.filters.removeByKey("VcStreetFilter");
				}
			// Фильтр по Дому
				var VcHouseFilter = this.get("VcHouseFilter");
 
				if (VcHouseFilter && VcHouseFilter.value) {
					esq.filters.add("VcHouseFilter", this.Terrasoft.createColumnFilterWithParameter(
						this.Terrasoft.ComparisonType.EQUAL, "[VcApartments:Id].VcHouse", VcHouseFilter.value));
				} else {
					esq.filters.removeByKey("VcHouseFilter");
				}
			// Фильтр по названию
				var VcNameFilter = this.get("VcNameFilter");
 
				if (VcNameFilter && VcNameFilter.value) {
					esq.filters.add("VcNameFilter", this.Terrasoft.createColumnFilterWithParameter(
						this.Terrasoft.ComparisonType.EQUAL, "[VcApartments:Id].Id", VcNameFilter.value));
				} else {
					esq.filters.removeByKey("VcNameFilter");
				}
			}
		}
	};
});

 

У меня такой же вопрос

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

Сталкивался с подобной проблемой. Пришлось заместить данные методы на странице редактирования (в моем случае) InvoiceSectionV2

			/**
			 * @inheritdoc Terrasoft.BaseViewModel#onLookupDataLoaded
			 * @override
			 */
			onLookupDataLoaded: function(config) {
				this.callParent(arguments);
				this.mixins.LookupQuickAddMixin.onLookupDataLoaded.call(this, config);
			},
			getLookupListConfig: function() {
				return this.mixins.LookupQuickAddMixin.getLookupListConfig.apply(this, arguments);
			},
 
			/**
			 * @inheritdoc Terrasoft.BaseViewModel#getLookupQuery
			 * @override
			 */
			getLookupQuery: function(filterValue, columnName) {
				var esq = this.callParent(arguments);
				this.applyColumnsOrderToLookupQuery(esq, columnName);
				var filterGroup = this.getLookupQueryFilters(columnName);
				esq.filters.addItem(filterGroup);
				return esq;
			},
			/**
			 * Applies order information to lookup entity schema query.
			 * @protected
			 * @param {Terrasoft.EntitySchemaQuery} esq Entity schema query.
			 * @param {String} columnName Lookup column name.
			 */
			applyColumnsOrderToLookupQuery: function(esq, columnName) {
				var lookupColumn = this.getColumnByName(columnName);
				var lookupListConfig = lookupColumn.lookupListConfig;
				if (!lookupListConfig || !lookupListConfig.orders) {
					return;
				}
				var columns = esq.columns;
				this.Terrasoft.each(lookupListConfig.orders, function(order) {
					var orderColumnPath = order.columnPath;
					if (!columns.contains(orderColumnPath)) {
						esq.addColumn(orderColumnPath);
					}
					var sortedColumn = columns.get(orderColumnPath);
					var direction = order.direction;
					sortedColumn.orderDirection = direction ? direction : Terrasoft.OrderDirection.ASC;
					var position = order.position;
					sortedColumn.orderPosition = position ? position : 1;
					this.shiftColumnsOrderPosition(columns, sortedColumn);
				}, this);
			},
			/**
			 * Shift columns order position.
			 * @private
			 * @param {Array} columns Entity columns.
			 * @param {Object} sortedColumn Entity sorting column.
			 */
			shiftColumnsOrderPosition: function(columns, sortedColumn) {
				var sortedColumnOrderPosition = sortedColumn.orderPosition;
				if (Ext.isNumber(sortedColumnOrderPosition)) {
					columns.each(function(column) {
						if (column !== sortedColumn && Ext.isNumber(column.orderPosition) &&
							column.orderPosition >= sortedColumnOrderPosition) {
							column.orderPosition += 1;
						}
					});
				}
			},

 

Спасибо, все получилось!

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!

Внутри CRM есть большое число позиций изделий из сплавов металлов. В сплав может входить от двух до четырех металлов.  

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

Есть ли способ найти только те позиции, где требуемый металл находится на первом месте?
(Например: АРбуз, АРка, АРгон. Но не: бАРжа, кАРтон, сАРай) 

У меня такой же вопрос

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

Вариантов много я бы посмотрел в сторону

1) Искать начинающиеся на #Арб

2) или изменить структуру хранения данных о составе металла

3) а лучше всего, создать свой фильтр в котором вы обработаете вашу строку с указанием сплава. (Например разобьете в массив со списком металлов и его отфильтруете)

В расширенных фильтрах

 

Варфоломеев Данила,

Спасибо за совет, но строка с указанием сплава имеет вид - #Наименование сплава# (#Металл1##Металл2##Металл3##Металл4#) Например: Мельхиор (CuNi)

Вариантов много я бы посмотрел в сторону

1) Искать начинающиеся на #Арб

2) или изменить структуру хранения данных о составе металла

3) а лучше всего, создать свой фильтр в котором вы обработаете вашу строку с указанием сплава. (Например разобьете в массив со списком металлов и его отфильтруете)

А что мешает искать по «(Cu»?

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

Спасибо за совет, хорошая идея!

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Товарищи помогите решить задачу.

Есть справочное поле и собственно сам справочник, открывающийся в модальном окне.

Справочник вида :Название - Описание.

Задача фильтровать значения по колонке описание

Я так понимаю что в атрибутах я должен сделать что-то вроде

"UsrDebtorStatus":{
  dataValueType: Terrasoft.DataValueType.LOOKUP,
  lookupListConfig: {
      filter: function() {
      var description= "Дебитор";
      return Terrasoft.createColumnFilterWithParameter( Terrasoft.ComparisonType.EQUAL, "????????????",description);
              }
      }
  }

 

У меня такой же вопрос

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

если UsrDebtorStatus — обычный справочник, то скорее всего Name. Обычно 2 параметром идёт колонка из объекта (в "кубик" UsrDebtorStatus загляните). Ну и лучше всего по guid-у сортировать

Роман, добрый день!

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

1. Согласно базовой логике приложения, для того, чтоб иметь возможность реализовать фильтрацию в зависимости от типа клиента, колонка, которая содержит записи типов клиентов (в справочнике), должна быть с типом "Справочник". Данную колонку необходимо добавить в разделе "Конфигурация":
  - найти объект, который является Вашим справочником
  - открыть объект, развернуть его наполнение объекта, нажать правой кнопкой мыши на "Inherited Columns", выбрать "Добавить", выбрать тип колонки "Справочник";
  - в свойствах созданной колонки, в поле «Справочник» указать справочник типов, по которому необходимо будет выполнять фильтрацию;
  - опубликовать объект.

2. На странице раздела, в которой будет присутствовать справочное поле, настроить бизнес-правило:
  - добавить действие бизнес-правила "Добавлять фильтр значений в поле"
  - указать в поле "какую колонку фильтровать и по какой связи в справочнике этого поля" - созданное справочное поле по связи с полем, в котором указан тип клиента;
  - указать в поле "по какому полю фильтровать" поле на странице раздела, в котором указан тип клиента;
  - сохранить изменения.

Больше о настройке бизнес-правил Вы сможете узнать на Академии: https://academy.terrasoft.ru/documents/sales-enterprise/7-11/nastroyka-biznes-pravil
Также на Академии есть информация по разработке бизнес-правила фильтрации: https://academy.terrasoft.ru/documents/technic-sdk/7-11/primer-primeneniya-pravila-filtration, но мы рекомендуем использовать функционал Бизнес-правил в Мастере раздела.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день.
Создал иерархический справочник "Варианты" со структурой (ID, ParentID, Name) и в таблице задач (tbl_Task) создал поле, ссылающееся на этот справочник.
Хочу сделать такой пользовательский фильтр, чтобы выбирал задачи, у которых значение варианта совпадает с выбранным в фильтре или было подчиненным ему.
Есть значения
1.0
|- 1.1
|- 1.2
|- 1.3
2.0
|- 2.1
|- 2.1.1
и т.п.
Я хочу,чтобы после применения этого фильтра при значении 1.0 отбирались задачи со значениями вариантов 1.0, 1.1, 1.2 и 1.3.

Я хотел реализовать это с помощью пользовательского фильтра справочника. Для этого я сделал табличную функцию, которая принимает ID записи из фильтра и возвращает ID этой записи и всех ее потомков. Но для пользовательского фильтра параметр запроса генерируется только при исполнении и не доступен в администраторе. Можно это как нибудь обойти?
Или другой вариант: можно ли обычный фильтр (не пользовательский) вывести на панель фильтров и заполнять параметр этого фильтра вручную?

У меня такой же вопрос

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

Я так понимаю ID и ParentID - ссылки на данные одной и той же таблицы? Тогда просто добавьте пользовательский фильтр по полю ParentID. Значения будете выбирать из общего пула записей в данной таблице, а в результате будете получать только подчиненный к выбранной записи данные.

ps: возможно будет проблема с отображением данных в реестре после фильтрации, т.к. в наборе данных не будет представлен корневой элемент,и дерево не сможет отрисоваться. В таком случае необходимо использовать UNION по аналогии с разделом "Проекты".

Спасибо за ответ, но мне это не поможет, так как в справочнике может быть много уровней иерархии. Допустим, что узел 2.1.1 подчинен 2.1, а тот, в свою очередь, 2.0. Если я в фильтре укажу отобрать по 2.0, то получу только те задачи, у которых 2.0 и 2.1. 2.1.1 напрямую не подчинен и выведен не будет.
Я посмотрел в отладчике, при накладывании пользовательского фильтра генерируется что-то типа:

WHERE(([tbl_Task].[InformationTypeID] IN (:AutoGen_00160FA_4653CC2)))

Есть ли возможность добраться до этого механизма или это функционал самой платформы и из js не доступен?

Нет, нельзя... Генерация фильтров компонентом FuilterBuilder это ядровые механизмы.

ps: насколько я помню подчиненные элементы должны отрисоваться автоматом, т.е. при структуре

1
1.1
1.1.1
2
2.1
2.1.1

Если ввести в фильтр 1.1, то 1.1.1 у вас отобразится автоматом. Разумеется, если в выборке будет присутствовать и 1 (т.е. где запись ParentID = null). Это решается UNION'ом.

В любом случае - можете добавить какую либо кнопку и всю фильтрацию реализовать скриптом на JS.

День добрый!!! вот в Интернете нашел интересную статью. http://www.getinfo.ru/article610.html
Всю задачу что описал Riptor я бы решил в террасофте один в один как в Статье. Если требуется помощь в реализации данной статьи в Террасофте обращайтесь помогу. Только вот если честно так и не понял зачем Задачи делать Иерархические и еще со сложными Древовидностями? Цель какая?

Здравствуйте, Михаил.

Вероятно, речь идет о функционале, схожим с разделом "Проекты", но при этом реализованным на основе раздела "Задачи", т.к., возможно, пользователям привычнее работать именно с этим разделом.
Т.е. разбивать большие задачи на несколько маленьких и наглядно видеть структуру этих задач в самом реестре.

В любом случае, на Ваш вопрос лучше ответит автор данного "топика", г-н Riptor.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день, TS Community. В запросе используется 2 Uniona. Создал пользовательский фильтр по строке в каждом select'е. В клиенте отображается 3 одноименных фильтра. Как обойти эту проблему? Буду благодарен за советы.

У меня такой же вопрос

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

Добрый день, Антон!

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

Спасибо

Антон, пожалуйста, предоставьте скриншот фильтр-билдера.

Выкладываю скрин:
FilterBuilder

Антон, спасибо за скриншот. Ваше обращение передано в департамент разработки. По факту предоставления решения мы с Вами свяжемся.

Вот решали эту проблему здесь

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

Антон, проблема рассматривается на уровне департамента разработки. Планируемый срок предоставления решения - 13.01.2014

Хорошо, спасибо, буду ждать

Антон, Вам необходимо в скрипте своего раздела в нужном месте подставить функцию очистки пользовательских фильтров, как описано здесь

Мне вот интересно, я 25 декабря писала эту ссылку, как сказано:

"Каневский Антон Владимирович" написал:Решение проблемы специфическое, относится к определенному скрипту в Проектах.

Но все-таки это оно и есть?

Пробую, как Вы сказали... Сопоставить раздел Проекты и применить это в своем, не получается. Можно, в общих чертах, описать, что нужно сделать с моими select'ами в коде?

Такое поведение компонента FiltersBuilder связано с логикой построения запросов. В компонент последовательно выводятся фильтра из SelectQuery dataset’а. Т.к. в запросе есть Union, согласно ядровой логики, пользовательские запросы добавляются для каждого select’а, т.е. 1 – union = 2 раза, 2 – union’а = 3 раза и т.д. Проблема решается конфигурационно, путём очистки пользовательских фильтров. Указанное решение рекомендуем применить, например, на BeforeOpen dataset’а грида.

спасибо. Но мне не нужно очищать пользовательские фильтры, ведь в разделе они могут быть сохранены и нужны.. А так они затираются в select'ах...

Антон, добрый день.

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

Конечно, было бы замечательно, если бы в дальнейших сборках учли эту особенность фильтров.
Кстати, версия TS XRM 3.4.0.130.
Задачу решил так: вытянул в sq sql text column, в которую вытягиваю необходимые данные (в моем случае это данные с детали моего раздела) , по которым хочу фильтровать. В датасет запроса добавляю поле с соответствующим типом. Для меня вопрос закрыт, всем спасибо

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!
Помогите реализовать в конфигураторе пользовательский фильтр в разделе "Контрагенты".
У меня есть деталь "Закрепленные сотрудники". Хочу выбрать контрагентов, которые никогда не были закреплены за каким-нибудь конкретным сотрудником.
В SQL запрос выглядит следующим образом:

SELECT [GT-TRANS_PROG].[dbo].[tbl_Account].*
  FROM [GT-TRANS_PROG].[dbo].[tbl_Account]
  WHERE (
                        ([ID] NOT IN
(SELECT [GT-TRANS_PROG].[dbo].[tbl_MountedStaff].[AccountID]
FROM [GT-TRANS_PROG].[dbo].[tbl_MountedStaff]
WHERE [GT-TRANS_PROG].[dbo].[tbl_MountedStaff].[StaffID] = '56B74B8C-5C11-49D1-AF62-3BD4DDBCE283')
                        )
                 )

У меня такой же вопрос

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

Добрый день!
Вам необходимо добавить в запрос sq_Account IncludeFilter с использованием Test Subquery.
Т.е. необходимо реализовать Фильтр «IN» более сложной структуры:
- Добавить IncludeFilter, установить признак "Not".
- Для выражения в поле «Тип» указать Test Subquery:
/system/files/_1__0.png
- Сохранить сервис запроса и переоткрыть его.
- Фильтр будет иметь вид:
/system/files/_2_.png
В результате, Вы сможете реализовать Фильтр «IN» нужного вида.

Добрый день!
Спасибо за ответ!
Так и сделал. Но возникла проблема - фильтр в блоке фильтрации вижу только на своем компьютере. На других компьютерах даже под своим пользователем с правами системного администратора фильтра не видно.
Прилагаю скриншот фильтра.

Пробовал чистить кеш, не помогает.

Сделал то же самое (вроде как) с помощью фильтра Exists - видно нормально всем пользователям. Очень странно.

Создала подобный фильтр (версия бинарных файлов 3.4.0.149) - пользовательский фильтр (входящий в IncludeFilter) отображается на разных машинах.
Какую версию Вы используете?

У нас используется версия 3.3.0.84

Николай, добавила подобный фильтр, он отображается корректно.
Проверяла на разных машинах и на разных сборках (3.3.0.84 и 3.3.0.63)

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!

TS 3.3.2.211, Оракл

Создал раздел Карты. Раздал права доступа необходимым группам. У группы все пользователи нет прав на этот раздел вообще. В разделе Контакты создал пользовательский фильтр ссылающийся на созданный раздел. Для пользователя, у которого есть права на раздел Карты фильтр работает идеально. Если у пользователя нет прав на этот раздел, то получаем ошибку ORA-00904: "tbl_Card"."ContactID": invalid identifier. При этом на сервер отправляется вот такой вот запрос:

SELECT
        "ID",
        "Name",
        "Communication1",
        "AccountName",
        "AccountID",
        "ContactTypeID",
        "ContactTypeName"
FROM (
SELECT
        "tbl_Contact"."ID" "ID",
        "tbl_Contact"."Name" "Name",
        "tbl_Contact"."Communication1" "Communication1",
        "tbl_Account"."Name" "AccountName",
        "tbl_Contact"."AccountID" "AccountID",
        "tbl_Contact"."ContactTypeID" "ContactTypeID",
        "tbl_ContactType"."Name" "ContactTypeName"
FROM
        "TS"."vw_Contact" "tbl_Contact"
LEFT OUTER JOIN
        "TS"."vw_Account" "tbl_Account" ON "tbl_Account"."ID" = "tbl_Contact"."AccountID"
LEFT OUTER JOIN
        "TS"."tbl_ContactType" "tbl_ContactType" ON "tbl_ContactType"."ID" =
"tbl_Contact"."ContactTypeID"
WHERE (("tbl_Contact"."IsNotActive" :pIsActive) AND
        (EXISTS
        (SELECT
                NULL "ID"
        FROM
                "TS"."tbl_Empty" "tbl_Card"
        WHERE ("tbl_Contact"."ID" = "tbl_Card"."ContactID" AND
                1 = 0 AND
                1 = 0 AND
                1 = 0 AND
                1 = 0))))
ORDER BY
        2 ASC
)
 WHERE ROWNUM 40

Что я прописал не так для пользовательского фильтра в запросе? Сервис запроса прилагаю.

У меня такой же вопрос

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

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

В tbl_Empty нет поля ContactID:

SELECT 
                NULL "ID"
        FROM 
                "TS"."tbl_Empty" "tbl_Card"
        WHERE ("tbl_Contact"."ID" = "tbl_Card"."ContactID"

Если у пользователя нет прав на таблицу, то при построении запроса она заменяется на tbl_Empty, поэтому возникает такая ошибка.

Из решений вижу отключение фильтра перед открытием датасета, если нет прав на эту таблицу.

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

С моей стороны может быть сделано простое решение: добавить в таблицу tbl_Empty поле ContactID. Но тогда такое поле необходимо добавлять фактически для каждого раздела.

Может кто-то еще сталкивался с подобной ситуацией? Как решали данную проблему?

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

В данном случае следует раздать права таким образом:

Дать права на чтение на tbl_Card группе Все пользователи;

Установить для нее признак "Администрируется по записям" и убрать из прав по умолчанию на записи группу Все пользователи.

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

В Вашем случае есть вариант воспользоваться отдельной функциоей получения результата запроса в CustomSqlColumn:

http://www.community.terrasoft.ua/blogs/8267#comment-34549

Анна, спасибо, но как-то неправильно давать права на чтение всем пользователям. Они вообще не должны видеть этот раздел, не говоря о его содержимом. Как Вы говорите можно скрыть раздел в зависимости от прав пользователя? Может все-таки можно в ядре что-то подправить? Ведь попытка обработать такую ситуацию ядром системы есть...

Записей они видеть не будут, только сам раздел.

Для того, чтобы скрыть раздел в меню, нужно в scr_Main в функции InitializeWorkspacesInfo() добавить проверку на вхождение пользователя в определнную группу, например.

amiCard.IsVisible = Value; //результат проверки

Я всё же настаиваю что это ошибка и вопрос необходимо передать разработчикам для исправления. Например сделать как при отображении детали, на которую нет прав доступа на чтение:

SELECT
	"ID",
	"SalesPointID",
	"SalesPointName",
	"PurchaseDate",
	"PurchaseNumber",
	"ContactID",
	"ContactName",
	"CardID",
	"CardNumber",
	"PromoutionCheckID",
	"CheckNumber",
	"DiscountTypeID",
	"DiscountTypeName",
	"BasicAmountPaid",
	"BasicTotalDiscount",
	"BasicTotalBonus",
	"CashierID",
	"CashierName"
FROM (
SELECT 
	NULL "ID",
	NULL "SalesPointID",
	NULL "SalesPointName",
	NULL "PurchaseDate",
	NULL "PurchaseNumber",
	NULL "ContactID",
	NULL "ContactName",
	NULL "CardID",
	NULL "CardNumber",
	NULL "PromoutionCheckID",
	NULL "CheckNumber",
	NULL "DiscountTypeID",
	NULL "DiscountTypeName",
	NULL "BasicAmountPaid",
	NULL "BasicTotalDiscount",
	NULL "BasicTotalBonus",
	NULL "CashierID",
	NULL "CashierName"
FROM 
	"TS"."tbl_Empty" "tbl_PromoutionPurchase"
LEFT OUTER JOIN
	"TS"."tbl_SalesPoint" "tbl_SalesPoint" ON "tbl_SalesPoint"."ID" = NULL
LEFT OUTER JOIN
	"TS"."vw_Contact" "tbl_Contact" ON "tbl_Contact"."ID" = NULL
LEFT OUTER JOIN
	"TS"."tbl_DiscountType" "tbl_DiscountType" ON "tbl_DiscountType"."ID" = NULL
LEFT OUTER JOIN
	"TS"."vw_Contact" "Cashier" ON "Cashier"."ID" = NULL
WHERE (1 = 0)
)
 WHERE ROWNUM <= 40

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

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

Анна, задача простая: необходимо дать пользователю, у которого есть право на чтение раздела Карты, вывести контакты, у которых есть карта, удовлетворяющая определённым условиям (по номеру, по типу и т.п.). Для этого в сервисе sq_Contacts (прикреплен к первому сообщению) я создал фильтр типа Exist с названием CardsFilter. Пытался сделать его на подобие аналогичных фильтров. Может я что-то перемудрил?

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

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

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

Дмитрий, для меня так и останется загадкой почему конфигурация может определить что при применении пользовательского фильтра у пользователя нет доступа в другой раздел и подставить вместо tbl_Card tbl_Empty, а вместо tbl_Card.ContactID подставить NULL (как в посте №7) она не может.

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

Ozzy, дело в том что эти данные подставляет не конфигурация, а ядро.
А почему Вы не хотите скрыть иконку "Раздела" для тех кому он не должен быть виден, а доступ на чтение на раздел "Карты" выдать?

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

Ozzy, я сообщу в департамент разработки о проблеме. По результатам Вам отпишу в этом топике.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Доброе время суток участникам форума!

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

Логика такая:
- создан новый справочник "отрасли КВЭД" (стандартный справочник "Отрасли" решила не "ломать")
- реестр переделан на древовидный (добавлено поле парентдИД и т.п.)
- создано доп.поле "полный путь", в котором генерируется названия предыдущих "уровней" (без текущего уровня -- на скриншоте есть пример). поле табличное, то есть информация хранится в бд.
- в запросе контрагентов создан пользовательский подзапрос для этого поля

Задача -- создать динамические группы по отраслям.
Проблема в том, что по некоторым контрагентам может быть заполнена отрасль значением 1го уровня (либо 2, либо 3), пока не уточнится 4й уровень (всего максимум 4 уровня). Поэтому, если указана группа, допустим, 2го уровня -- то в нее должны входить и те контрагенты, где отрасль либо она, либо "ниже по иерархии".

Но -- при нажатии на кнопку "применить" -- оно не фильтрует! отображает все записи. хотя должно отображать только 2, так как в одном контрагенте отрасль вообще не выбрана, а в другом -- другой "верхний" уровень. Даже не так, судя по моей логике отображать должно, наверное, только одну запись (тест 1).

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

Еще -- можно, конечно, сделать фильтр типа "отрасль КВЭД равна"+выбрать все возможные значения соответствующих уровней. но это не выход, так как отрасль может добавится, удалиться и т.п. Разве что как временное решение.

п.с. бинарные файлы -- 3.3.2.179, Террасофт СРМ, скул 2008р2. кеш чистился.

Заранее спасибо за помощь.

У меня такой же вопрос

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

Ольга, для диагностики необходим полный текст запроса, который идет в базу данных. Рекомендую попробовать посмотреть профайлером и прикинуть примерный запрос на выборку в Management Studio. так будет проще понять, что именно реализовать в конструкторе запросов.

Здравствуйте, Анна!
профайлер показал, что в бд никаких запросов не шло. но я нашла ошибку -- оказывается, пользовательский фильтр нужно предварительно "завернуть" в exists-фильтр. переделала -- все теперь нормально фильтрует.
вопрос решен. спасибо за помощь!

Сомнительно, чтобы не шло никаких запросов в БД: либо у Вас настроены фильтры в профайлере, либо у данного пользователя нет разрешения на профайлинг на уровне БД.

Однако я рада, что вопрос решен. Приятной работы!

"Alimova Anna" написал:Сомнительно, чтобы не шло никаких запросов в БД: либо у Вас настроены фильтры в профайлере, либо у данного пользователя нет разрешения на профайлинг на уровне БД.

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

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Доброго времени суток!
Задача состоит вот в чем. Есть древовидный реестр, который строится запросом с UNION. Нужно реализовать пользовательский фильтр для динамических групп. Стандартными методами это реализовать не удается, так как у родительских записей это поле всегда пустое, а у дочерних - заполнено. Соответственно, если положиться на галочку "Поле фильтрации" в Dataset'e, - получаем пустую гриду, так как дочерние хоть и фильтруются верно, родительские записи не одна не попадает в результат, так как мы по факту сравниваем ноль с параметром. Я так понимаю нужно воспользоваться пользовательским фильтром, но появляется проблема - так как WHERE есть и для родительской и для дочерней записи, то получаем в конечном итоге 2 фильтра с одинаковым названием в построителе фильтров. Как можно обойти это, и собственно где можно посмотреть правильную реализацию пользовательских фильтров, либо почитать мануал?

У меня такой же вопрос

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

Предлагаю вам мой вариант решения, описан от тут

Константин, Если Вам необходимо фильтровать именно все корневые записи, тогда имеет смысл реализовать фильтры рабочей области, пример можно посмотреть в разделе Проекты.

В случае, если необходимо отфильтровать запись с конкретным идентификатором-родителем, с этим проблем не возникнет.

Войдите или зарегистрируйтесь, чтобы комментировать
Публикация

Добрый день!

Как Вы наверное все знаете, на основной реестр можно накладывать фильтры, добавить которые можно в блоке пользовательского фильтра:

1

Существует возможность фильтрации основного реестра раздела по данным деталей. В окне фильтрации деталь отмечается "плюсиком", т.е. записью, которая содержит в себе подчиненные записи - поля детали таблицы.
Однако можно столкнутся с тем, что раскрыв такую запись мы не найдем нужного поля, по которому хотим произвести фильтрацию.
Так, к примеру, в разделе контакты нету возможности профильтровать записи по названию воздействия, с которым связан тот или иной контакт.
Однако, добавить данное поле все же можно. Для этого нужно создать свой собственный пользовательский фильтр через Террасофт Администратор.

Далее, приведу пример создания такого фильтра именно для настройки фильтрации контактов, по названию воздействия.
Для этого в сервис sq_Account в блок MarketingFilters добавьте новый пользовательский фильтр типа «Справочник», и заполните его следующим образом:
2

После этого, сохраните изменения и перезапустите клиентское приложение. Получим:
3

Вот и всё.
Приятной работы с Террасофт!

Поделиться

0 комментариев
Войдите или зарегистрируйтесь, чтобы комментировать