To check if a BLOB field has a value, you call its HASVALUE function. For example: IF Item.Picture.HASVALUE THEN;
In older versions, earlier than NAV 2009, you had to call CALCFIELDS before you could check HASVALUE, which – if you think of it, did not make much sense. This was changed in NAV 2009, so ever since that version you can check HASVALUE before you decide to call CALCFIELDS first. It makes all the sense – you don’t need to pull up to 2GB of data over just to see if anything is inside.
If you are an old-school guy (or just old, as me), and you CALCFIELDS first, HASVALUE next, maybe it’s time for you to reconsider it.
Rembember – the pattern is: IF Field.HASVALUE THEN Rec.CALCFIELDS(Field);
Pingback: Do you have a value, Mr. BLOB? – 11/3, Navigate Into Success |
Unfortunately MS doesn’t use this useful change of behavior of HASVALUE. Have a look at the new table 9651 (Custom Report Layout) function UpdateWordLayoutXML@5:
CALCFIELDS(Layout);
IF NOT Layout.HASVALUE THEN
EXIT;
Nice to know! But just to be clear about that: what performance gain do you receive bei checking for value if you get it anyway if it has a value? if its empty, nothing is transfered by calling calcfields, if its not empty its transferred anyway, or am I missing something?
Of course it makes sense if you realy just want to check, lets say on a page to indicate if the record has a value. But in a code routine?
Devch: You have just given the answer. Sometimes, you just want to know if the value is in there (e.g. showing a checkbox in a list page to indicate that a picture is present), and you don’t want to pull all 2 GB of data that each blob might contain, just to do that. In more than 90% situations, though, it doesn’t really matter which way you do it.
This saved me just now in NAV 2015. I was adding a BLOB field to Excel Buffer to be able to read larger texts. The writing worked great, but reading would always fail to return the data. I was doing:
IF NOT “Cell Value as BLOB”.HASVALUE THEN
__CALCFIELDS(“Cell Value as BLOB”);
IF “Cell Value as BLOB”.HASVALUE THEN BEGIN;
__”Cell Value as BLOB”.CREATEINSTREAM(MyInStream);
__IF NOT MyInStream.EOS THEN
____MyInStream.READTEXT(CellValueText);
END;
By moving the CALCFIELDS after the second HASVALUE it worked !
Thanks again.
As always I keep finding my way here.
Glad I helped 🙂 And sorry for being so late with my replies 🙂