Добрый день.
Подскажите пожалуйста как реализовать поиск по деталям?

А именно как реализовать выполнение подобного запроса:

SELECT  
acc.Id FROM [dbo].[Account] acc, [dbo].[AccountCommunication] comm
WHERE
comm.AccountId = acc.Id AND
comm.Number LIKE '%123456%'
GROUP BY(acc.id)

чтобы в реестре вывелись записи по заданному условию?

Сейчас сделал так:

var dataSource = Page.DataSource;
Select selectPhone = new Select(Page.UserConnection).Top(15)
        .Column("Account","Id")
        .From("Account")
        .Join(JoinType.Inner, "AccountCommunication")
                .On("Account", "Id").IsEqual("AccountCommunication", "AccountId")
                .Where("AccountCommunication", "Number").ConsistsWith(Column.Const(Page.PhoneSearchEdit.Value.ToString()))
                as Select;

var selectExecute = selectPhone.ExecuteReader(Page.UserConnection.EnsureDBConnection());
                                       
Page.TreeGrid.Clear();                                         
while (selectExecute.Read())
{
    Page.DataSource.LoadRow(new Guid(selectExecute[0].ToString()));            
}

Page.ThrowEvent("LoadRowsByFilter");
return true;

но мне кажется что так не верно.
Возникает две ошибки:
1. Без ограничения количества записей в селекте, возникает ошибка. Очень много вызовов DataSource.Load
2. Перестают обновляться детали.

Нравится

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

Здравствуйте, Илья!

Такая возможность заложена в базовую функциональность системы: можно вывести значения при помощи агрегирующего фильтра в блоке фильтрации:

1. Наведите мышью справа от ссылки "Добавить условие" и дождитесь появления маркера. Выберите Агрегирующий фильтр:

2. В списке выберите Средства связи Контрагента:

3. Выберите вариант Существует:

4. Укажите дополнительные фильтры, например, номер:

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

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

var dataSource = Page.DataSource;
var structure =  dataSource.CurrentStructure;
 
Select selectPhone = new Select(Page.UserConnection)
		.Column("Account","Id")
        .From("Account")
		.Join(JoinType.Inner, "AccountCommunication")
			.On("Account", "Id").IsEqual("AccountCommunication", "AccountId")
			.Where("AccountCommunication", "Number").ConsistsWith(Column.Const(Page.PhoneSearchEdit.Value.ToString()))
		as Select;
 
var selectExecute = selectPhone.ExecuteReader(Page.UserConnection.EnsureDBConnection());
 
var phoneFiltersName = "phoneFilters";
var phoneFilters = dataSource.FindFiltersGroupByName(phoneFiltersName);
if (phoneFilters != null) {
	structure.Filters.Remove(phoneFilters);
}
phoneFilters = structure.CreateFiltersGroup(phoneFiltersName, LogicalOperationStrict.Or);
 
while (selectExecute.Read())
{
phoneFilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, FilterComparisonType.Equal, "Id", new Guid(selectExecute[0].ToString())));
}
 
Page.ThrowEvent("LoadRowsByFilter");
 
Page.TreeGrid.Clear();						
dataSource.CurrentStructure.Filters.Add(phoneFilters);
dataSource.LoadRows();
 
return true;

Но к сожалению осталась одна проблема, при изменении выделенной записи не происходит обновление раздела детали.

Здравствуйте, Константин.

Попробуйте в конце скрипта добавить

Page.TreeGrid.RefreshData();

Проблема получила продолжение, при выполнение SQL запроса полученного из

Select selectPhone = new Select(Page.UserConnection)
		.Column("Account","Id")
        .From("Account")
		.Join(JoinType.Inner, "AccountCommunication")
			.On("Account", "Id").IsEqual("AccountCommunication", "AccountId")
		.Join(JoinType.Inner, "Contact")
			.On("Account", "Id").IsEqual("Contact", "AccountId")
		.Join(JoinType.Inner, "ContactCommunication")
			.On("Contact", "Id").IsEqual("ContactCommunication", "ContactId")
			.Where("ContactCommunication", "Number").ConsistsWith(Column.Const(Page.PhoneSearchEdit.Value.ToString()))
		as Select;
SELECT
	[Account].[Id]
FROM
	[dbo].[Account]
	INNER JOIN [dbo].[AccountCommunication] ON ([Account].[Id] = [AccountCommunication].[AccountId])
	INNER JOIN [dbo].[Contact] ON ([Account].[Id] = [Contact].[AccountId])
	INNER JOIN [dbo].[ContactCommunication] ON ([Contact].[Id] = [ContactCommunication].[ContactId])
WHERE
	[ContactCommunication].[Number] LIKE N'%' + N'456' + N'%'

напрямую из базы, получаем 2530 записей (при Group by около 700)
но если выполнить это же в коде

var selectExecute = selectPhone.ExecuteReader(Page.UserConnection.EnsureDBConnection());

получаем 3 (три) одинаковых записи.
Вопрос: в чем может быть проблема?

Вопрос 2: раздел Контрагенты. создаю новую страницу реестра контрагентов 2, основанную на реестре контрагентов. добавляю новую вкладку и вставляю ее туда. Опубликовываю. При переходе на эту вкладку2 панель детали перестают обновляться при переходе по контрагентам.

С запросом разобрался. И остался вопрос с деталями. Что же нужно сделать чтобы событие происходило?

Здравствуйте, Илья!

покажите, пожалуйста, скриншот настроек детали в рабочих местах.

Alimova Anna

Сделал по совету Maxim Gritsenko

Большое спасибо. Сделал через рабочие места и все заработало. Но почему не работает через конфигурацию? Непонятно (.

Здравствуйте, Илья!

Ответ на Ваш вопрос был дан тут: http://www.community.terrasoft.ru/forum/topic/9530#comment-40492

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

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

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

Добрый день.
Подскажите пожалуйста как реализовать поиск по деталям?

А именно как реализовать выполнение подобного запроса:

SELECT  
acc.Id FROM [dbo].[Account] acc, [dbo].[AccountCommunication] comm
WHERE
comm.AccountId = acc.Id AND
comm.Number LIKE '%123456%'
GROUP BY(acc.id)

чтобы в реестре вывелись записи по заданному условию?

Сейчас сделал так:

var dataSource = Page.DataSource;
Select selectPhone = new Select(Page.UserConnection).Top(15)
        .Column("Account","Id")
        .From("Account")
        .Join(JoinType.Inner, "AccountCommunication")
                .On("Account", "Id").IsEqual("AccountCommunication", "AccountId")
                .Where("AccountCommunication", "Number").ConsistsWith(Column.Const(Page.PhoneSearchEdit.Value.ToString()))
                as Select;

var selectExecute = selectPhone.ExecuteReader(Page.UserConnection.EnsureDBConnection());
                                       
Page.TreeGrid.Clear();                                         
while (selectExecute.Read())
{
    Page.DataSource.LoadRow(new Guid(selectExecute[0].ToString()));            
}

Page.ThrowEvent("LoadRowsByFilter");
return true;

но мне кажется что так не верно.
Возникает две ошибки:
1. Без ограничения количества записей в селекте, возникает ошибка. Очень много вызовов DataSource.Load
2. Перестают обновляться детали.

Нравится

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

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

Наталия. в последней итерации это выглядит так.
в реестре контрагентов добавлено тесктовое поле и кнопка по нажатию которой происходит поиск.
и ссответственно код:

var dataSource = Page.DataSource;
var structure =  dataSource.CurrentStructure;
 
Select selectPhone = new Select(Page.UserConnection)
		.Column("Account","Id")
        .From("Account")
		.Join(JoinType.Inner, "AccountCommunication")
			.On("Account", "Id").IsEqual("AccountCommunication", "AccountId")
			.Where("AccountCommunication", "SearchNumber").ConsistsWith(Column.Const(Page.edtPhoneSearch.Value.ToString()))
 
		.Union(new Select(Page.UserConnection)
					.Column("Account","Id")
       				.From("Account")
					.Join(JoinType.Inner, "Contact")
						.On("Account", "Id").IsEqual("Contact", "AccountId")
					.Join(JoinType.Inner, "ContactCommunication")
						.On("Contact", "Id").IsEqual("ContactCommunication", "ContactId")
					.Where("ContactCommunication", "SearchNumber").ConsistsWith(Column.Const(Page.edtPhoneSearch.Value.ToString()))
					as Select)
		as Select;
 
var selectExecute = selectPhone.ExecuteReader(Page.UserConnection.EnsureDBConnection());
 
var phoneFiltersName = "phoneFilters";
var phoneFilters = dataSource.FindFiltersGroupByName(phoneFiltersName);
if (phoneFilters != null) {
	structure.Filters.Remove(phoneFilters);
}
phoneFilters = structure.CreateFiltersGroup(phoneFiltersName, LogicalOperationStrict.Or);
 
var i=0;
while (selectExecute.Read())
{
i++;
var guidFromSelect = selectExecute[0].ToString();
phoneFilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, FilterComparisonType.Equal, "Id", new Guid(guidFromSelect)));
}
 
Page.ThrowEvent("LoadRowsByFilter");
 
Page.TreeGrid.Clear();		
if (i>0)
{
  dataSource.CurrentStructure.Filters.Add(phoneFilters);
  dataSource.LoadRows();
  Page.TreeGrid.RefreshData();
}
 
return true;

Осталось доделать проверку на пустые входные условия, преобразование входных условий (оставить только цифры) и очистку фильтра

сильно......поизучаю на досуге......thnx что поделились....

Итого. Последняя версия на текущий момент:

var dataSource = Page.DataSource;
var structure = dataSource.CurrentStructure;
Terrasoft.UI.WebControls.Controls.DataSourceFilterCollection filters = null;
filters = dataSource.FindFiltersGroupByName("CustomFilters");
if (filters != null) {
	structure.Filters.Remove(filters);
}
 
var address = Page.edtAddressSearch.Value.ToString();
address = address.Trim();
 
var phone = Page.edtPhoneSearch.Value.ToString();
phone = phone.Trim();
 
var ret = false;
 
if (address == String.Empty)
{
 Page.ClearAddressSearch.Hide();
}
else
{
 Page.ClearAddressSearch.Show();
}
 
if (phone == String.Empty)
{
 Page.ClearPhoneSearch.Hide();
}
else
{
 Page.ClearPhoneSearch.Show();
}
 
if ((address == String.Empty)&&(phone == String.Empty))
{
	return true;
}
 
 
string searchColumn = "Number";
var compareType = FilterComparisonType.NotEqual;
var compareStringPhone = "Телефон";
var compareStringFax = "Факс";
var filterValues = new object[] { 
"0DA6A26B-D7BC-DF11-B00F-001D60E938C6", //Домашний телефон
"3DDDB3CC-53EE-49C4-A71F-E9E257F59E49", //Рабочий телефон
"D4A2DC80-30CA-DF11-9B2A-001D60E938C6", //Мобильный телефон
"2B387201-67CC-DF11-9B2A-001D60E938C6", //Дополнительный телефон
"6A3FB10C-67CC-DF11-9B2A-001D60E938C6", //Телефон
"9A7AB41B-67CC-DF11-9B2A-001D60E938C6" //Факс
};
if (Page.cbCommunication.Text == "Телефон")
{
	compareType = FilterComparisonType.Equal;
	searchColumn = "SearchNumber";
	StringBuilder sb = new StringBuilder();
	foreach (var ch in phone)
	{
  		if (Char.IsNumber(ch))
  		{
    		sb.Append(ch);
  		}
	}
	phone = sb.ToString();
}
 
 
 
 
 
filters = structure.CreateFiltersGroup("CustomFilters", LogicalOperationStrict.And);
 
if (!string.IsNullOrEmpty(address)) {
	var addressfilters = structure.CreateFiltersGroup("CustomAddressFilters", LogicalOperationStrict.Or);
	addressfilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, 
		FilterComparisonType.Contain, "[AccountAddressCLADR:Account].AddressString", 
		address));
	addressfilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, 
		FilterComparisonType.Contain, "[Contact:Account].[ContactAddressCLADR:Contact].AddressString", 
		address));
	filters.Add(addressfilters);
}
 
if (!string.IsNullOrEmpty(phone)) {
	var phonefilters = structure.CreateFiltersGroup("CustomPhoneFilters", LogicalOperationStrict.Or);
 
	var accountCommunicationtypefilters = structure.CreateFiltersGroup("ContactCommunicationTypeFilters", LogicalOperationStrict.And);
	accountCommunicationtypefilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, 
		FilterComparisonType.Contain, "[AccountCommunication:Account]." + searchColumn,//SearchNumber", 
		phone));
	accountCommunicationtypefilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, 
		compareType, "[AccountCommunication:Account].[CommunicationType:Id:CommunicationType].Id", 
		filterValues));
	phonefilters.Add(accountCommunicationtypefilters);
 
	var contactCommunicationtypefilters = structure.CreateFiltersGroup("ContactCommunicationTypeFilters", LogicalOperationStrict.And);
	contactCommunicationtypefilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, 
		FilterComparisonType.Contain, "[Contact:Account].[ContactCommunication:Contact]." + searchColumn,//SearchNumber", 
		phone));
	contactCommunicationtypefilters.Add(structure.CreateFilterWithParameters(dataSource.Schema, 
		compareType, "[Contact:Account].[ContactCommunication:Contact].[CommunicationType:Id:CommunicationType].Id", 
		filterValues));
 
	phonefilters.Add(contactCommunicationtypefilters);
 
	filters.Add(phonefilters);
}
 
 
Page.TreeGrid.Clear();		
if (filters.Count > 0) {
	structure.Filters.Add(filters);
	dataSource.LoadRows();
	Page.TreeGrid.RefreshData();		
}
 
 
return true;
Показать все комментарии