Технические вопросы
Разработка

Перейти к группе записей

А каким образом можно было бы переходить не только к одной записи по ID, а к группе записей?
Например, из контактов "Перейти к невыполненным задачам по контакту"

Особенно интересно это было бы делать из "Итогов". Потому что одно дело - это видеть обобщенную информацию, а другое - это сразу ее расскрывать.

Нравится

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

Здравствуйте!

Для реализации данной функциональности Вам необходимо выполнить некоторые изменения в скрипте.

1. scr_BaseGridArea
a. Изменить функцию GotoReference:
[javascript]
function GotoReference(ActionMenuItem) {
var SelectedIDsArray = GetGridSelectedIDsArray();
GotoWorkspaceByActionMenuItem(ActionMenuItem, dlData.Dataset, SelectedIDsArray);
}
[/javascript]

// плюс создать функцию:

[javascript]
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;
}
[/javascript]
2. scr_WindowUtils
a. Изменить функцию GotoWorkspaceByActionMenuItem (добавить еще один параметр SelectedIDsArray):
[javascript]
function GotoWorkspaceByActionMenuItem(ActionMenuItem, Dataset, SelectedIDsArray) {
var ReferenceInfo = ActionMenuItem.Tag.split(',');
var WorkspaceWindowUSI = ReferenceInfo[0];
var DataFieldName = ReferenceInfo[1];
GotoWorkspaceByReferenceInfo(Dataset, DataFieldName,
WorkspaceWindowUSI, SelectedIDsArray);
}
[/javascript]
b. Изменить функцию GotoWorkspaceByReferenceInfo
[javascript]
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);
}
[/javascript]
3. scr_Main
a. Изменить функцию FilterByID
[javascript]
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);
}
[/javascript]

Terrasoft Support Team

Спасибо!

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

То есть, можно открыть "Задачи", выбрать фильтр "невыполненные задачи" и задать быстрый фильтр по нужному контакту. И это я хотел бы реализовать в виде простого перехода из раздела "Итоги"

Добрый день!
При создании подобного перехода из раздела "Итоги" могут возникнуть сложности в реализации, так как само создание меню для перехода "тянет" за собой сразу несколько доработок. Попробую по порядку:

  1. Раздел итоги создается динамически, в процессе работы приложения в зависимости от настроек. Таким образом, могут формироваться любые реестры, даже в которых не присутствует поле "Контакт". Значит, меню формировать нужно не для всех реестров, а для определенных. Соответственно, нужно хранить где-то признак формировать меню или нет. Вероятнее всего, делать надо в настройке итогов.
  2. Для формирования реестра служит окно wnd_UserReportView. В скрипте этого окна нужно сделать динамическую генерацию самого меню и его пунктов, а так же динамически связать функцию перехода с событием нажатия пункта меню.
  3. Реализовать саму функцию перехода.

Вот такой общий алгоритм реализации поставленной задачи.

Здравствуйте,

А возможно ли сделать переход от Контрагента в раздел Котакты, где записи отфильтрованы по Контрагенту, из контекстного меню которого делается переход?

делала что-то похожее, не очень хороший способ, может, кто-то лучше предложит
[javascript]
var MainWindow = Connector.Attributes('MainWindow');
MainWindow.ScriptControl.Run('ShowGroupWorkspace', '', 'wnd_DocumentsWorkspace',
null, true, new Array('AccountID', 'DocumentTypeID', 'IsTemplate'),
new Array(AccountID, WaterAnalisDocumentTypeID, false));
[/javascript]
для этого пришлось добавить в функцию ShowGroupWorkspace() еще два входящих параметра и в конце добавить условие
[javascript]
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);
}
}
if (IDDataFieldValue != null) {
System.BeginProcessing();
try {
FilterWorkspace(WorkspaceWindow, IDDataFieldValue)
}
finally {
System.EndProcessing();
}
} else
if (Assigned(FilterParamNames)&&Assigned(FilterParamValues)) {
FilterWorkspaceByParamSet(WorkspaceWindow, FilterParamNames, FilterParamValues);
}
}

[/javascript]
в случае, если поле, по которому накладывается фильтр, не ID, вызывается функция FilterWorkspaceByParamSet()
[javascript]
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);
}
[/javascript]
только, кажется, я предполагала фильтрацию по IDшникам и булевским полям

фильтровали документы по контрагенту?

в данном примере документы по контагенту + по типу документа + по логическому полю "Шаблон", чтобы перейти к контактам, отфильтрованным по контрагенту, в обработчике события нажатия пункта контекстного меню нужно вызвать ShowGroupWorkspace() с такими параметрами:
[javascript]
var MainWindow = Connector.Attributes('MainWindow');
MainWindow.ScriptControl.Run('ShowGroupWorkspace', '', 'wnd_ContactsWorkspace',
null, true, new Array('AccountID'),
new Array(AccountID));
[/javascript]

[javascript]
var MainWindow = Connector.Attributes('MainWindow');
MainWindow.ScriptControl.Run('ShowGroupWorkspace', '', 'wnd_DocumentsWorkspace',
null, true, new Array('AccountID', 'DocumentTypeID', 'IsTemplate'),
new Array(AccountID, WaterAnalisDocumentTypeID, false));
[/javascript]

а эту часть кода где необходимо написать?

ой, уже на все ответили))
спасибо!!!

а сам пункт меню находится в подпункте "Перейти к"? Если да, то как это реализовано? Насколько мне известно, этот список формируется автоматически, руками ничего не добавить(

список формируется автоматически, но он добавляет к пункту контекстного меню amiGoto подпункты, которые определяет из датасета, поэтому, если Вы добавите вручную подпункт, он не исчезнет, просто после него появятся новые
также можно создавать новый подпункт динамически
[javascript]
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');
}
[/javascript]

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

я тоже, наверное, немало времени тогда потратила
всегда пожалуйста :)

Здравствуйте! А каким образом можно осуществить подобный переход не из основного реестра, а из деталей? Я поступил так:

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

Хочется перейти из детали.

Здравствуйте.

scr_BaseTreeArea - это скрипт базового древовидного окна. Его менять нужно только если у Вас в деталь используется древовидный реестр.
По поводу перехода к множеству записей из детали, функционал остается тем же самым, только нужно переписать данную функцию:
[code]
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;
}

[/code]

Установите отладчик, и посмотрите заполняется ли массив выделенными на детали записями?

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