Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
1-84364
SLI
2003-06-16 18:23
2003.06.26
Архивирование данных


1-84126
Hooch
2003-06-10 13:26
2003.06.26
Вид приложения


4-84841
fifo
2003-04-22 18:10
2003.06.26
Как захватить изображене чужого окна?


1-84177
Эдик Дятлов
2003-06-11 08:45
2003.06.26
Отрисовка окна в цикле


1-84327
Igor
2003-06-16 05:29
2003.06.26
Как запустить программу и дождаться ее завершения?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский