Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Работа с формулами [D7, IB6.x]


yaric ©   (2004-09-13 18:26:00) 

Народ помогите пожалуйста советом.

У меня табличка 2 поля field1,field2

Значение поля field1 просто вводит пользователь.
А field2 нужно расчитывать по формулам field2=f(field1)
Причем пользователь должен сам вводить необходимы ему
формулы для разных записей(формулы простейшие +,-,*,/,(,)).
Причем там могут присутствовать еще и переменные.

Вообщем я тут подумал и выделил следующие проблемы:
1)Синтакситческий анализ формулы(можна избежать
 если использовать какой-нибуть построитель-конструктор формул)

2)Выполнение ее на сервере для того чтобы посмотреть
 все записи с посчитанными значениями в field2
 field1   f1(field1)
 field1   f2(field1)
 ..............
 field2   fn(field1)

Там я слышал что в Firebird 1.5 Макроподстановки
появились Execute statement, или через вычисляемые поля
ну вобщем с чего начинать?


yaric   (2004-09-16 11:54:00) [1]

Я тут еще почитал про макроподстановки в Firebird 1.5 вот что у меня получилось. Привожу текст хранимой процедуры:

create procedure new_procedure
returns (
   ret_value decimal(16,2),
   ret_value2 decimal(16,2))
as
declare variable table_name varchar(100);
declare variable fields_name varchar(100);
declare variable field2 decimal(16,2);
declare variable field1 decimal(16,2);
declare variable id varchar(100);
declare variable f varchar(100);
begin
for select test_table.f,
           test_table.id,
           test_table.field2,
           test_table.field1
      from test_table
      into :f,:id,:field2,:field1
        do
     begin
          table_name='test_table where id='||id;
          fields_name='field1,'||f;

              for execute statement
              ' select '||fields_name||' from '|| table_name  into :ret_value,:ret_value2
              do suspend;

       end
end

Талица test_table имеет вид

id      field1             f  
   1       100               field1*3
   2       100               FIELD1/0.75)+15+(FIELD1/100)*11
   3       100               FIELD1/2

При в выполнении процедуры имеем:
id      field1             field2  
  1       100                300
  2       100                159.33
  3       100                50

Что скажете?


yaric   (2004-09-16 11:41:00) [2]

>>Deniz

Спасибо за ссылку, я посмотрел очень класные компоненты
но они подразумевают расчет по формулам на клиенте. Я боюсь
что при большом количестве записей будет притормаживать.
Ведь нужно сначала забрать с сервера весь набор данных с полем в
которых будут записаны формулы, потом пройтись по этому набору и просчитать вызвать Evaluate для каждо записи и только потом показівать пользователю. Хотя у нас отпадает проблема парсинга формул Fast Script это делает сам.

Однако хочется все же на серваке.


Deniz   (2004-09-16 07:30:00) [3]

Механизм Computed by придумывать не надо, просто в тригере before insert or update вызвать UDF и поставить в field2 полученное значение + можно воспользоваться компонентом FastScript
http://www.fastreport.ru/ru/products/products.php?BID=5
советую скачать демку и посмотреть что там и как.


Zacho   (2004-09-15 18:09:00) [4]

yaric   (15.09.04 17:22) [4]
Например, с помощью UDF. А в неё хоть парсер встраивай и передавай формулу строкой.
Хотя, imho, подобное всё-таки лучше делать на клиенте.


yaric   (2004-09-15 17:22:00) [5]

Да идея с таблицей мне нравиться. Обязательноей воспользуюсь.

А как пересчет формул реализовать на сервера, а не на клиенте.
По сути нужно придумать механизм Computed by но только в этом случае для  каждой записи теоретически может быть своя формула


Sergey13   (2004-09-15 10:33:00) [6]

Если количество формул конечно и они повторяются, то может стОит завести некую табличку формул и хранить ссылку на нее? Дальше в процедуре брать формулу и посчитав (например динамическим SQL) возвращать результат.


yaric   (2004-09-15 10:24:00) [7]

>>сергей1
Спасибо.

Вопрос: может кто-то встречал такой компонент который бы реализовывал функции конструктора формул. Киньте плиз линк.
Заранее спасибо.


сергей1   (2004-09-14 19:27:00) [8]

про IB c макроподстановками не знаю, но сталкивались мы уже с такой проблемой, осознали очень полезную вещь :

не надо давать пользователям самим забивать формулу, уверяю тебя, там обязательно будут появляться левые символы, знаки и черт знает что еще. И дело не ограничится только ошибками ввода, например, кто-нибудь обязательно попробует забить что-нибудь типа s^2, а потом спросит, почему вылетает ошибка, а в квадрат не возводится (ведь в екселе все работает !).

в данном случае лучше сделать именно конструктор. Т.е. поставить несколько пимп со значками +,-,* и т.д. (лучше в отдельной форме, если этих кнопок будет много), а получающеюся формулу выводить в label. И никакого синтаксического анализатора не потребуется.

>Причем там могут присутствовать еще и переменные.
а это вы, батенька, уже загнули

а сам резалт сет в dbgrid'e нужен ? типа этого :

form1.ADOQuery1.SQL.Text:='select field1, field1 '+ quotedstr(znak)+form1.edit1.text+ ' as result from table1';
form1.ADOQuery1.Open;

здесь имеется ввиду, что оператор в формуле прочитан в переменную znak, а число, с которым будем работать находится в edit1 (только в сам еdit впихать проверку на правильность ввода).


Наверх

Титульная страница Поиск, карта сайта Написать письмо