Форум: "Базы";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];
Вниз---|Ветка была без названия|--- Найти похожие ветки
← →
Avreliy (2003-05-30 16:30) [0]Здравствуйте мастера! (вкратце: FireBird->D7->BDE->DBGrid)
Есть подчинённая таблица и один из столбцов объявлен так:
SUMM Numeric(9,2)(он же - TableESUMM). При внесении данных без всякой самодеятельности (без попыток переприсвоить) - всё срабатывает. А вот, если я после серии проверок желаю изменить вносящиеся данные (в проц-ре OnChange), например, таким образом
TableESUMM.Value := 100 * TableESUMM.Value,
то Д7 выдаёт Debugger Fault Notification: "access violation at 0Xxxxxxxx: write of address 0Xyyyyyyy".
Когда я пытаюсь изменить данные этого поля через запрос, напр.,
QueryESUMM.Value := 100,
то всё срабатывает. В чём ошибка?
← →
AlexSerp (2003-05-30 16:57) [1]Обычно access violation выдает Делфи. Проблема не в данных.
Я получал access violation, только тогда, когда пытался обратиться к несозданной или освобожденной переменной/объекту.
Других ошибок с access violation у меня не было.
← →
Соловьев (2003-05-30 17:00) [2]
> данные (в проц-ре OnChange),
а не пробовал при Edit
← →
Avreliy (2003-05-30 17:06) [3]> AlexSerp ©
Дело в том, что у меня уже есть существующий нединамический объект, а динамические объекты я не создавал.
← →
Sandman25 (2003-05-30 17:09) [4]Похоже, что происходит рекурсивный вызов обработчика OnChange, пока значение TableESUMM.Value не выйдет за пределы максимально возможного.
← →
Avreliy (2003-05-30 17:26) [5]> Sandman25
А как может происходить вызов, если я его в обработчике не указываю?
> Соловьев
Ведь такого обработчика не существует для TField-объектов?
Т.е. советуешь использовать AfterEdit для TTable?
← →
Zacho (2003-05-30 17:31) [6]
> Avreliy (30.05.03 17:26)
Изменение значения поля в OnChange приводит к вызову OnChange .. и поехало - бесконечная рекурсия.
Используй TField.OnSetText - он для этого и придуман.
← →
Sandman25 (2003-05-30 18:03) [7]2 Avreliy
procedure TableOnChange(...);
begin
Table.OnChange := nil;
try
TableESUMM.Value := 100 * TableESUMM.Value;
finally
Table.OnChange := TableOnChange;
end;
← →
Zacho (2003-05-30 18:14) [8]
> Sandman25 © (30.05.03 18:03)
Зачем ??? Ведь есть OnSetText.
← →
Avreliy (2003-05-30 18:21) [9]Если я использую TField.OnSetText, то игнорируется OnValidate и вдобавок после попытки ввести данные они исчезают.
Если использовать просто OnValidate, то вводимые данные тоже будут исчезать.
← →
Sandman25 (2003-05-30 18:24) [10]2 Zacho
Может пригодиться. В данном случае, возможно, и не нужно.
← →
Zacho (2003-05-30 18:27) [11]
> Sandman25 © (30.05.03 18:03)
И еще дополнение: работать твой пример все равно не будет. Правильно было бы так:
procedure TMyForm.MyTableMyFieldChange(Sender:TField);
var
tmpOnChange:TFieldNotifyEvent;
begin
tmpChange:=Sender.OnChange;
Sender.OnChange:=nil;
try
Sender.Value:=...;
finally
Sender.OnChange:=tmpOnChange;
end;
end;
Только зачем такое извращение ?
← →
Sandman25 (2003-05-30 18:28) [12]2 Zacho
Вспомнил одну программку по вводу ТТН, где при изменении пользователем цены с НДС нужно было устанавливать цену без НДС, а при изменении цены без НДС устанавливать цену с НДС.
← →
Avreliy (2003-05-30 18:30) [13]> Sandman25
Не совсем понял твой код???
Ведь у TTable нет обработчика OnChange.
И что такое Table.OnChange?
← →
Zacho (2003-05-30 18:33) [14]
> Avreliy (30.05.03 18:21)
Значит, как-то не так используешь OnSetText, у меня проблем не было.
А OnValidate предназначен исключительно для того, чтобы вызвать Exception если введенные данные не прошли проверку.
← →
Sandman25 (2003-05-30 18:33) [15]>Zacho © (30.05.03 18:27)
Я обычно ставил обработчик на DataSource.OnDataChange.
Для него и пример привел, только не в тему :)
← →
Sandman25 (2003-05-30 18:37) [16]>Avreliy (30.05.03 18:30)
См.Zacho © (30.05.03 18:27), а еще лучше
Zacho © (30.05.03 17:31) ибо Sandman25 © (30.05.03 18:33)
Прошу прощения за нежеланное запутывание
← →
Zacho (2003-05-30 18:44) [17]
> Sandman25 © (30.05.03 18:33)
Да дело не столько в теме, сколько в том, что Table.OnChange := TableOnChange - неправильно. Возможно, ты все-таки имел в виду не процедуру, а метод ? :-)
← →
Avreliy (2003-05-30 18:44) [18]> Zacho © (30.05.03 18:33)
В том-то и дело, что он не вызывает Exception.
Вводимые данные попросту исчезают из поля ввода, абсолютно игнорируясь.
← →
Sandman25 (2003-05-30 18:54) [19]Zacho © (30.05.03 18:44)
Естественно метод. Ошибся.
procedure TForm1.DataSource1OnChange(Sender:TObjoect; Field:TField); Примерно так надо было... вроде :)
PS. Я сегодня встал в полпятого утра и хочу спать, а с работы уйти не могу - работаю до 19-00 по мск. Вот и приходится лазить по форуму, чтобы не уснуть. Ничего, через пару минут наконец-то пойду домой :)
Счастливо!
← →
Sandman25 (2003-05-30 18:55) [20]Не, вот так :)
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
← →
Zacho (2003-05-30 19:00) [21]
> Avreliy (30.05.03 18:44)
Exception должен вызывать ты сам в OnValidate. Или ты о чем-то другом ?
← →
Avreliy (2003-05-30 19:34) [22]В OnValidate я анализирую состояние переменных и в случае чего генерирую исключительную ситуацию. Например, анализирую на предмет возможного ввода отрицательного значения.
А вот после его ввода(отриц. зн-ния) поле ввода снова, как ни в чём и не бывало, оказывается пустым и исключительная ситуация не генерируется.
И ещё. Ведь OnSetText предназначен скорее для работы с текстом, чем для работы с числовыми переменными. И как-то бессмысленно работать со свойством Text вместо Value.
Или с этим обработчиком нужно работать по-другому?
Если код из OnChange просто перебросить в OnSetText, то данные после ввода исчезают.
← →
Zacho (2003-05-30 20:01) [23]
> Avreliy (30.05.03 19:34)
Честно признаюсь, потребность в OnGetText/OnSetText последний раз возникала у меня довольно давно, и было это на Дельфи 3 :-)
Но помню, что никаких проблем не возникало. Приведи свой код обработчика OnSetText.
Как вариант - попробуй TDataSet.BeforePost
← →
Avreliy (2003-05-30 20:52) [24]if (ANSILowerCase(taEMDETAILRISETYPE.Value) = "ххххх") then begin
if quJob.Active then quJob.Close;
quJob.ParamByName("JOBTYPE").Value := taEMDETAILJOBTYPE.Value;
quJob.Open;
if (taEMPLOYEEGRADETYPE.IsNull) then
taEMDETAILSUMM.Value := taEMDETAILSUMM.Value * (quJobCOEFF.Value / 100)
else begin
if quGrade.Active then quGrade.Close;
quGrade.ParamByName("GRADETYPE").Value := taEMPLOYEEGRADETYPE.Value;
quGrade.Open;
taEMDETAILSUMM.Value := quGradeGRADESUM.Value * (quJobCOEFF.Value / 100)
end
end
else taEMDETAILSUMM.Value := taEMDETAILSUMM.Value
--------------------------------------------------
ta -таблицы, qu -запросы.
taEMDETAILSUMM.Value, quGradeGRADESUM.Value - TBCDField
quJobCOEFF.Value - TInteger
← →
Zacho (2003-05-30 21:21) [25]
> Avreliy (30.05.03 20:52)
Насколько я понял, это обработчик OnSetText именно поля taEMDETAILSUMM ?
Тогда можно попробовать следующее:
1. else taEMDETAILSUMM.Value := taEMDETAILSUMM.Value - убрать, все равно бессмысленно.
2. taEMDETAILSUMM.Value := taEMDETAILSUMM.Value * (quJobCOEFF.Value / 100) заменить на Sender.Value :=StrToFloat(Text) * (quJobCOEFF.Value / 100)
И, если не получится, как насчет обработки в BeforePost ?
← →
Zacho (2003-05-30 21:26) [26]
> Avreliy (30.05.03 20:52)
И, в догонку, это случаем не lookup поле?
← →
Avreliy (2003-05-30 21:41) [27]1. Это не lookup поле.
2. taEMDETAILSUMM.Value := taEMDETAILSUMM.Value * (quJobCOEFF.Value / 100) заменить на
Sender.Value :=StrToFloat(Text) * (quJobCOEFF.Value / 100) -
не помогает.
3. В BeforePost ещё не успел.
← →
Zacho (2003-05-30 22:14) [28]
> Avreliy (30.05.03 21:41)
> 2. taEMDETAILSUMM.Value := taEMDETAILSUMM.Value * (quJobCOEFF.Value
> / 100) заменить на
> Sender.Value :=StrToFloat(Text) * (quJobCOEFF.Value / 100)
> не помогает.
Странно. То ли я уже хорошенько забыл, как работает OnSetText, то ли в D7 он работает как-то по другому. То ли дело вообще в чем-то другом.
Попробуй сделать нужные тебе действия в BeforePost.
Похоже, больше ничем не могу помочь. :(
← →
Avreliy (2003-05-30 22:15) [29]Я вот подумал...
BeforePost не подходит, потому что мне нужно, чтобы результат отображался незамедлительно после ввода, а не перед попыткой отправить данные на базу.
← →
Zacho (2003-05-30 22:35) [30]
> Avreliy (30.05.03 22:15)
Тогда попробуй разобраться с OnSetText. Imho, это самый правильный способ.
В крайнем случае - Zacho © (30.05.03 18:27) , но это все же изврат.
P.S. А почему BDE ? Старый проект ? Если есть возможность перейти на FIBPlus или IBX - крайне рекомендую.
← →
Avreliy (2003-05-30 22:48) [31]Дело в том, что это мой первый проект БД...
и весьма вероятно, что последний с использованием BDE...
Если помнишь, мы уже говорили на эту тему.
Но в любом случае, спасибо за содействие.
← →
Zacho (2003-05-30 23:05) [32]
> Avreliy (30.05.03 22:48)
> Если помнишь, мы уже говорили на эту тему.
Уже забыл, что именно с тобой :(
Удачи !
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.028 c