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

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

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

Нравится

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

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

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

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

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

В функции AppendRecord скрипта scr_BaseDBEditUtils заполняется ссылка на раздел (там, где BaseDBEdit.ParentItemID) и значения по умолчанию:

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);
	}
}

Эта функция срабатывает при отытии любой карточки с новой записью.

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

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

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

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

Лучше добавить проверку.
Вроде такого, тут проверяется на деталь в конкретном разделе:

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;
	}
}

Вторую функцию можно модифицировать, чтобы проверялось нахождение в детали вообще.

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

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

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

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