Здравствуйте.
Как уже ранее я писал по другой проблеме: мне нужно добавить кнопку "Установить скидку на все продукты в счете" в воркспейс "Продукт" (wnd_OfferingDetailTreeArea) детали раздела "Счета".
Естественно, необходимо каким-то образом определить размер устанавливаемой скидки.
Я попробовал добавить floatDataControl на форму (см. приложенный скриншот fltDataControl.png).
Однако, при работе, значение в этом поле невозможно изменить, поле подсвечено серым и недоступно для редактирования.
Как это исправить?
Если такой способ выбора размера скидки невозможно реализовать, то как его можно реализовать по-другому?
Нравится
"Алейник Алексей Вадимович" написал:Я попробовал добавить floatDataControl на форму
Алексей, попробуйте добавить не floatDataControl, а NumericEdit + допишите нужное количество знаков после запятой в его свойствах, например, Precision=2 (по умолчанию там 0, кажется).
дело в том, что ДатаКонтролы "привязаны" к датасету (следовательно, данные берутся из какой-то таблицы либо же МемориДатасета), в Вашем же случае привязки нету, поэтому нужно использовать "обычный" контрол.
чтобы "взять" из него значение, пропишите NumericEdit.Value
Спасибо за помощь, Ольга. Подскажите, в таком случае, как мне обновить значения поля скидка и связанных с ним других полей записей продуктов в счете? Массив записей отфильтровал по 'InvoiceID':
[javascript]
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;
}
//... здесь нужен код обновляющий записи (по одной и в цикле, как я понимаю)...
}
[/javascript]
При обращении с помощью InvoiceDataset.Values('DiscountPercent') мы обращаемся сразу ко всем записям?
И надо-ли создавать новый UpdateQuery для обновления записей?
Хотел посмотреть как обновляются записи при изменении, например поля "% Скидки" карточки редактирования "Продукт" детали продукты раздела счета (wnd_OfferingDetailEdit). Нашёл обработчик dlDataOnDatasetDataChange, но в нём вызывается функция DatasetDataChange(), которая почему-то обрабатывает изменения только полей "OfferingID", "CustomOffering", "CurrencyID" и всё. Где реализовано обновление полей связанных со скидкой? я бы хотел воспользоваться кодами этих функций.
в событиях датасета (не окна) ds_OfferingInInvoice тоже есть событие ДатаЧендж, в котором прописана функция OfferingDetailDataChange(DataField, ScriptObject).
вот в ней и все "кейсы"-поля.
насчет "как обновить" -- думаю, если не отключать события датасета, пройтись в цикле по всем записям Продуктов в счете и сделать Едит() -- прописать скидку -- Пост(), то должно быть все ок.
события Вы не будете отключать -- значит, "сработает" базовый пересчет других полей.
или Вам нужно свою логику дописать? тогда "копайте" дальше в функции OfferingDetailDataChange...
получился вот такой код в скрипте wnd_OfferingsDetailTreeAreaScript:
[javascript]
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);
}
[/javascript]
Однако, появляется ошибка (см. скриншот).
![]()
Видимо нужен на АпдэйтКвери?
"Алейник Алексей Вадимович" написал:появляется ошибка
ошибка так и говорит, что датасет не в том "режиме" (ни в едит -- редактирование, ни в инсерт -- добавление новой записи)
Вам нужно
"Ольга Прилипко" написал:сделать Едит() -- прописать скидку -- Пост()
т.е., если исходить из Вашего кода:
[javascript]
//...
while(!InvoiceDataset.IsEOF) {
InvoiceDataset.Edit();
InvoiceDataset.Values('DiscountPercent') = numEditDiscount.Value;
InvoiceDataset.Post();
InvoiceDataset.GotoNext();
}
//...
[/javascript]
П.С. пересмотрела Вашу функцию...
можно узнать, почему Вы
А. берете новый екземпляр датасета ds_OfferingInInvoice
Б. накладываете фильтр по значению поля ИнвойсИД в нем...
ладно бы, если ИнвойсИД Вы откуда-то брали (из аттрибутов окна, например).
тут же оно непонятно какое значение подставит (теоретически -- понятно. оно откроет датасет и возьмет ИД счета из первой записи в нём. а вот какая это будет запись, зависит от сортировки по умолчанию и общей структуры запроса...)
если у Вас wnd_OfferingsDetailTreeArea (т.е. деталь Продукты в счете), то попробуйте так:
[javascript]
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);
}
[/javascript]
Попробовал как Вы предложили. При нажатии на кнопку меняется значения во всех связанных со скидкой полях кроме поля "% Скидки" (как раз то, которое которое явно инициализируется в только что написанной функции) и только для первой записи, затем выскакивает ошибка(см. скриншоты) и до второй итерации дело не доходит.
![]()
![]()
Здравствуйте, Алексей!
Возможно ли для решения проблемы организовать удаленное подключение?
"Алейник Алексей Вадимович" написал:затем выскакивает ошибка(см. скриншоты) и до второй итерации дело не доходит.
судя по всему, ошибка выскакивает "дальше" (на ДатаЧендже), ее сообщение имеет ввиду, что не подключен какой-то скрипт или где-то опечатка в вызове функции. поскольку весь функционал "завернут" в конструкцию "try-finally", то оно и "вываливается" на finally.
Вы ничего в этом скрипте не меняли?
можно попробовать закомментировать строчки "try-finally"-- чтобы оно точно указало, чего ему "не хватает"..
Андрей, возможно, готов сегодня до 18:00 или на следующей недели.
Ольга, закомментировал try/fynally в датаченжде: при нажатии на кнопку, везде добавляет скидку, но подсвеченный (выделенный) продукт копирует дважды, ошибок не выдаёт.
Ошибка была устранена в ходе сеанса удаленного доступа.
Причина ошибки - обращение к отключенным полям датасета, которое происходило в момент пересчета суммы налога.
Понадобилось добавить возможность установить абсолютное значение скидки, перенести установку значения скидки на отдельную открывающуюся форму с разными вариантами установления скидки. Создал форму, вызываю её с помощью "ShowEditWindowEx()". Как получить значения полей из этой формы? Можно-ли их вытащить из возвращаемого функцией ShowEditWindowEx() значения?
Если через Notify, то это как я понимаю нужно добавить обработчик на событие OnNotify формы? Можно какой-нибудь примерчик?
алгоритм навскидку :
1) при вызове окна в его Атрибуты добавляете атрибут НотифайОбжект = текущее окно (Селф).
[javascript]
Attributes('NotifyObject') = Self;
//.....
ShowEditWindowEx('wnd_xxx', Attributes, DefaultValues)
[/javascript]
2) в самом окне, при нажатии "ок" или где у Вас там окно закрывается (т.е. перед его закрытием) пишите функцию СендНотифай(Селф, "месседж", данные)
[javascript]
SendNotify(Self, 'TodoSomething', Result);
[/javascript]
Result -- сюда можете "положить" данные, которые нужно передать (как массив, строку или обьект, неважно. главное, при обработке к нему "правильно" обратится")
3) в первом окне, которое "получает" это сообщение, прописываете обработчик онНотифай (так, как Вы написали), там конструкция вида "если сообщение == "месседж", то выполняем чтото с данными".
если это какой-то воркспейс, т.е. есть базовые функции онНотифай, то после своей обработки пропишите базовую.
[javascript]
switch (Message) {
case 'TodoSomething':
//TODO
break
}
[/javascript]
удачи Вам!
Спасибо за помощь, Ольга!
Реализовал, как Вы по Вашему алгоритму, однако столкнулся с некоторыми проблемами.
1) Не выполняется функция SendNotify() добавленная в код обработчика btnOKOnClick(control)
см. скриншот notify_error.png
2) Не вызывается обработчик dlDataOnDatasetDataChange(DataField). Он должен блокировать и разблокировать соответствующие поля ввода значения скидки, в зависимости от типа скидки (абсолютное значение или значение в процентах)
скриншот OnDatasetDataChange.png![]()
![]()
Буду признателен любой помощи.
Ругается именно на параметр Self.
При вызове SendNontify() без параметра Result всё тоже самое.
Алексей, такое ощущение, что проблема не в Self, а в обращении к функции SendNotify().
Проверьте, пожалуйста, происходит ли переход к описанию функции при клике по ее вызову с зажатой клавишей Ctrl.
Если нет - нужно подключить скрипт, в котором реализована функция (скрипт scr_WindowUtils).
Алексей, спасибо. Взяли в работу. Как только будет информация - отпишемся.
Алексей, для корректного назначения скидки замените строку кода:
[javascript]
InvoiceDataset.Values('DiscountPercent') = Data.Value;
[/javascript]
На:
[javascript]
InvoiceDataset.Values('DiscountPercent') = Data;
[/javascript]
