А каким образом можно было бы переходить не только к одной записи по ID, а к группе записей?
Например, из контактов "Перейти к невыполненным задачам по контакту"
Особенно интересно это было бы делать из "Итогов". Потому что одно дело - это видеть обобщенную информацию, а другое - это сразу ее расскрывать.
Нравится
Здравствуйте!
Для реализации данной функциональности Вам необходимо выполнить некоторые изменения в скрипте.
1. scr_BaseGridArea
a. Изменить функцию GotoReference:
function GotoReference(ActionMenuItem) { var SelectedIDsArray = GetGridSelectedIDsArray(); GotoWorkspaceByActionMenuItem(ActionMenuItem, dlData.Dataset, SelectedIDsArray); }
// плюс создать функцию:
function GetGridSelectedIDsArray() { if (!Assigned(grdData) && !Assigned(BaseGridArea.Grid)) { return null; } else { if (!Assigned(BaseGridArea.Grid)) { BaseGridArea.Grid = grdData; } } if (BaseGridArea.Grid.SelectedIDs.Count == 0) { return null; } var SelectedIDsArray = new Array(); for (var i = 0; i < BaseGridArea.Grid.SelectedIDs.Count; i++) { SelectedIDsArray.push(BaseGridArea.Grid.SelectedIDs.Items(i)); } return SelectedIDsArray; }
2. scr_WindowUtils
a. Изменить функцию GotoWorkspaceByActionMenuItem (добавить еще один параметр SelectedIDsArray):
function GotoWorkspaceByActionMenuItem(ActionMenuItem, Dataset, SelectedIDsArray) { var ReferenceInfo = ActionMenuItem.Tag.split(','); var WorkspaceWindowUSI = ReferenceInfo[0]; var DataFieldName = ReferenceInfo[1]; GotoWorkspaceByReferenceInfo(Dataset, DataFieldName, WorkspaceWindowUSI, SelectedIDsArray); }
b. Изменить функцию GotoWorkspaceByReferenceInfo
function GotoWorkspaceByReferenceInfo(Dataset, DataFieldName, WorkspaceWindowUSI, SelectedIDsArray) { if (IsDatasetEmpty(Dataset)){ var Message = "Запись не выделена"; ShowInformationDialog(Message); return; } var DataFieldValue; if (!Assigned(SelectedIDsArray)) { DataFieldValue = GetFieldValueFromDisabledField(Dataset, DataFieldName); if (!IsEmptyGUID(DataFieldValue)) { GotoWorkspace(WorkspaceWindowUSI, DataFieldValue); return; } } else { DataFieldValuesArray = new Array(); var FieldValue; Dataset.DisableEvents(); try { for (var i = 0; i < SelectedIDsArray.length; i++) { Dataset.Locate('ID', SelectedIDsArray[i]); FieldValue = GetFieldValueFromDisabledField(Dataset, DataFieldName); if (IsEmptyValue(FieldValue)) { continue; } var IsValueExists = false; for (var j = 0; j < DataFieldValuesArray.length; j++) { if (DataFieldValuesArray[j] == FieldValue) { IsValueExists = true; break; } } if (!IsValueExists) { DataFieldValuesArray.push(FieldValue); } } } finally { Dataset.EnableEvents(); } if (DataFieldValuesArray.length > 0) { GotoWorkspace(WorkspaceWindowUSI, DataFieldValuesArray); return; } } var DataField = Dataset.DataFields(DataFieldName); var Message = FormatStr("Поле %1 пусто или Вы не имеете прав для чтения", DataField.Caption); ShowInformationDialog(Message); }
3. scr_Main
a. Изменить функцию FilterByID
function FilterByID(WorkspaceWindow, IDDataFieldValue) { var FBControl = WorkspaceWindow.ComponentsByName('fbcFilters'); var Dataset = FBControl.DatasetLink.Dataset; FBControl.FiltersBuilder.ClearFilter(); var IDDataField = Dataset.DataFields.ItemsByName('ID'); var FirstIDValue; if (typeof(IDDataFieldValue) == 'object') { FirstIDValue = IDDataFieldValue[0]; for (var i = 0; i < IDDataFieldValue.length; i++) { var FBItem = FBControl.FiltersBuilder.RootItems.CreateItemByDataField( IDDataField); FBItem.Value = IDDataFieldValue[i]; FBItem.Operator = totEqual; FBItem.LogicalOperator = lotOr; FBControl.FiltersBuilder.RootItems.Add(FBItem); } } else { FirstIDValue = IDDataFieldValue; var FBItem = FBControl.FiltersBuilder.RootItems.CreateItemByDataField( IDDataField); FBItem.Value = IDDataFieldValue; FBItem.Operator = totEqual; FBControl.FiltersBuilder.RootItems.Add(FBItem); } EnableDatasetFilters(Dataset, false); FBControl.ApplyFilter(); FBControl.Refresh(); SetAttribute(WorkspaceWindow, IsInSingleRowModeAttrName, true); RefreshDataset(Dataset); Dataset.Locate('ID', FirstIDValue); SetAttribute(WorkspaceWindow, IsInSingleRowModeAttrName, false); }
Terrasoft Support Team
Спасибо!
Эффект интересный, но немного не тот, о котором я спрашивал.
В принципе, то, что я спрашивал - это небольшая автоматизация выбора динамического/статического фильтров и быстрого поиска.
То есть, можно открыть "Задачи", выбрать фильтр "невыполненные задачи" и задать быстрый фильтр по нужному контакту. И это я хотел бы реализовать в виде простого перехода из раздела "Итоги"
Добрый день!
При создании подобного перехода из раздела "Итоги" могут возникнуть сложности в реализации, так как само создание меню для перехода "тянет" за собой сразу несколько доработок. Попробую по порядку:
- Раздел итоги создается динамически, в процессе работы приложения в зависимости от настроек. Таким образом, могут формироваться любые реестры, даже в которых не присутствует поле "Контакт". Значит, меню формировать нужно не для всех реестров, а для определенных. Соответственно, нужно хранить где-то признак формировать меню или нет. Вероятнее всего, делать надо в настройке итогов.
- Для формирования реестра служит окно wnd_UserReportView. В скрипте этого окна нужно сделать динамическую генерацию самого меню и его пунктов, а так же динамически связать функцию перехода с событием нажатия пункта меню.
- Реализовать саму функцию перехода.
Вот такой общий алгоритм реализации поставленной задачи.
делала что-то похожее, не очень хороший способ, может, кто-то лучше предложит
var MainWindow = Connector.Attributes('MainWindow'); MainWindow.ScriptControl.Run('ShowGroupWorkspace', '', 'wnd_DocumentsWorkspace', null, true, new Array('AccountID', 'DocumentTypeID', 'IsTemplate'), new Array(AccountID, WaterAnalisDocumentTypeID, false));
для этого пришлось добавить в функцию ShowGroupWorkspace() еще два входящих параметра и в конце добавить условие
function ShowGroupWorkspace(GroupCode, WorkspaceUSI, IDDataFieldValue, AddHistory, FilterParamNames, FilterParamValues) { if (!GetIsWorkspaceAllowed(WorkspaceUSI)) { ShowWarningDialog("Текущий пользователь не имеет достаточно прав для просмотра данных"); SlipGoBack(); return; } if (!CheckX15ExcludedWorkspaces(WorkspaceUSI)) { return; } if ((WorkspaceUSI == 'wnd_OLAPWorkspace') && (!GetIsOLAPControlIstalled())) { ShowWarningDialog("OLAP компонент не установлен в системе"); var GroupActionMenuItem = GetCheckedActionMenuItem(amWorkspace); var ActionMenuItem = GetActionMenuItemByTag(GroupActionMenuItem, Main.PriorOldActionMenuItemTag); Main.OldActionMenuItemTag = Main.PriorOldActionMenuItemTag; ShowGroupWorkspace(GroupActionMenuItem.Tag, ActionMenuItem.Tag, null, true); return; } Main.WorkspaceUSI = WorkspaceUSI; var GroupItemValue = GetNewValue(); var WorkspaceItemValue = GetNewValue(); GetWorkspaceActionMenuItem(GroupCode, WorkspaceUSI, GroupItemValue, WorkspaceItemValue); var GroupActionMenuItem = GroupItemValue.Value; Main.GroupCode = GroupCode; var WorkspaceActionMenuItem = WorkspaceItemValue.Value; if ((!Assigned(GroupActionMenuItem)) || (!Assigned(WorkspaceActionMenuItem))) { throw FormatStr("Модуль%1 не найден", WorkspaceUSI); } WorkspaceActionMenuItem.IsChecked = true; var WorkspaceWindow = GetWorkspaceByUSI(WorkspaceUSI); if ((!Assigned(wndWorkspace.Window)) || (!wndWorkspace.Window.Equal(WorkspaceWindow))) { wndWorkspace.Window = WorkspaceWindow; if (WorkspaceUSI == 'wnd_DashboardView') { wndWorkspace.Window.Prepare(); } if (AddHistory && !Main.DoNotUpdateHistory) { AddWorkspacesHistory(GroupActionMenuItem.Tag, WorkspaceActionMenuItem.Tag); } } <strong>if (IDDataFieldValue != null) { System.BeginProcessing(); try { FilterWorkspace(WorkspaceWindow, IDDataFieldValue) } finally { System.EndProcessing(); } } else if (Assigned(FilterParamNames)&&Assigned(FilterParamValues)) { FilterWorkspaceByParamSet(WorkspaceWindow, FilterParamNames, FilterParamValues); } }</strong>
в случае, если поле, по которому накладывается фильтр, не ID, вызывается функция FilterWorkspaceByParamSet()
function FilterWorkspaceByParamSet(WorkspaceWindow, ParamNames, ParamValues) { var FBControl = WorkspaceWindow.ComponentsByName('fbcFilters'); var Dataset = FBControl.DatasetLink.Dataset; FBControl.FiltersBuilder.ClearFilter(); for (var i = 0; i < ParamNames.length; i++) { var IDDataField = Dataset.DataFields.ItemsByName(ParamNames[i]); var FBItem = FBControl.FiltersBuilder.RootItems.CreateItemByDataField( IDDataField); if (typeof(FBItem.Value) == 'boolean') { FBItem.Value = ParamValues[i]; } else if (typeof(FBItem.Value) == 'object') { FBItem.Value.Add(ParamValues[i]); FBItem.Operator = totEqual; } FBControl.FiltersBuilder.RootItems.Add(FBItem); } EnableDatasetFilters(Dataset, false); FBControl.ApplyFilter(); FBControl.Refresh(); SetAttribute(WorkspaceWindow, IsInSingleRowModeAttrName, true); RefreshDataset(Dataset); SetAttribute(WorkspaceWindow, IsInSingleRowModeAttrName, false); }
только, кажется, я предполагала фильтрацию по IDшникам и булевским полям
в данном примере документы по контагенту + по типу документа + по логическому полю "Шаблон", чтобы перейти к контактам, отфильтрованным по контрагенту, в обработчике события нажатия пункта контекстного меню нужно вызвать ShowGroupWorkspace() с такими параметрами:
var MainWindow = Connector.Attributes('MainWindow'); MainWindow.ScriptControl.Run('ShowGroupWorkspace', '', 'wnd_ContactsWorkspace', null, true, new Array('AccountID'), new Array(AccountID));
var MainWindow = Connector.Attributes('MainWindow'); MainWindow.ScriptControl.Run('ShowGroupWorkspace', '', 'wnd_DocumentsWorkspace', null, true, new Array('AccountID', 'DocumentTypeID', 'IsTemplate'), new Array(AccountID, WaterAnalisDocumentTypeID, false));
а эту часть кода где необходимо написать?
список формируется автоматически, но он добавляет к пункту контекстного меню amiGoto подпункты, которые определяет из датасета, поэтому, если Вы добавите вручную подпункт, он не исчезнет, просто после него появятся новые
также можно создавать новый подпункт динамически
function amGridOnPrepare(ActionMenu, Control) { Initialize(ActionMenu.ParentWindow); scr_BaseGridArea.amGridOnPrepare(ActionMenu, Control); if (!Assigned(Self.ComponentsByName('amiTest'))){ var ActionMenuItem = Self.CreateComponent('ActionMenuItem', 'amiTest'); ActionMenuItem.Caption = FormatStr("'%1'", 'Caption'); ActionMenuItem.Tag = 'wnd_AccountsWorkspace' + ',' + 'Contacts'; amiGoto.AddItem(ActionMenuItem); SetObjectEventDispatcher(amiGoto.ParentWindow, ActionMenuItem, ActionMenuItem.Name, 'OnExecute', 'amiTestOnExecute'); } } function amiTestOnExecute() { Log.Write(1, 'test'); }
я тоже, наверное, немало времени тогда потратила
всегда пожалуйста :)
Здравствуйте! А каким образом можно осуществить подобный переход не из основного реестра, а из деталей? Я поступил так:
в скрипте scr_BaseTreeArea создал функции, аналогичные предложенным Вами для scr_BaseGridArea, по идее обработчик должен уже анализировать, является ли выделенная область массивом, но этого не происходит. все остальные скрипты уже были ранее приведены к требуемому виду, и переход по группе записей из основного реестра - работает.
Хочется перейти из детали.
Здравствуйте.
scr_BaseTreeArea - это скрипт базового древовидного окна. Его менять нужно только если у Вас в деталь используется древовидный реестр.
По поводу перехода к множеству записей из детали, функционал остается тем же самым, только нужно переписать данную функцию:
function GetGridSelectedIDsArray() { if (!Assigned(grdData) && !Assigned(BaseGridArea.Grid)) { return null; } else { if (!Assigned(BaseGridArea.Grid)) { BaseGridArea.Grid = grdData; } } if (BaseGridArea.Grid.SelectedIDs.Count == 0) { return null; } var SelectedIDsArray = new Array(); for (var i = 0; i < BaseGridArea.Grid.SelectedIDs.Count; i++) { SelectedIDsArray.push(BaseGridArea.Grid.SelectedIDs.Items(i)); } return SelectedIDsArray; }
Установите отладчик, и посмотрите заполняется ли массив выделенными на детали записями?