Подскажите пожалуйста, как отсортировать записи в детали по умолчанию? То есть если не выбрана сортировка ни по одной из выбранных колонок, то записи должны быть отсортированы по одному из полей?

В частности: версия 3.2., в разделе Документы, деталь Продукты, если нет сортировки ни по одной из видимых колонок, то записи продуктов будут расположены по моему в порядке их добавления в документ. А нужно их отсортировать по коду продукта, по полю Code.

В запрос sq_OfferingInDocument, который расположен в Documents - Details - Offerings, я добавил поле Code, и включил сортировку. Почему то не работает. Должно работать?

Нравится

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

Укажите свойство OrderType колонки Code соответствующего грида, но обратите внимание, что данный грид используется в нескольких разделах.

Можно следующим образом: попробуйте в обработчик события dlDataOnDatasetBeforeOpen окна детали продуктов (скрипт wnd_OfferingsDetailTreeAreaScript) вставить такой код:

function dlDataOnDatasetBeforeOpen(Dataset, DoOpen) {
	var IsOrdered = false;
	for (var i = 0; i < grdData.ActiveView.Count; i++) {
		if (grdData.ActiveView.Items(i).OrderType != 0) {
			IsOrdered = true;
			break;
		}
	}
	if (!IsOrdered) {
		Dataset.DataFields.ItemsByName('Code').OrderType = otAsc;
		Dataset.DataFields.ItemsByName('Code').OrderPosition = 1;
	}
}

Таким образом, если сортировки в реестре нет ни по одному из полей, автоматически включится сортировка по полю Code.

Спасибо! Все получилось! Решил сделать через OrderType, правда там не было этой колонки, я ее добавил, и теперь она конечно видна в гриде )))

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

Как многие знают, есть такое ограничение на использование CustomSQLColumn-а: датафилд, полученный по нему, нельзя фильтровать (как быстрым фильтром, так и фильтром из FilterBuilder-а), что значительно ограничивает нас при реализации сложных запросов с использованием функций и хранимых процедур. Но недавно случайно один из разработчиков (Дмитрий Мушенко - страна должна знать своих героев :)) обнаружил, что в случае, если завернуть CustomSQLColumn в subselect, то все будет нормально работать. Т.е. датасет, полученный по запросу вида

select
    ID as ID,
    Amount1 - Amount2 as Difference
from tbl_MyTable

где Amount1 - Amount2 - это CustomSQLColumn,
не будет фильтроваться по датафилду Difference

Но если видоизменить запрос на

select 
    ID as ID,
    (select  top 1
         m.Amount1 - m.Amount2 
     from tbl_MyTable m
     where m.ID = tbl_MyTable) as Difference

from tbl_MyTable

то все будет работать замечательно.

Прим.: Единственный неприятный момент, что удалось обнаружить, - эта фича не работает со строковыми полями. Т.е. если Вы в таком поле получаете дату, числовое значение или значение из справочника (GUID-ное значение), все будет фильтроваться нормально. Если же строку - фильтрация работать не будет.

Нравится

Поделиться

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

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

Есть еще несколько путей решения такой задачи:

  • чтобы обеспечить работу быстрого фильтра, можно создать в SelectQuery CustomSQLFilter с нужным условием и вручную применять его в обработчике событий OnQuickFilter соответствующего DataGrid - самый правильный и безотказный вариант, правда доступный только в более поздних версиях
  • можно в реальной таблице создать вычисляемое поле (для случаев, когда все данные для вычисления берутся из одной таблицы и когда такое позволяет СУБД - MS SQl Server точно позволяет, насчет других не уверен, но скорее всего у них тоже с этим не будет проблем), а затем добавить его в сервис таблицы без сохранения структуры (в принципе, такой вариант я бы посоветовал вместо первого для тех случаев, когда возникает реальная необходимость в оптимизации запроса)

>>чтобы обеспечить работу быстрого фильтра, можно создать в SelectQuery CustomSQLFilter с нужным условием и вручную применять его в обработчике событий OnQuickFilter соответствующего DataGrid - самый правильный и безотказный вариант, правда доступный только в более поздних версиях

Да, можно. Только кода больше нужно писать.

>>можно в реальной таблице создать вычисляемое поле

Только для случаев, когда данные находятся в одной таблице. К сожалению, такие случаи очень редки.

>>Можно просто использовать View:

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

Можно подробнее про OnQuickFilter?
Я создал фильтр, вызываю его в этом обработчике, но датасет не фильтруется (пустой).

OnQuickFilter - метод, который срабатывает, когда пользователь применяет быстрый фильтр в реестре (выбирает в контекстном меню "Быстрый фильтр" - на англ. "Quick Filter"). Т.е. он не срабатывает, когда Вы применяете любой произвольный фильтр на датасете.

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

К сожалению, в стандартном DataGrid нет возможности отключить сортировку грида опционально. Поэтому в случае, если необходимо реализовать подобную функциональность, то могу предложить альтернативное решение.
Как известно, при включении сортировки грида - датасет сперва закрывается, затем открывается уже с сортировкой. Следовательно, для того, чтобы отключить возможность сортировки необходимо просто "не дать" датасету закрыть себя (это происходит при нажатии на названии колонки).

Для этого, в событии датасета "OnDatasetBeforeClose" прописываем следующее:

function mds_rtsOnDatasetBeforeClose(Dataset, DoClose) {
    DoClose.Value = false;
}

Таким образом он просто не закроется. Но, когда это необходимо сделать (для того, чтобы очистить датасет и следовательно наполнить иными данными), то следует просто передать соответствующий параметр. К примеру:
....

//Здесь нужно дать датасету себя закрыть
Dataset.Attributes('AllowClose') = true;
Dataset.Close();
Dataset.Append();
.....
и метод "OnDatasetBeforeClose" будет выглядеть так:
function mds_rtsOnDatasetBeforeClose(Dataset, DoClose) {
    if (Dataset.Attributes('AllowClose')) {
        DoClose.Value = true;
        Dataset.Attributes('AllowClose') = null;
        return;
    }
    DoClose.Value = false;
}

Таким образом, датасет будет закрываться только при помощи пользователя (а не грида или дерева).

Желаю удачи!

С уважением,
Мельникова Екатерина

Нравится

Поделиться

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