Обновление поля карточки контрагента после открытия справочника и изменения соответствующего значения в нем

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

Возникла следующая ситуация. В карточке контрагента есть два поля Контакт (LookupDataControl) и Телефон контакта (TextDataControl). При выборе контакта поле Телефон контакта автоматически заполняется значением поля Средство связи 1 Контакта. Происходит это на событии dlDataOnDataSetDataChange.
Но поле Телефон контакта обновляется, только если выбирать нового контакта в открывшемся окне справочника. А если у ранее выбранного контакта просто изменить номер телефона (нажав кнопку Изменить в окне Выбор контакта и изменив значение поля Средство связи 1), то есть не выбирать новый контакт, а как бы изменить и выбрать прежний, то поле Телефон контакта карточки контрагента не обновится. И телефон останется прежним.

Подскажите, пожалуйста, как сделать так, чтобы значение поля Телефон контакта обновлялось сразу после закрытия окна справочника Контактов?

Нравится

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

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

Здравствуйте, Ольга!
Если я все правильно понимаю, у меня сейчас все так и есть.
В tbl_account есть только поле ContactID. В запросе sq_account есть колонка ContactPhone. Есть соответствующее поле в датасете и в карточке.
В том то и дело, что Поле Телефон в карточке контрагента обновляется только при следующем открытии карточки. А необходимо, чтобы это происходило сразу после выбора и закрытия справочника.
Поэтому на событие dlDataOnDataSetDataChange была описана функция обновляющая поле ContactPhone. Но, как я уже говорила выше, это событие не обрабатывается, если не был выбран новый контакт, а просто было обновлено поле телефон, у того контакта, который уже был выбран.

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

//Try потому что при получении прародительского окна из Воркспейса контактов вылетает ошибка (прародительского окна нет)
try {
	//Получаем прародительское окно (Допустим идем по такому пути Счет - выбираем Клиента (Окно выбора контрагента) - карточка контрагента - выбираем основной контакт(окно выбора контакта) - карточка контакта (текущее окно))
	var ParentWindow = Self.Attributes('NotifyObject').Attributes('NotifyObject').ParentWindow;
	//Убеждаемся что прародительское окно - это карточка контрагета (можно по USI брать)
	if (ParentWindow.Caption == 'Контрагент') {
		//Берем Dataset окна контрагента
		var AccountDataset = ParentWindow.ComponentsByName('dlData').Dataset;
		//Проверяем, что в текущей карточке тот контакт, который у нас в поле Основной контакт в контрагенте, а то и DataChange в контргаенте с этим справится
		//Вдруг меняют телефон другого контакта (между делом)
		if (AccountDataset('PrimaryContactID') == Dataset('ID')) {
			//Запихиваем нужную информацию
			AccountDataset('FieldX') = Dataset('Communication1');
		}
	}
} catch(e) {
}

Надеюсь разберетесь

Здравствуйте, Александр Владимирович!

Спасибо Вам за совет!

Попробывала этот код привязать на событие dlDataOnDatasetDataChange (компонента dlData сервиса wnd_ContactEdit). Выглядит это следующим образом:

function dlDataOnDatasetDataChange(DataField) {
    var Dataset = DataField.ParentDataFields.ParentDataset;
    var Value = DataField.Value;
    var Name = DataField.Name;
    switch (Name) {
        case ('Communication1'):
            try {
        	var ParentWindow = Self.Attributes('NotifyObject').Attributes('NotifyObject').ParentWindow;
		if (ParentWindow.Caption == 'Контрагент') {
                    var AccountDataset = ParentWindow.ComponentsByName('dlData').Dataset;
                    if (AccountDataset('ContactID') == Dataset('ID')) {
                        AccountDataset('ContactPhone') = Dataset('Communication1');
                    }
                }
            } catch(e) {
            }
        break;

В этом случае, действительно, в момент правки поля Средство связи 1 в карточке контакта тоже самое происходит в поле Телефон контакта в карточке контрагента. Но это не совсем верно, потому что может так случится, что пользователь Начнет править телефон в карточке контакта (параллельно он исправиться и в карточке контрагента), а потом передумает и нажмет Отмена. В результате в карточке контакта телефон останется прежним. А в карточке контрагента будет записан тот, что пользователь пробовал ввести в карточке контакта перед тем как нажать отмену.

Еще попробывала привязать этот скрипт на событие OnDatasetDataChange у ds_Contact (function SelfOnDatasetDataChange(DataField) в скрипте scr_Contact)

if (DataField.Name == 'Communication1'){
    try {
            var ParentWindow = Self.Attributes('NotifyObject').Attributes('NotifyObject').ParentWindow;
            if (ParentWindow.Caption == 'Контрагент') {
                var AccountDataset = ParentWindow.ComponentsByName('dlData').Dataset;
                if (AccountDataset('ContactID') == Dataset('ID')) {
                    AccountDataset('ContactPhone') = Dataset('Communication1');
                }
            }
    } catch(e) {
    }
    return;
}

Но это не помогло. В этом случае поле Телефон контакта в карточке Контакта вообще не обновляется.

Может быть я что-то неправильно делаю ? Или код нужно прописать на каком другом событии ? Подскажите, пожалуйста...

В скрипте датасета не надо прописывать. Из него вы не обратитесь к прародительскому окну, а так как там стоит try, то вы и ошибку не видите. (хотя может вру)
Думаю надо делать все в карточке контакта.
Чтобы избежать ситуации, которую вы описали, могу предложить создать глобальную переменную

var ContactPhone = null; //На OnPrepare лучше тоже прописать ContactPhone = null

На изменение поля Communication1 записывать значение в эту переменную (без моего скрипта).

ContactPhone = Dataset('Communication1');

А мой скрипт поместить на датасет в карточке на BeforePost, только вместо поля Dataset('Communication1') брать глобальную переменную, если она не null.
Если пользователь закроет карточку или отмену нажмет, то BeforePost не сработает, если ContactPhone == null, то телефон не менялся, не зачем его записывать в контрагента.
И только когда телефон поменяли и была нажата кнопка "ОК" произойдет то, что нужно.

Это мысли вслух (точнее в форум), не проверял, оставляю на вас, пропадет динамика (добавили 1 цифру в контакте, тут же добавилась цифра в контрагенте), но вроде бы она вам и не нужна.

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