Публикация

Премудрости сортировки

Недавно, не побоюсь этого слова, столкнулся с пожеланием клиента жестко сортировать записи в гриде по двум полям дат - в первую очередь по одной (приезд), потом по другой (отъезд). Персонал долго и плотно сидел на экселе, так что желание было вполне понятно.
Сначала показалось, что никаких проблем с этим не может возникнуть, но как выяснилось, без тех поддержки обойтись не удалось :confused:.
Первая мысль была - взять да отсортировать датасет в настройках SelectQuery, благо там есть прекрасная возможность настройки сортировки хоть по всем полям сразу. Что и было сделано.

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

Однако :exclaim:, вопреки ожиданиям... все осталось еще более удивительно так же, как и было :smile:
Убив довольно много времени на вариации настроек и чесание затылка, я решил наконец посмотреть что-же там в запросе, собственно, запрашивается...

Как и следовало ожидать никаких мной настроенных сортировок там не было. Профайлер показывал следующее:

exec sp_executesql N'SELECT TOP 40
/*№1*/     [tbl_Opportunity].[ID] AS [ID],
                [tbl_Opportunity].[CustomerID] AS [CustomerID],
                [tbl_Account].[Name] AS [CustomerName],
                [tbl_Opportunity].[Probability] AS [Probability],
                CAST(CONVERT(VARCHAR(8), [tbl_Opportunity].[ActualCloseDate], 112) AS DATETIME) AS [ActualCloseDate],
                [tbl_Opportunity].[TypeID] AS [TypeID],
                [tbl_Opportunity].[StatusID] AS [StatusID],
                [tbl_Opportunity].[CreatedOn] AS [CreatedOn],
                [tbl_Opportunity].[CreatedByID] AS [CreatedByID],
                [CreatedBy].[Name] AS [CreatedByName],
                [tbl_Opportunity].[WorkflowItemID] AS [WorkflowItemID],
                [tbl_OpportunityStatus].[IsFinish] AS [IsFinish],
                [tbl_Opportunity].[Revenue] AS [Revenue],
/*№14*/   CAST(CONVERT(VARCHAR(8), [tbl_Opportunity].[DateArrival], 112) AS DATETIME) AS [DateArrival],
                CAST(CONVERT(VARCHAR(8), [tbl_Opportunity].[DateDeparture], 112) AS DATETIME) AS [DateDeparture],
                [tbl_Opportunity].[MemberQuantity] AS [MemberQuantity],
                [tbl_Opportunity].[PlaceArrival] AS [PlaceArrival],
                [tbl_Opportunity].[PlaceDeparture] AS [PlaceDeparture],
                [tbl_Opportunity].[WaterType] AS [WaterType],
                [tbl_Opportunity].[BusType] AS [BusType],
                [tbl_Opportunity].[Additionally] AS [Additionally],
                [tbl_Opportunity].[TourGuidesFIO] AS [TourGuidesFIO],
                [tbl_Opportunity].[TourHotelReserves] AS [TourHotelReserves],
                [tbl_Opportunity].[TourCreditSum] AS [TourCreditSum],
                [tbl_Opportunity].[Profit] AS [Profit]
FROM
                [dbo].[tbl_Opportunity] AS [tbl_Opportunity]
LEFT OUTER JOIN
                [dbo].[tbl_Account] AS [tbl_Account] ON [tbl_Account].[ID] = [tbl_Opportunity].[CustomerID]
LEFT OUTER JOIN
                [dbo].[tbl_OpportunityStatus] AS [tbl_OpportunityStatus] ON [tbl_OpportunityStatus].[ID] = [tbl_Opportunity].[StatusID]
LEFT OUTER JOIN
                [dbo].[tbl_Contact] AS [CreatedBy] ON [CreatedBy].[ID] = [tbl_Opportunity].[CreatedByID]
WHERE(((([tbl_Opportunity].[DateArrival] >= @P1 OR
                [tbl_Opportunity].[DateDeparture] >= @P2) AND
                ([tbl_Opportunity].[DateArrival] @P3 OR
                [tbl_Opportunity].[DateDeparture] @P4))))
ORDER BY
                14 ASC,
                1 ASC'
,N'@P1 datetime2(7),@P2 datetime2(7),@P3 datetime2(7),@P4 datetime2(7)','2013-04-01 00:00:00','2013-04-01 00:00:00','2013-05-01 00:00:00','2013-05-01 00:00:00'

Вот это меня убило: 1 ASC
Вторая сортировка - это сортировка пользователя по колонке (кликом)
Никаких настроенных сортировок и в помине...

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

Цитата:
Сортировка реестра работает следующим образом:
по умолчанию устанавливается сортировка по полю ID. Если пользователь применил сортировку по колонке реестра - к сортировке по ID добавляется сортировка по данной колонке.
Установленная для колонок сортировка в запросе при открытии датасета реестра снимается и не учитывается.
Чтобы накладывать сортировку на нужные Вам колонки, необходимо:
1. Перед открытием датасета реестра программно устанавливать сортировку.
2. Скриптом сортировка устанавливается таким образом:

Dataset.DataFields.ItemsByName(DataFieldName).OrderType = otAsc;
Dataset.DataFields.ItemsByName(DataFieldName).OrderPosition = 1;

Где константа otAsc – определяет сортировку по возрастанию, а otDesc – сортировку по убыванию.

Сделал, как написано - и ура, оно заработало, но с одним "но" - возможность сортировать по столбцам (кликом) теперь какая-то странная такая возможность:
при открытии

ORDER BY
        18 ASC,
        19 ASC,
        1 ASC'

при сортировке по полю №27

ORDER BY
        18 ASC,
        19 ASC,
        27 ASC,
        1 ASC

при сортировке по полю №4

ORDER BY
        18 ASC,
        4 ASC,
        19 ASC,
        1 ASC'

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

ПС. Если создавать датасет так:

var Dataset = SelectQuery.Open();

то сортировка точно работает, скорее всего сбрасывание происходит где-то на связке грида с датасетом

Нравится

Поделиться

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

Добрый день, Дмитрий.

1. OrderPosition - 0 = не сортировать. Выставляйте позиции с 1-цы в настройках грида и будет сортировать.
2. Уточним.

Новости?:smile:

"Maxim Gritsenko" написал:
1. OrderPosition - 0 = не сортировать. Выставляйте позиции с 1-цы в настройках грида и будет сортировать.

---речь о 3.4.0.164---

Сортировать будет, но есть нюансы:
- если у DataGrid установлено CanChangeSort - true, пользователь может поменять сортировку - и она такой и останется (в профайлдата)
- если у DataGrid установлено CanChangeSort - false и очищены настройки пользователя, пользователь не может поменять сортировку, но и она не работает)
- если у DataGrid установлено CanChangeSort - false и НЕ очищены настройки пользователя, пользователь сортировку менять не может, а сама сортировка остается такой, какой была в последний раз.
Кроме того, CanChangeSort относится сразу ко всем представлениям (DataGridView), что не очень удобно.

ПС. Я наверно, опять не прочитал мануал, но оказывается можно сортировать по нескольким\многим колонкам - через Shift. В нашем случае, правда, это не выход - почему-то считается, что не надо оставлять это на пользователя (т.к. настройки гридов сохраняются в настройках пользователя, и, поменяв, он может не вспомнить, как вернуть назад)

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