автоматическое заполнение
Скрипты
Разработка

Автоматическое заполнение связей

Добрый день. Я меня в каждой карточке прописаны (а кое-где так и было в системе изначально) действия по автоматическому заполнению других полей при изменении связей. Это происходит для любого датасета ХХХ на событие OnDatasetDataChange в функциях SelfOnDatasetDataChange скрипта ds_ХХХScript. Все хорошо и правильно работает, скорость заполнения карточек возрастает в несколько раз.
Но есть проблема. Скрипт не отрабатывает, если создавать новые записи в деталях. Работает какой-то другой скрипт, который только заполняет одно поле, по которому деталь привязана к разделу. И все.
Те есть я например создаю Операцию из раздела Продажи, то поле Продажа будет заполнено автоматически, а другие поля, которые должны заполняться в этой связи (допустим Клиент, Воздействие) останутся пустыми. При этом как бы получается, что заполнение поля Продажа не есть в этом случае событие OnDatasetDataChange.

Какой скрипт работает при создании карточки в детали? Как после заполнения связи "заставить" систему считать это изменением Dataseta?

Нравится

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

Здравствутйе, Виктория!
Для деталей обычно используются другие датасеты, не те, что в разделах:

Думаю, все дело в этом.

Но такие дополнительные датасеты есть не для всех деталей. Кроме того, в них нет ничего, кроме только ID самой связи, это не полноценный набор данных. И скриптов к таким датасетам нет, хотя бы те, которые отвечают за заполнение этой одной связи в созданной карточке. Где происходит это заполнение?
При этом , например, заполнение значений по умолчанию работает корректно. И в создаваемых карточках эти поля заполнены верно.

"Тихенко Виктория" написал:Где происходит это заполнение?

В функции AppendRecord скрипта scr_BaseDBEditUtils заполняется ссылка на раздел (там, где BaseDBEdit.ParentItemID) и значения по умолчанию:
[javascript]
function AppendRecord(BaseDBEdit, Window) {
var Dataset = BaseDBEdit.Dataset;
var Attributes = Window.Attributes;
var DoDisableEvents = !Attributes('DoNotDisableEvents');
BaseDBEdit.RecordID = Connector.GenGUID();
Dataset.DisableGettingDisplayValues();
try {
Dataset.Append();
if (DoDisableEvents) {
Dataset.DisableEvents();
}
try {
Dataset.ValAsGUID('ID') = BaseDBEdit.RecordID;
Window.Attributes('RecordID') = BaseDBEdit.RecordID;
if ((!IsEmptyValue(BaseDBEdit.ParentItemID)) &&
(!IsEmptyValue(BaseDBEdit.ParentItemFieldName))) {
var DataField = Dataset.DataFields(BaseDBEdit.ParentItemFieldName);
if (Assigned(DataField)) {
DataField.Value = BaseDBEdit.ParentItemID;
}
}
SetDefaultValues(BaseDBEdit);
Window.Attributes('IsNewRecordAppend') = true;
} finally {
if (DoDisableEvents) {
Dataset.EnableEvents();
}
}
} finally {
Dataset.EnableGettingDisplayValues();
}
if (!Attributes('DontSetWindowCaption')) {
SetEditWindowCaption(BaseDBEdit, Window);
}
}
[/javascript]
Эта функция срабатывает при отытии любой карточки с новой записью.

Скрипт на изменение поля не отрабатывает, поскольку атрибут DoNotDisableEvents равен false, то есть в момент заполнения ссылки на раздел события специально отключены.

Чтобы их оставить включенными, надо в GridArea вашей детали сделать свой обработчик кнопки «Добавить» аналогично, например, wnd_ContractsDetailGridAreaScript. Примерно так:

[javascript]
function btnAddOnClick(Control) {
var Attributes = GetNewDictionary();
Attributes('DoNotDisableEvents') = true;
AddGridAreaData(Self, Self, BaseGridArea, Attributes);
}
[/javascript]

Если в большинстве случаев , в деталях идет ссылка на на специально созданное DetailGridArea для отражения связанных данных, а на основное (например сразу на wnd_OpportunitiesGridArea), то там тоже можно так прописать?
или это повлечет какие-то неприятные последствия в разделе (в данном случае в разделеOpportunity)?

Лучше добавить проверку.
Вроде такого, тут проверяется на деталь в конкретном разделе:
[javascript]
function btnAddOnClick(Control) {
if (IsWindowProjectDetaill(Self)) {
var Attributes = GetNewDictionary();
Attributes('DoNotDisableEvents') = true;
AddGridAreaData(Self, Self, BaseGridArea, Attributes);
} else {
scr_BaseGridArea.btnAddOnClick(Control);
}
}

function IsWindowProjectDetail(Window) {
try {
var Result =
Window.ParentContainer.ParentWindow.Name == 'wnd_ProjectWorkspace';
return Result;
} catch (E){
return false;
}
}
[/javascript]
Вторую функцию можно модифицировать, чтобы проверялось нахождение в детали вообще.

Виктория вопрос в своем обращение вы какую цель хотели достичь? В детали Операции Из раздела Продажи вы создаете операцию и желаете чтобы в Открытой карточке были заполнены по максимому Поля из Текущей записи Продажи. я правильно вас понял?

У меня целей много. И из Продажи создавать операции, инциденты, и еще кучу всего. И из других сущностей создавать Продажи. И т.д... Так что это лишь пример.
Мало того, в любой из этих ситуаций поля по разному заполняются на основании разной информации и связей. Все это прописано в карточках на изменении полей.
Цель - что бы эта же логика была в деталях.

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

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