При обновлении, добавлении, удалении продукта в счете надетали, необходимо обновить текущую счет в основном гриде. Делаю через OnNotify? обновляю весь грид. Если счет не на первой странице, то обновленный грид меняет страницу на первую и счет пропадает из поля видимости. Как сделать так, чтобы счет оставался выделенным после обновления грида или как обновлять только эту запись, но опять же чтобы она никуда не пропадала?
Вот такой вот вопрос возник. Есть форма (1), на ней контейнер Page.RightCategoryPageContainer
В контейнере форма (2) с гридом под названием TreeGrid.
Как бы обратиться к этому гриду формы 2 из скриптов основной формы 1?
Через Page.RightCategoryPageContainer.PageInstance обращаемся к форме 2? А дальше?
Задача - посмотреть, например, есть ли в этом гриде выбранная запись TreeGrid.SelectedNodes.Count
а что использовать в качестве Page? у меня только контейнер Page.RightCategoryPageContainer в котором лежит этот Page
значит задача несколько уже - нужен Page лежащий в контейнере, потом от него методом FindPageControlByName возьмем грид...
К идее http://www.community.terrasoft.ru/ideas/9586 А вот вам и решение
Не уверен, что не вызовет где-нибудь конфликта, но пока полет нормальный
Модифицировал scr_BaseGridArea.
Обращаю внимание, что это затронет только гриды на базе BaseGridArea.
1. Добавляем функции в scr_BaseGridArea
function UpdateGridForIDFields(Window){ if(!Connector.CurrentUser.IsAdmin)return;
var Grid = GetGrid(Window); if(Assigned(Grid)){ var Count = Grid.Count; for(var i =0; i Count; i++){ var GridView = Grid.Items(i); var ComponentName ='col'+'ID'+ GridView.Name; if(Assigned(Window.ComponentsByName(ComponentName)))return var DataGridColumn = Window.CreateComponent('DataGridColumn', ComponentName);
DataGridColumn.DataFieldName='ID';
DataGridColumn.IsVisible=false;
GridView.Add(DataGridColumn); } } }
function GetGrid(Window){ var Count = Window.ComponentCount; for(var i =0; i Count; i++){ var Component = Window.Components(i); if((Component.TypeCode=='DataGrid')||(Component.TypeCode=='DataTreeGrid')){ return Component; } } returnnull; }
2. Добавляем вызов UpdateGridForIDFields на OnPrepare
function wnd_BaseGridAreaOnPrepare(Window){
InitializeGridArea(Window, BaseGridArea, dlData);
InitializeGridAreaHotKeyList(Window);
UpdateGridForIDFields(Window);// test }
Справочники используют свое окно (где грид пересоздается). Чтобы это сработало и с ними, надо в wnd_DictionaryGridAreaScript в функцию добавить UpdateGridForIDFields(Window):
function wnd_DictionaryGridAreaOnPrepare(Window){
wnd_BaseGridAreaOnPrepare(Window);
Initialize(Window);
UpdateGridForIDFields(Window);/* 3.4.0 if (!DictionaryGridArea.ExternalOpening) {
BaseGridArea.GridDataset.Open();
}
*/}
если код функции у вас не в scr_BaseGridArea - не забудьте подключить
Недавно, не побоюсь этого слова, столкнулся с пожеланием клиента жестко сортировать записи в гриде по двум полям дат - в первую очередь по одной (приезд), потом по другой (отъезд). Персонал долго и плотно сидел на экселе, так что желание было вполне понятно. Сначала показалось, что никаких проблем с этим не может возникнуть, но как выяснилось, без тех поддержки обойтись не удалось .
Первая мысль была - взять да отсортировать датасет в настройках SelectQuery, благо там есть прекрасная возможность настройки сортировки хоть по всем полям сразу. Что и было сделано.
Однако, результата это не дало - все осталось удивительно так же, как и было
Безуспешно пошаманив над запросом, я переключился на настройки грида.
Однако , вопреки ожиданиям... все осталось еще более удивительно так же, как и было
Убив довольно много времени на вариации настроек и чесание затылка, я решил наконец посмотреть что-же там в запросе, собственно, запрашивается...
Как и следовало ожидать никаких мной настроенных сортировок там не было. Профайлер показывал следующее:
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
Вторая сортировка - это сортировка пользователя по колонке (кликом)
Никаких настроенных сортировок и в помине...
На всякий случай просмотрев разные варианты профайлером, я начал сомневаться, что занимаю свое место... и написал-таки в техподдержку.
Ответ немного удивил, но было уже не важно
Цитата:
Сортировка реестра работает следующим образом:
по умолчанию устанавливается сортировка по полю ID. Если пользователь применил сортировку по колонке реестра - к сортировке по ID добавляется сортировка по данной колонке.
Установленная для колонок сортировка в запросе при открытии датасета реестра снимается и не учитывается.
Чтобы накладывать сортировку на нужные Вам колонки, необходимо:
1. Перед открытием датасета реестра программно устанавливать сортировку.
2. Скриптом сортировка устанавливается таким образом:
Где константа otAsc – определяет сортировку по возрастанию, а otDesc – сортировку по убыванию.
Сделал, как написано - и ура, оно заработало, но с одним "но" - возможность сортировать по столбцам (кликом) теперь какая-то странная такая возможность:
при открытии
ORDERBY 18ASC, 19ASC, 1ASC'
при сортировке по полю №27
ORDERBY 18ASC, 19ASC, 27ASC, 1ASC
при сортировке по полю №4
ORDERBY 18ASC, 4ASC, 19ASC, 1ASC'
Я тогда не стал дальше разбираться, т.к. и так много времени на это потратил, поэтому спрошу здесь:
- работают ли настройки сортировки в сервисе грида и, если да, то как их использовать?
- зачем-зачем-зачем сортировка в датасете сбрасывается на сортировку по ID?
ПС. Если создавать датасет так:
var Dataset = SelectQuery.Open();
то сортировка точно работает, скорее всего сбрасывание происходит где-то на связке грида с датасетом
"Maxim Gritsenko" написал:
1. OrderPosition - 0 = не сортировать. Выставляйте позиции с 1-цы в настройках грида и будет сортировать.
---речь о 3.4.0.164---
Сортировать будет, но есть нюансы:
- если у DataGrid установлено CanChangeSort - true, пользователь может поменять сортировку - и она такой и останется (в профайлдата)
- если у DataGrid установлено CanChangeSort - false и очищены настройки пользователя, пользователь не может поменять сортировку, но и она не работает)
- если у DataGrid установлено CanChangeSort - false и НЕ очищены настройки пользователя, пользователь сортировку менять не может, а сама сортировка остается такой, какой была в последний раз.
Кроме того, CanChangeSort относится сразу ко всем представлениям (DataGridView), что не очень удобно.
ПС. Я наверно, опять не прочитал мануал, но оказывается можно сортировать по нескольким\многим колонкам - через Shift. В нашем случае, правда, это не выход - почему-то считается, что не надо оставлять это на пользователя (т.к. настройки гридов сохраняются в настройках пользователя, и, поменяв, он может не вспомнить, как вернуть назад)
Не подскажете ли решение одной проблемы – как определить положение колонки грида? Смотрел ее свойства – свойства Left нет. Есть ширина, но OrderPosition 0 у всех (может оно где-то на последнем этапе появляется). Если бы можно было пройтись по колонкам от первой до интересующей, то можно было бы вычислить положение. Как определить координаты элементов?
Добрый день.
Настройка положения колонок "вытаскивается" из закешированного содержимого. Базовые функции. работающие с кешем представлены в Common\Library\scr_WindowUtils: WinCache_Get, WinCache_CheckExtent() и т.д. Примеры их использования можно найти в конфигурации.
Если окно еще ни разу не открывалось - ядро обращается непосредственно к XML содержимому сервиса окна, и по мере получения Item'ов формирует обект окна. При необходимости уточним у разработчиков, учитывается ли OrderPosition, и реализуема ли Ваша задача. Уточните также, в свою очередь, какие бинарные файлы используете Вы (их версию).
var j = 0;
var ActiveView = DataGrid.ActiveView;
for (var i = 0; i < DataGrid.ActiveView.Count; i++) {
var DataField = ActiveView.Items(i);
if (!DataField.IsEnabled) {
continue;
}
//Это поле, DataField стоит под номером j. Дальше что хотите, то и делаете
j++;
}
Даже если кто-то испортил порядок вручную, то запустив эту функцию еще раз мы все-равно определим положение
Спасибо, работает. Не поскажете еще как программно менять порядок следования элементов внутри фреймгруп. Например внутри FrameGroup5 находятся (fgOffering1, fgOffering2, fgOffering3, fgOffering4) Хотелось бы изменить порядок следования - (fgOffering4, fgOffering2, fgOffering1, fgOffering3)
Проблема в следующем, создал вычисляемое поле в датасете С типом Дробное число с точностью 4 знака после запятой(см.рис)
, в обработчик OnDatasetCalcFields поместил скрипт:
function ds_OfferingInMovementOnDatasetCalcFields(Dataset){ //TODO Сумма по цене реализации var SaleSumma = Dataset('Quantity')*Dataset('SalePrice');
Dataset('CalcSaleSumma')= parseFloat(SaleSumma.toFixed(4)); //Number(SaleSumma.toFixed(4));
Поля из запроса отображаются с 4-я знаками после запятой с дополнением незначащими нулями до 4-х знаков, вычисляемое поле обрезается до фактической точности, хотелось бы сделать "безобразно, но единообразно"(с) :-)
Руслан, насколько я понимаю, Вы используете версию 3.3.0. Вычисляемые поля в ней действительно работают так, как Вы описали: незначащие нули отбрасываются. Данная ситуация исправлена в более поздних версиях (проверил на 3.3.2) - достаточно в коде написать:
function ds_OfferingInMovementOnDatasetCalcFields(Dataset){//TODO Сумма по цене реализации
Dataset('CalcSaleSumma')= Dataset('Quantity')*Dataset('SalePrice');
В Вашей версии можно использовать обходной путь. Поскольку вычисляемые поля обычно используются только для отображения, попробуйте заменить тип поля в датасете на строковый, а в коде оставить:
function ds_OfferingInMovementOnDatasetCalcFields(Dataset){//TODO Сумма по цене реализации
var SaleSumma = Dataset('Quantity')*Dataset('SalePrice');
Dataset('CalcSaleSumma')= SaleSumma.toFixed(4);//Number(SaleSumma.toFixed(4));
Ну, если критично отображение запятой, то можно выполнить ещё и replace:
function ds_OfferingInMovementOnDatasetCalcFields(Dataset){//TODO Сумма по цене реализации
var SaleSumma = Dataset('Quantity')*Dataset('SalePrice');
Dataset('CalcSaleSumma')= SaleSumma.toFixed(4).replace(/\./g, ',');//Number(SaleSumma.toFixed(4));
Как данное окно называется в Администраторе? Дело в том, что в этот грид хочу добавить еще одно поле "Номер объекта" (для поиска), но не знаю названия.
Terrasoft Real Estate 3.2.0.43
Это стандартное окно выбора. Чтобы добавить в данное окно поле, Вам необходимо найти датасет сущности "Объект" и установить для нужного поля опцию "Поле для отображения".
Тахир, посмотрела, "Объекты" - это ds_Opportunity, т.е. Вам для нужного поля необходимо установить опцию:
Поле для отображения - если хотите видеть в реестре колонку.
Поле для поиска - выполнять поиск по данному полю в окне выбора.
Нередко клиенты обращаются с вопросом:"Каким образом определить кооординаты ячейки в гриде". Предоставлю решение, чтобы Вы не тратили ценное время на поиски этого в SDK.
Как известно, координаты состоят из двух параметров: номера колонки и номера строки.
Для того, чтобы определить номер строки, можно воспользоваться:
DatasetLink.Dataset.PageRecordCount
Для того, чтобы определить номер колонки, можно воспользоваться
Если Вы успели заметить, в версии приложения Terrasoft CRM 3.3 появилось новое свойство грида CheckBoxDataFieldName. Наверняка, пользователю, плотно столкнувшемуся с разработкой дополнительных функциональностей, не является интуитивно понятным значение этого свойства. Итак, позвольте поясню.
Это свойство определяет название булевского поля из датасета для заполнения галочек, которые отображаются слева в начале реестра. Если свойство пустое галочки не отображаются, иначе слева в гриде отображаются синие квадратики, а наличие галочки определяется значением поля, название которого указано в этом свойстве.