floatDataControl на панели кнопок детали воркспэйса

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

Как уже ранее я писал по другой проблеме: мне нужно добавить кнопку "Установить скидку на все продукты в счете" в воркспейс "Продукт" (wnd_OfferingDetailTreeArea) детали раздела "Счета".
Естественно, необходимо каким-то образом определить размер устанавливаемой скидки.

Я попробовал добавить floatDataControl на форму (см. приложенный скриншот fltDataControl.png).
Однако, при работе, значение в этом поле невозможно изменить, поле подсвечено серым и недоступно для редактирования.

Как это исправить?
Если такой способ выбора размера скидки невозможно реализовать, то как его можно реализовать по-другому?

Нравится

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

"Алейник Алексей Вадимович" написал:Я попробовал добавить floatDataControl на форму

Алексей, попробуйте добавить не floatDataControl, а NumericEdit + допишите нужное количество знаков после запятой в его свойствах, например, Precision=2 (по умолчанию там 0, кажется).
дело в том, что ДатаКонтролы "привязаны" к датасету (следовательно, данные берутся из какой-то таблицы либо же МемориДатасета), в Вашем же случае привязки нету, поэтому нужно использовать "обычный" контрол.
чтобы "взять" из него значение, пропишите NumericEdit.Value

Спасибо за помощь, Ольга. Подскажите, в таком случае, как мне обновить значения поля скидка и связанных с ним других полей записей продуктов в счете? Массив записей отфильтровал по 'InvoiceID':

function btnSetDiscountOnClick(Control) {
	var InvoiceDataset = Services.GetNewItemByUSI('ds_OfferingInInvoice');
	InvoiceDataset.Open();        
	ApplyDatasetFilter(InvoiceDataset, 'InvoiceID', InvoiceDataset.Values('InvoiceID'), true);
 
	if (InvoiceDataset.Values('InvoiceID') == null) {
		MessageBox('Нет привязанного счета!');
		return;
	}
//... здесь нужен код обновляющий записи (по одной и в цикле, как я понимаю)...
}

При обращении с помощью InvoiceDataset.Values('DiscountPercent') мы обращаемся сразу ко всем записям?
И надо-ли создавать новый UpdateQuery для обновления записей?

Хотел посмотреть как обновляются записи при изменении, например поля "% Скидки" карточки редактирования "Продукт" детали продукты раздела счета (wnd_OfferingDetailEdit). Нашёл обработчик dlDataOnDatasetDataChange, но в нём вызывается функция DatasetDataChange(), которая почему-то обрабатывает изменения только полей "OfferingID", "CustomOffering", "CurrencyID" и всё. Где реализовано обновление полей связанных со скидкой? я бы хотел воспользоваться кодами этих функций.

в событиях датасета (не окна) ds_OfferingInInvoice тоже есть событие ДатаЧендж, в котором прописана функция OfferingDetailDataChange(DataField, ScriptObject).
вот в ней и все "кейсы"-поля.

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

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

или Вам нужно свою логику дописать? тогда "копайте" дальше в функции OfferingDetailDataChange...

получился вот такой код в скрипте wnd_OfferingsDetailTreeAreaScript:

function btnSetDiscountOnClick(Control) {
	var InvoiceDataset = Services.GetNewItemByUSI('ds_OfferingInInvoice');
	InvoiceDataset.Open();        
	ApplyDatasetFilter(InvoiceDataset, 'InvoiceID', InvoiceDataset.Values('InvoiceID'), true);
 
	if (InvoiceDataset.Values('InvoiceID') == null) {
		MessageBox('Нет привязанного счета!');
		return;
	}
 
	while(!InvoiceDataset.IsEOF) {
		InvoiceDataset.Values('DiscountPercent') = numEditDiscount.Value;
		InvoiceDataset.GotoNext();
	}
 
	InvoiceDataset.Close();
	RefreshDataset(dlData.Dataset);
}

Однако, появляется ошибка (см. скриншот).

Видимо нужен на АпдэйтКвери?

"Алейник Алексей Вадимович" написал:появляется ошибка

ошибка так и говорит, что датасет не в том "режиме" (ни в едит -- редактирование, ни в инсерт -- добавление новой записи)
Вам нужно
"Ольга Прилипко" написал:сделать Едит() -- прописать скидку -- Пост()

т.е., если исходить из Вашего кода:

//...
 while(!InvoiceDataset.IsEOF) {
                InvoiceDataset.Edit();
                InvoiceDataset.Values('DiscountPercent') = numEditDiscount.Value;
                InvoiceDataset.Post();
                InvoiceDataset.GotoNext();
        }
//...

П.С. пересмотрела Вашу функцию...
можно узнать, почему Вы
А. берете новый екземпляр датасета ds_OfferingInInvoice
Б. накладываете фильтр по значению поля ИнвойсИД в нем...

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

если у Вас wnd_OfferingsDetailTreeArea (т.е. деталь Продукты в счете), то попробуйте так:

function btnSetDiscountOnClick(Control) {
        var InvoiceDataset = dlData.Dataset;;
        InvoiceDataset.GotoFirst();        
       //фильтр не надо, т.к. деталь уже отфильтрована по счету
        while(!InvoiceDataset.IsEOF) {
               InvoiceDataset.Edit();
                InvoiceDataset.Values('DiscountPercent') = numEditDiscount.Value;
                InvoiceDataset.Post();
                InvoiceDataset.GotoNext();
        }
 
        RefreshDataset(InvoiceDataset);
}

Попробовал как Вы предложили. При нажатии на кнопку меняется значения во всех связанных со скидкой полях кроме поля "% Скидки" (как раз то, которое которое явно инициализируется в только что написанной функции) и только для первой записи, затем выскакивает ошибка(см. скриншоты) и до второй итерации дело не доходит.

Здравствуйте, Алексей!
Возможно ли для решения проблемы организовать удаленное подключение?

"Алейник Алексей Вадимович" написал:затем выскакивает ошибка(см. скриншоты) и до второй итерации дело не доходит.

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

Андрей, возможно, готов сегодня до 18:00 или на следующей недели.

Ольга, закомментировал try/fynally в датаченжде: при нажатии на кнопку, везде добавляет скидку, но подсвеченный (выделенный) продукт копирует дважды, ошибок не выдаёт.

Ошибка была устранена в ходе сеанса удаленного доступа.
Причина ошибки - обращение к отключенным полям датасета, которое происходило в момент пересчета суммы налога.

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

здравствуйте, Алексей!
можно использовать или Нотифай, или через модальное окно, которое может возвращать результат.
второй вариант -- посмотрите здесь

Если через Notify, то это как я понимаю нужно добавить обработчик на событие OnNotify формы? Можно какой-нибудь примерчик?

алгоритм навскидку :
1) при вызове окна в его Атрибуты добавляете атрибут НотифайОбжект = текущее окно (Селф).

Attributes('NotifyObject') = Self;
//.....
ShowEditWindowEx('wnd_xxx', Attributes, DefaultValues)

2) в самом окне, при нажатии "ок" или где у Вас там окно закрывается (т.е. перед его закрытием) пишите функцию СендНотифай(Селф, "месседж", данные)

SendNotify(Self, 'TodoSomething', Result);

Result -- сюда можете "положить" данные, которые нужно передать (как массив, строку или обьект, неважно. главное, при обработке к нему "правильно" обратится")
3) в первом окне, которое "получает" это сообщение, прописываете обработчик онНотифай (так, как Вы написали), там конструкция вида "если сообщение == "месседж", то выполняем чтото с данными".
если это какой-то воркспейс, т.е. есть базовые функции онНотифай, то после своей обработки пропишите базовую.

switch (Message) {
   case 'TodoSomething':
     //TODO
   break
}

удачи Вам!

Спасибо за помощь, Ольга!

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

1) Не выполняется функция SendNotify() добавленная в код обработчика btnOKOnClick(control)
см. скриншот notify_error.png

2) Не вызывается обработчик dlDataOnDatasetDataChange(DataField). Он должен блокировать и разблокировать соответствующие поля ввода значения скидки, в зависимости от типа скидки (абсолютное значение или значение в процентах)
скриншот OnDatasetDataChange.png

Буду признателен любой помощи.

Ругается именно на параметр Self.
При вызове SendNontify() без параметра Result всё тоже самое.

Алексей, такое ощущение, что проблема не в Self, а в обращении к функции SendNotify().
Проверьте, пожалуйста, происходит ли переход к описанию функции при клике по ее вызову с зажатой клавишей Ctrl.
Если нет - нужно подключить скрипт, в котором реализована функция (скрипт scr_WindowUtils).

Наталия, Вы были правы,
Сейчас я добавил scr_WindowUtils.
Однако, почему-то скидка не хочет инициализироваться.

Алексей, вложите, пожалуйста, сервисы.

Наталия, прикладываю сервисы:services.zip

Алексей, спасибо. Взяли в работу. Как только будет информация - отпишемся.

Алексей, для корректного назначения скидки замените строку кода:

InvoiceDataset.Values('DiscountPercent') = Data.Value;

На:

InvoiceDataset.Values('DiscountPercent') = Data;
Показать все комментарии