Поиск блогу

пятница, 29 мая 2009 г.

Точка, точка, запятая...

Все тот же Delphi, все таже программа для студентов. Написал, быстренько протестил - вроде все работает. И отправил на согласование. Жду лестных отзывов. А отзывы приходят совсем неожидаемые.

Не работают увеличение/уменьшение дробный чисел. Почему? Ведь там все предельно просто:
Edit.text:=floattostr(a-0.01);

Стал разбираться. Оказалось функция floattostr работает косячно. И очень зависит от настроек винды. Если винда настроена на точку, то дробным число она считает с точкой, если на запятую, то дробные числа с запятой, а с точкой это слово. Все вроде бы ничего. Но на событии OnChange есть процедура val, которая работает исключительно с точкой.
В итоге, так как уменя все на точку настроено, то глюков у меня нет. А вот на компе согласование настроено на запятую. И при увеличении там значения, val думает, что это текст, выдаёт ошибку и возвращает предыдущие значение, но через тот же floattostr. Система зациклилась, увеличение/уменьшение не работает.

Решение этой проблемы банальное, меняем принудительно точку на запятую, а это на каждый вывод чисел дополнительно надо вешать Stringreplace. Опять получается громоздко. А все почему? Поточу что кт0-то не может прийти к единому мнению как писать дробные числа с точкой или запятой... Не правильно это...

четверг, 28 мая 2009 г.

Контролировать ввод данных.

Так случилось, что пришлось сесть за комп, открыть Delphi и писать программу, не коммерческого, но, можно сказать, массового использования. Сие творение будет представлять из себя лабораторную работу для студентов изучающих процессы в оптоволокне.
В ходе работы потребуется вводить различные значения. Но студент не будет студентом если не введёт что-то другое, нежели указано в методическом указании. Вот собственно я и задался проблемой обломать студентов и перекрыть им возможность всяких буковок и прочей фигни...

Первый вариант был достаточно прост и удобен. Решил я все сделать по событию OnKeyPress. Все вроде бы просто, смотришь, что было уже написано, определяешь, где находится курсор, вставляешь туда символ который нажали. Полученный текст прогоняешь процедурой val(s,a,r), где s - наша получившаяся строка, а число которое процедура смогла выцепить и r - номер символа на котором процедура споткнулась. И если либо a не удовлетворяет условию, либо r больше нуля присваиваешь переменной Key #0
Все работало удивительно, за исключением маленькой проблемки. Нельзя было стереть лишние символы. Но это просто решалось добавлением условия, что вести обработку только тех символов, которые больше  равны пробела. Но счастье длилось не долго.  Я забыл про такую комбинацию клавиш как ctrl+V, которая вставляла  в поле все, что хотела, хоть войну и мир.

Делать нечего. Надо думать над вторым вариантом. И вторым вариантом стала обработка события OnChange. У этого события есть один недостаток. Оно ничего не возвращает, то есть не говорит что нового появилось и не помнит что было. Вот Вам мол что есть с этим и работайте, раньше точно было другое. Это проблема устраняется вводом новой переменной, которая бы запоминала предыдущее состояние поля. Я взял эту переменную типа real. Ну а дальше опять же val
Но как оказалось и тут промашка. При попытке ввести отрицательные значения например и нажатии двух минусов подряд, значение в поле сбрасывает в предыдущее реальное значение, то есть 0, хотя вроде как предыдущим-то должно быть "-". Такая же бодяга и с точками. Выход из этой ситуации сделать переменную предыдущего статуса текстового типа, но мне данный вариант не понравился. Либо оставлять VAL еще и на событии OnKeyPress. Что мне тоже не понраву, так как если много полей и для каждого свои условия, то исходный код программы разрастается ужасно много.

В общем время потеряно. А проблема осталась. Но в принципе-то работать можно. Студенты со нормальной длиной носа лишнего ничего не введут, а вот длинноносым будет хуже при сдаче лабораторной ;)

P.S. Вот как-то так:
var s:string;
r:integer;
a:real;
begin
  begin
    s:=(Sender as Tedit).Text;
    if (s<>'') then
    begin
     val(s,a,r);
     if (r>0)or(a<0)or(a>=2000)or(length((Sender as tedit).Text)>5) then 
begin 
(Sender as Tedit).Text:=floattostr(L);
(Sender as Tedit).SelStart:=length((Sender as Tedit).Text);
end else l:=a;
    end
    else L:=0;
  end;
end;


Первый пост.

Вот он, первый пост. Как всегда ни о чем. :) Но зато дальше наверно пойдёт интереснее.

По планам блог не будет иметь особой тематики. Тут будут писать все кто-то хочет из тех кто называл себя членом "Nabla Group". Возможно потом изменим, поудаляем... А пока жизнь, смерть, философия, компы, новости и прочее, прочее, прочее... всё в одной куче.