Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
Not applicable

Inside field calculation?

Hi all,

i have a table where one of the field contain claculation formula based on fields of the table

id, field1, field2, calc

1 , 1      , 10    , field1/field2

2 , 2      , 20    , field1*field2

3 , 3      , 30    , field1+field2

Is it possible to resident load this table in script and add new field which is based on calculation of "calc" field?

I've played with evaluate() function but the result is always null.

Thanks!

Stefan

32 Replies
SunilChauhan
Champion
Champion

see the attached file

where i have took the expression in resident table

tab1:
load * inline [
id, field1, field2
1 , 1      , 10   
2 , 2      , 20   
3 , 3      , 30   
4 , 4      , 30   
];


Load *,
if(rowno()=1,field1/field2,
if(rowno()=2,field1*field2,
if(rowno()=3,field1+field2,if(rowno()=4,field1-field2)))) as calc
resident tab1;

drop table tab1;

Sunil Chauhan
Not applicable
Author

Hi Sunil,

thanks for your answer but i'm looking for more general solution (if is possible) because the table in the first post is a sample table and the real data may contain many and different calculations and many fields included.

Thanks!

Stefan

john_duffy
Partner - Creator III
Partner - Creator III

Hi Stefan.

How do you determine which fields are to be used in the calculation and what the calculations is?

In your sample in the first post, what determines that field 1 is divided by field 2 as opposed to multiplied by field 2 or added to field 2 on the first record?

John.

Not applicable
Author

Hi John,

i don't determine nothinng. The "calc" field is a database field and the formula is stored in it.

Regards!

Stefan

swuehl
MVP
MVP

Stefan,

that's an interesting question and I was attempted to say, yes you can do this using evaluate() function.

I remembered I played around with something similar few weeks ago (http://community.qlik.com/message/135222) and I just wanted to adapt that to your requirements. I couldn't make it to work again. Then I noticed I was now using QV10SR3 and I remembered using QV9 from time to time - and surprisingly, my linked demo script just works fine in QV9SR6.

Then I continued working on QV9, trying to integrate your requirements. To my surprise, I couldn't get some assumingly easy expressions like 'field1' to work either, it always return NULL, as you mentioned.

I could access the data for already read in rows by using the peek() method, but this is not what you required. Hm, why this? Is the expression evaluated in a different context where the actual current input row fields are not accessible, like in a global context?

I tried to investigate on this, but couldn't find any information in the help or the forum. Almost all examples are using quite easy expressions where they don't use current input row field values, most of the time examples like '6*8' or something like this.

I then noticed that the problem might be similar to http://community.qlik.com/thread/15247 and the statement Hector made. Not sure about this, I believe it has to do with QV's internal structure (latter issue probably with how and when expressions are (pre-)parsed and evaluated, which I believe will probably not be done on record base).

Then I played around with other functions, trying to evaluate() them on script load, something like:

Table2:

LOAD id, field1, field2, calc,

if(IsNull(evaluate(calc))=-1,'no',evaluate(calc)) as Result;

LOAD * INLINE [

  id, field1, field2, calc

1 , 1      , 10    , field1/field2

2 , 2      , 20    , field1*field2

3 , 3      , 30    , field1+field2

4 , 4      , 40    , date(today())

5 , 5    , 50   , "peek('field1',-1)*peek('field2',-1)"

7 , 7   ,60       , rowno()

8 , 8    , 70   , rowno()*field1

];

and I again noticed differences between QV 9 and 10, not only with the peek() function evaluation, but also with the rowno().

Finally, I was just about giving up, I remembered the "easy ones" using something like

evaluate('8*6')

so what about replacing the field values in the string to evaluate before evaluating?

And in fact, I got this to work for both QV9 and QV10:

Table2:

LOAD id, field1, field2, calc,calc2,

if(IsNull(evaluate(calc2))=-1,'no',evaluate(calc2)) as Result;

LOAD id, field1, field2, calc,

Replace(Replace(calc,'field1',text(field1)),'field2',text(field2)) as calc2;

  LOAD * INLINE [

  id, field1, field2, calc

1 , 1      , 10    , field1/field2

2 , 2      , 20    , field1*field2

3 , 3      , 30    , field1+field2

];

Not sure if this meets your requirement, but I think I am at my wits' end.

Best regards,

another Stefan

Miguel_Angel_Baeyens

Hi Stefan,

What about using a variable with fields as parameters? Is that acceptable given your data model and possible values?

SET fxEval = Evaluate($1 & KeepChar($2, '+-/*') & $3);

LOAD *, $(fxEval(field1, calc, field2)) AS calc2 INLINE [
id, field1, field2, calc
1 , 1      , 10    , field1/field2
2 , 2      , 20    , field1*field2
3 , 3      , 30    , field1+field2
];

Hope that helps.

Miguel Angel Baeyens

BI Consultant

Comex Grupo Ibérica

Not applicable
Author

Thanks Stefan i've ednded with the same situation

Thanks Miguel using your solution actually show some results! But is there any way to adapt the variable to use randon number of fileds?

Thanks!

Stefan

swuehl
MVP
MVP

Stefan,

the replace method will also work with more than two fields and if not every field is used in the calc string (the replace just won't have any effect for that field). So just extend the expression with more replace() functions up to maximum number of fields you need (well, I hope you are not using too many, and honestly I don't know if restrictions apply for too many functions embedded into other functions, just give it a try.

I think replacing the field values is probably more flexible with regard to calc function structure, for example you will have not problems with such 'sqr(field1)' or 'field2 / field1' or 'field1 / (field2 + field1)'.

Hope his helps,

Stefan

rbecher
MVP
MVP

Hi all,

why not store this in an Excel file and load the calc field?

😉

- Ralf

Astrato.io Head of R&D