Добрый день!

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

Нравится

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

При открытии по кнопке или двойному клику по строке вызывается функция EditGridAreaData в scr_BaseGridAreaUtils. Если по ссылке, то DoLookupColumnClick в scr_WindowUtils, а из неё функция ShowDatasetEditWindow.

Далее в обоих случаях вызывается непосредственно функция показа карточки ShowEditWindowEx с одним из параметров Attributes, где хранятся атрибуты окна. Можно модифицировать вышеупомянутые функции, чтобы в атрибуты добавлялся свой, разный для открытия из реестра или по ссылке. А в карточке при открытии проверять его значение.

При изменении функций стоит учесть, что они используются во всех разделах, и не поломать существующую логику.

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

Александр, спасибо за подсказку. Немного проанализировав код я нашел у окна, вызываемого по ссылке, атрибут LookupColumnClick, который я и буду использовать.

Действительно, спасибо за уточнение, не заметил присвоение атрибута. Но ход мысли авторов угадал...

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

Пытаюсь действовать по этому блогу
https://community.terrasoft.ru/blogs/9079
Но почти на первом же шаге ошибка. Когда вставляем первый скрипт

var defValuesId = Guid.NewGuid();
var defValues = new Dictionary string, object>();
defValues.Add("Contact", Page.ContactEdit.Value.ToString());
defValues.Add("Account", Page.AccountEdit.Value.ToString());
defValues.Add("Title", Page.TitleEdit.Value.ToString());
var IncidentId = Guid.NewGuid();

UserConnection.UserContext.Add(defValuesId.ToString(), defValues);
var parameters =  
      new Dictionarystring, string> {
            {"createWithUId", IncidentId.ToString()},
                        {"entitySchemaUId", "C449D832-A4CC-4B01-B9D5-8A12C42A9F89"},
                        {"defValuesId", defValuesId.ToString()}
      };
OpenTaskEditPage.OpenerInstanceId = InstanceUId;
OpenTaskEditPage.UseCurrentActivePage = true;
OpenTaskEditPage.PageUId = new Guid("F2BF397B-8FA3-48BA-B691-57360871967A");
OpenTaskEditPage.PageParameters = parameters ;
OpenTaskEditPage.CloseMessage = "IncidentEditPageClosed";

Выдает ошибки:

И во-вторых, где взять ид, которые есть в скрипте
"entitySchemaUId", "C449D832-A4CC-4B01-B9D5-8A12C42A9F89"}
OpenTaskEditPage.PageUId = new Guid("F2BF397B-8FA3-48BA-B691-57360871967A");

Нравится

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

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

По поводу ошибки "Имя OpenTaskEditPage отсутсвует в текущем контексте", в блоге указано (пункт 3), что после создания действия процесса "Открыть страницу", ему следует присвоить наименование. Вы либо не добавили UserTask, либо не так назвали.
А по поводу "UserContext" - какая у Вас версия, не 5.2 случаем?

PS:
ID в принципе вы можете не менять, т.к. это стандартные схемы(окна) и ID У Вас совпадут. А вообще, посмотреть их можно либо запросом в БД, либо в адресной строке, при открытии того или иного окна, указывается также и его идентификатор.

Да, действительно, я слишком поспешил, но по-моему там немного порядок нарушен.
Что касается версии, то 5.4.0.591
После всего остались две ошибки: "UserContext" и еще во втором скрипте (после сигнала IncidentEditPageClosed)

TargetScemaQuery.Filters.Add(TargetScemaQuery.CreateFilterWithParameters(
        FilterComparisonType.Equal, 
        "Id", 
        IncidentId));

используется IncidentId, но в скрипте он до этого не объявлен.

Александр, есть там объявление (в первом листинге):

var IncidentId = Guid.NewGuid();

По поводу UserContext - он был в 5.2. В 5.4 теперь это SessionData. Т.е. по сути Вам нужно заменить

UserConnection.UserContext.Add(defValuesId.ToString(), defValues);

на

UserConnection.SessionData.[defValuesId.ToString()] = defValues;

Если там потом этот ключ где считывается, то код следующий:

var test = Page.UserConnection.SessionData[defValuesId.ToString()];

C "UserContext", т.е. с SessionData получилось.
На счет IncidentId. Она объявлена в первом скрипте, но второй скрипт идет как отдельная функция, т.е. она не видит что происходит в первом скрипте, соответственно не видит объявление IncidentId.
Или я что-то не понимаю? Как можно передать переменную из одного скрипта в другой?

Добрый день.

Здесь, действительно, немного запутана очередность действий.

Логика следующая:

(сигнал нажатия на кнопку) -> (скрипт подготовки действия процесса "открыть карточку") -> (действие процесса открыть карточку) -> (сигнал закрытия карточки инцидента) -> (скрипт генерации номера инцидента).

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

myParam =  IncidentId;

А в последнем скрипте, вместо IncidentId использовать параметр.

Параметр нужно создать с типом Guid.

Спасибо. Теперь подберусь немного к сути задачи. Мне надо создать именно инцидент (поставил id инцидента и его карточки, все нормально открывается). Что надо сделать, чтобы после нажатия на кнопку "Ок" у инцидента, т.е. инцидент создан в карточке e-mail он добавился в поле инцидент?

Александр, необходимо добавить сроку кода в элементе (скрипт генерации номера инцидента), т.е. в последний скриптовый элемент в рамках добавленной вами логики:

Page.DataSource.ActiveRow.SetColumnValue("IncidentId", myParam);

где myParam - параметр, в котором хранится Id созданного инцидента.

По сути эта строчка должна добавлять инцидент к письму

Page.IncidentEdit.SetValueAndText(incidentCollection[0].GetTypedColumnValue<Guid>(primaryColumn.Name), incidentCollection[0].GetTypedColumnValue<string>("Number"));

Но скрипт выполняется сразу после открытия окна инцидента, а т.к. запись еще не внесена он не видит эту строку, соответственно ничего не добавляет. Как подождать закрытия окна инцидента?

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

Нужно ждать сигнал, в данном случае IncidentEditPageClosed. Посмотрите, в блоге данный промежуточный обрабатывающий сигнал присутствует.

Да. вы права, человеческий фактор невнимательность, вместо обрабатывающего сигнала поставил генерирующий.

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

Коллеги, в тройке была возможность добавления действия на карточке редактирования любого объекта, с помощью которого можно было перейти к связанной сущности. То есть, например, на карточке задачи в поле редактирования контрагента можно было нажать на это действие (выглядело как молния) и из появившегося меню выбрать либо "Открыть карточку контрагента", либо "Перейти к контрагенту". Можно ли реализовать аналогичный функционал в BPMonline? Если да, то каким образом?

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

Нравится

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

1) Посмотрите как реализовано тут http://www.community.terrasoft.ua/blogs/8319
2) В реестрах если нажать правой кнопкой мыши есть пункт - "Перейти к" - возможно этот функционал вам подойдет

Максим, по п.1, в целом, подходящая реализация, но громоздкая. кнопки занимают много места и не очень гармонично смотрятся на карточке. Особенно, если их создавать на многих полях. Может быть все же есть возможность реализации, аналогичной тройке? чтобы и места отъедать немного, и можно было бы заодно еще какое-то действие привязать, помимо открытия карточки.
по п.2: как вариант такая реализация вполне подойдет. Но "Перейти к" есть не во всех реестрах, а там где есть, переход предлагается только к одному полю (это либо Контрагент, либо Создал, либо Ответственный). Подскажите, как можно расширить этот список, а в тех реестрах где нет этого пункта, создать его?

Вы можете создать кнопку прямо в поле редактирования. Для этого Вам надо нажать правой кнопкой мыши на поле редактирования, и выбрать добавить кнопку.

Функциональность пунктов контекстного меню реализована на конфигурации, и может быть добавлена по аналогии с существующими пунктами.

Анна, спасибо за еще один вариант реализации. В принципе, он вполне хорош, за исключением того, что пользователю не очевидно, что произойдет по нажатию этой кнопки.
То, что можно пункты контекстного меню добавить по аналогии с существующими - хорошо. Но где можно посмотреть как это реализовано сейчас? в каком окне, в каком процессе, событии?

Уточните, пожалуйста, какое у Вас отраслевое решение?

Много примеров в карточке Инцидента и Запроса на обслуживание в продукте Service Desk.

У нас обычная версия 5.2, неотраслевое решение. Сервис деска нет. В любом случае и в нашем решении есть стандартные меню "Перейти к Ответственному/Контрагенту и т.д.". Например, в разделе "Контрагенты" есть пункт "Перейти к -> Создал". Где можно посмотреть как это реализовано?

Пример создания контекстного меню можно посмотреть в базовом реестре (BaseGridPage), а конкретной реализации скрипта перехода - в процессе окна напоминаний (RemindingsPage) в обработчике JumpButtonClickScriptTask.

Анна, к сожалению, я так и не смог разобраться в BaseGridPage и повторить реализацию, например, меню "Отправить e-mail". Может быть, вы сможете описать подробнее что мне нужно сделать и какой код использовать?
Я добавил меню "Открыть" в общее контекстное меню в реестре контрагентов. Теперь я хотел бы, чтобы при наведении на этот пункт у меня открылись два пункта "Ответственный" и "Контакт". Соотв-но, меня интересуют все действия, которые мне нужно сделать, чтобы
1) при наведении на "Открыть" у меня появились два новых пункта
2) при нажатии на пункт меню "Ответственный" у меня открылась карточка редактирования ответственного за текущего контрагента сотрудника.

Меню "Перейти к" формируется ядром по следующему принципу: в него включаются все колонки справочника, которые на данный момент выведены в реестр.

таким образом, чтобы у Вас была возможность перейти к ответственному либо контакту, следует вытянуть в реестр колонки Контакт и Ответственный.

Формировать это меню в конфигурации не получится - можно только сделать свое отдельное по аналогии, но для этого следует задействовать jscript

А в этом отдельном меню можно реализовать то, о чем я спрашивал?

"D.T." написал:Также в тройке была возможность в реестре записей, например, тех же задач (и в других реестрах тоже) щелкнуть по почти любой колонке конкретной записи и открыть карточку редактирования этого объекта, например, щелкнув в реестре задач по контакту, открывалась карточка редактирования этого контакта. Возможно ли такое в BPMonline?

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

Если Вам необходимо добавить иерархический пункт меню в реестре, тогда при добавлении подпункта следует установить курсор на кнопку контекстного меню в дизайнере. из которой это подменю должно появляться. Обработчик нажатия писать отдельно.

"D.T." написал:То есть, например, на карточке задачи в поле редактирования контрагента можно было нажать на это действие (выглядело как молния) и из появившегося меню выбрать либо "Открыть карточку контрагента", либо "Перейти к контрагенту". Можно ли реализовать аналогичный функционал в BPMonline? Если да, то каким образом?

Для реализации это функциональности Вам следует в дизайнере карточки нажать правой кнопкой мыши на поле, и добавить на него кнопку-молнию, затем реализовать программный компонент перехода по аналогии с описанным тут: http://www.community.terrasoft.ua/blogs/8319

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

Добрый день!

В новой для меня области начинают возникать различные вопросы...
Имеется задача: в разделе используется 5 типов например продуктов. Для двух из них нужно в карточке отобразить дополнительные пару полей.
Если пользоваться базовым функционалом, то мы создаем нужное количество карточек (в данном случае 5) для каждого типа, на основании одной базовой, содержащей все прочие поля. Далее в каждой карточке для каждого типа добавляем индивидуально дополнительные поля.
Далее в настройке Рабочих мест к разделу в деталь "Карточки редактирования" добавляем все 5 карточек для каждого типа отдельно. Все работает.

Нюанс. Мы не можем использовать две карточки - одна с допполями, другая без них, одна для нужных типов, другая для остальных, так как в этом случае получаем обрушение системы на моменте открытия раздела - в нем на кнопке "добавить" генерируются динамически пунктики для создания каждого из типов продукта с именем, включающим в себя id соответствующей страницы редактирования (ну а так как страниц всего две, а типов много - получаем два ActionMenuItem с одинаковы именем и крах...)
Вопрос. Для тонкой настройки множества параметров для разных типов эта схема удобна, а вот если все так, как я описал? Есть ли другой путь?

Нравится

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

Кстати, вдогонку...
Гуру, подскажите для bpm-чайника стоит ли связываться и как проще сделать традиционное скрытие/показ контролов на карточке? Или такой метод будет идеологически совсем неправильным?

Александр, добро пожаловать в BPMonline :) На какой это версии? Думаю, стоит подправить базовую логику, чтобы название пункта меню формировалось как название типа + карточка.
Мы скрываем элементы управления используя метод public virtual void SetVisible(bool visible), он управляет видимостью с помощью выполнения скрипта на клиенте. и это быстрее, чем управлять видимостью меняя свойство public virtual bool Hidden, хотя так тоже можно.

Это версия 5.3.0.332
Базовая логика - с непривычки боязно, я буду бороться с этим страхом, обещаю;) настораживает, что это название потом может использоваться для подъема карточки, передаваясь куда-то. Соответственно править надо и его, почва для исследования есть.

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

По-моему, не используется само название, там при создании реестра динамически формируются пункты выпадающего меню кнопки добавить в соответствии с зарегистрированной информацией в разделе Рабочие места и тут же им добавляются обработчики нажатия, так что не должно быть ничего преступного :)
В разумных пределах, думаю, это нормально, а если там 200 контролов скрыто, то может быть заметно.

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

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

Нравится

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

Здравствуйте, Юрий
Рассмотрим пример (карточка счета в разделе счета)
1
Мы хотим найти сервис данной карточки в Terrasoft Administrator
Сервисы карточек редактирования, по договоренности в Terrasoft называют с окончанием Edit, к примеру
карточка контрагента - wnd_AccountEdit
карточка контакта - wnd_ContactEdit

  1. Использовать поиск по заголовку
    2
    С точным поиском слова "Счет" после пару итераций мы дойдем до нужного нам сервиса wnd_InvoiceEdit.
    3
    Что бы перейти к следующему найденному совпадению слова, нужно нажать F3
  2. Открыть сервис раздела, в нашем случае это - wnd_InvoicesWorkspace
    и в коде соответствующему сервису раздела (scr_InvoiceWorkspace) посмотреть какое значение присваивается атрибуту EditWindowUSI
    function InitializeGridData() {
    	...
    	SetAttribute(GridWindow, 'EditWindowUSI', 'wnd_InvoiceEdit');
    	...
    }

    Функция InitializeGridData вызывается в Initialize() - процесс инициализации раздела (Workspace), он вызывается на событии OnPrepare раздела

Спасибо Алекскй, но мой вопрос касался BPMonline. В BPMonline видимо принцып немного другой, мне пока не понятный.


Все карточки редактирования заканчиваются на EditPage в названии. Заголовок же для карточки редактирования записи раздела начинается на "Страница карточки", для деталей и справочников на "Страница редактирования". Учтите также, что поиск по схемам BPMonline чувствителен к регистру.

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

В BPMonline карточки редактирования имеют названия EditPage

То есть карточка редактирования контакта называется ContactEditPage

Для страниц реестра используется множественное число - ContactsGridPage

Но, если Вы сами добавляли страницы и не придерживались таких принципов, тогда искать буде сложнее

Спасибо, теперь понятно.

Здравствуйте, Юрий.

Вы также можете в разделе "Рабочие места" найти нужный раздел или деталь, и посмотреть свойства детали "Карточки редактирования"

Поправлю Сергея - названия страниц реестров имеют суффикс "GridPage" и множественное число сущности, пример: ContactsGridPage.
Если страницы создавали самостоятельно, то проще всего их найти путём отображения колонки с датой создания и сортировки по убыванию.

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

Добрый день!
Скажите, пожалуйста, можно ли каким-то образом отражать во второй вкладке(или первой) окна редактирования карточки какую-либо закладку из этого же раздела. И при этом иметь возможность при этом удалять/добавлять записи на подобную закладку.

Нравится

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

Здравствуйте Дарья.
Приведем пример, добавим в карточку редактирования wnd_IncidentEdit закладку описание и отобразим в ней содержимое детали [Описание]

Просьба ознакомится с прикрепленным файлом
Процесс создания закладки в карточке инцидента.doc

Добрый вечер!
Спасибо большое, но я имела ввиду немного другое.
В одной из презентаций я видела такой пример ( в прикрепленном файле)
Хотелось бы иметь возможность добавлять, удалять, изменять записи на этой закладке

Добрый день!
Использовала скрипт в карточке на onprepare

var Dataset = dlData.Dataset;
if (TGroup.InitializeInvoicesFlag != true) {

TGroup.InvoicesWindow = wndTravellingGroup.Window;
SetAttribute(TGroup.InvoicesWindow, 'EditWindowUSI', 'wnd_TravellingGroupEdit');
SetAttribute(TGroup.InvoicesWindow, 'ParentItemFieldName', 'ContractID');
TGroup.InvoicesWindow.Prepare();
TGroup.InvoicesDataset =
TGroup.InvoicesWindow.ComponentsByName('dlData').Dataset;
TGroup.InitializeInvoicesFlag = true;

}

var ContractID = Dataset.ValAsGUID('ID');
if (ContractID == TGroup.InvoicesOldContractID) {
return;
} else {
TGroup.InvoicesOldContractID = ContractID;
}
SetAttribute(TGroup.InvoicesWindow, 'ParentItemID', ContractID);
RefreshDetailData(Dataset, 'ID', TGroup.InvoicesDataset, 'ContractID');
ApplyDatasetFilter(TGroup.InvoicesDataset, 'ContractID', Dataset.Values('ID'), true);

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

Дарья, опишите, пожалуйста, конкретно задачу, которую вы пытаетесь реализовать.

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

Последовать рекомендациям Олега http://www.community.terrasoft.ua/forum/topic/799#comment-21195 не получилось ?

не получилось.
Сделали обходной путь - кнопка Сохранить в карточке контакта, перед тем как использовать кнопки на закладке.

Но хотелось бы именно сохранять родительскую запись перед созданием дочерней ( без дополнительной кнопки)

"Татаровская Дарья" написал:не получилось.

Дарья, а можете показать как вы делали?
В вашем случае просто нужно при нажатии на любую из кнопок в реестре проверять в каком состоянии находится dataset карточки. Если состояние Insert, то автоматически делать сохранение. Но только в этом случае нужно сохранять где-то пометку о том, что карточка была автоматически сохранена. Потому что если пользователь нажмет кнопку Отмена -- нужно удалять созданную запись.

Дарья, вашу задачу можно реализовать следующим образом:
1) в скрипте к окну-гриду создаете свой обработчик нажатия кнопки btnAdd

function btnAddOnClick(Control) { 
	if (Self.Attributes('ParentItemFieldName') == 'ContractID')
	{
		var Dataset = Services.GetNewItemByUSI('ds_Contract'); 
		ApplyDatasetFilter(Dataset, 'ID', Self.Attributes('ParentItemID'), true); 
		Dataset.Open(); 
		if (Dataset.IsEmptyPage) 
	    	    SendNotify(Self, 'SAVE'); 
		else 
	    	    scr_BaseGridArea.btnAddOnClick(btnAdd); 
		Dataset.Close(); 
		return;
	}
 
	scr_BaseGridArea.btnAddOnClick(btnAdd); 
} 

Таким образом проверяете, сохранена ли родительская запись, и если нет - отправляете сообщение SAVE родительскому окну.

2) в том же скрипте создаете обработчик события окна OnNotify

function wnd_BaseGridAreaOnNotify(ScriptableService, Sender, Message, Data) {  
	if (Message == 'SAVED') 
	{ 
		scr_BaseGridArea.btnAddOnClick(btnAdd); 
		return; 
	} 
 
	scr_BaseGridArea.wnd_BaseGridAreaOnNotify(ScriptableService, Sender, Message, Data); 
};

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

3) и, наконец, в форме редактирования, в котором расположили это окно-грид, также создаете обработчик события OnNotify

function wnd_BaseDBEditOnNotify(ScriptableService, Sender, Message, Data) { 
	if (Message == 'SAVE') 
	{ 
	    if (SaveChangesWithCheck(Self, BaseDBEdit)) 
	    { 
	    	dlData.Dataset.Edit(); 
	        Sender.Notify(Self, 'SAVED', null); 
	    } 
	} 
} 

В нем мы получаем сообщение SAVE, пытаемся сохранить запись, и отправляем в ответ сообщение SAVED

Спасибо, Валерий, за совет

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

В карточке редактирования добавлено поле справочника и поле описаия значеия выбранного значения справочника. Но описание отображается только после сохранения данных в карточке.
Как заставить отображать систему отображать поля связанного справочника после выбора нового значения в карточке редактирования?

Нравится

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

Добрый день, Станислав!
Насколько мы поняли из предоставленного Вами описания проблемы: у Вас есть два поля, соответствующие двум связанным справочникам, в зависимости от выбранного значения в одном поле, значения другого варьируются и зависят от выбранного значения в первом справочнике.
Аналогичная функциональность реализована в карточке раздела "Задачи" (зависимость справочника "Результат" от справочника "Состояния"). Для реализации необходимой Вам функциональности Вы можете просмотреть реализацию стандартного функционала и сделать это по аналогии (сервис scr_TaskEdit). Для того, чтобы второй справочник открывался в карточке без пересохранения ее, Вам необходимо сперва объявить переменные, соответствующие ключам обоих справочников, а затем "наложить" фильтр. Как например, это реализовано в разделе задач:

function edtResultOnPrepareSelectWindow(LookupDataControl) {
var Dataset = dlData.Dataset;
var LookupDataset = LookupDataControl.DataField.LookupDataset;
var StatusID = Dataset.Values('StatusID');
var TaskTypeID = Dataset.Values('TypeID');
ApplyDatasetFilter(LookupDataset, 'TaskTypeID', TaskTypeID, true);
ApplyDatasetFilter(LookupDataset, 'StatusID', StatusID, true);
var AllowedResultIDs = GetAttribute(Self, 'AllowedResultIDs');
var IsResultIDsFilterEnabled = Assigned(AllowedResultIDs);
ApplyDatasetIncludeFilter(LookupDataset, 'IncludeID',
AllowedResultIDs, IsResultIDsFilterEnabled);
}

Желаем удачи!

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

Попробую объяснить на примере который Вы привели.
Нужно на событие изменения поля "Контрагент" датасета карточки задачи, делать запрос на получение значения поля "Численность" из датасета контрагентов.
Затем это значение присваивать контролу в котором нужно отобразить значение.
Можно использовать функцию GetDatasetFieldValueByID(DatasetUSI, ID, FieldName) из scr_DB.
Код будет выглядеть примерно следующим образом.

...................
function dlDataOnDatasetDataChange(DataField) {
	if (!Assigned(DataField)) {
		return;
	}
	var DataFieldName = DataField.Name;
	var Dataset = DataField.ParentDataFields.ParentDataset;
	switch (DataFieldName){
		case ('AccountID'):
			edtQuantity.Value = GetDatasetFieldValueByID('ds_Account', DataField.Value, 'Quantity');
			break;
...............................
Показать все комментарии

В карточке редактирования wnd_...Edit предлагается выделять Caption визуальных контролов для полей Dataset-а с признаком "Только для чтения" цветом, отличающимся от цвета остальных полей, например, зеленым, или выставлять IsEnabled = false.

Нравится

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

Если заголовки (Caption) визуальных контролов для полей с признаком "Только для чтения" и для других полей имеют один и тот же цвет, то пользователь постоянно путается при вводе данных.
Вот пример решения:

//Модуль scr_BaseDBEditUtils
 
function ProcessBaseDBEditOnPrepare(Window, BaseDBEdit) {
...
    /* Добавляем строчку в функцию... */
    SetCaptionColorForIsReadOnlyFields(Window); //Устанавливает цвет для полей с признаком "Только чтение"
}
 
//Устанавливает цвет для полей с признаком "Только чтение"
function SetCaptionColorForIsReadOnlyFields(Window) {
	for (var i = 0; i < Window.ComponentCount; i++) {
		if (!IsUndefined(Window.Components(i).DataField)) {
			if (Window.Components(i).DataField.IsReadOnly) {
				//Можно включить выделение цветом --> Window.Components(i).CaptionColor = clReadOnlyCaptionColor;
				Window.Components(i).IsEnabled = false;
			}
		}
	}
}

Добрый день, Петр.
В карточках редактирования элементы, поля которых имеют признак ReadOnly, отображаются серым цветом.
Если Вашим пользователям недостаточно базового отображения ReadOnly полей, то можно пойти и тем путем, который Вы описали. Действительно хороший вариант!

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