Introduction
Because this post https://andreilungu.com/read-write-text-from-to-blob-field-nav/ is one of the most read posts from my blog, I decided to write about how to read/write data from/to multiple blob fields in a generic way (without duplicating code).
Functional description
For example, I used this when I had 2 BLOB fields in a setup table where I needed to store some tokens used for an API integration. The tokens were very long, exceeding the 250 max. characters of a Nav Text field.
The values of the two fields are displayed and written into the table by using following actions:
And the actions are defined like this in the development environment:
When using actions, values from BLOB are displayed in a page. When changing value in this page and close the page, the new value is stored in the BLOB field:
Techical solution
Of course, we could copy the logic used in the post I mentioned at the beginning, but duplicating code is not good practice. So, let’s see how we can read/write data from/to multiple blob fields in a generic way using Record References in NAV:
Code behind the 2 actions:
ViewUpdateToken - OnAction() ViewAndUpdateToken(FIELDNO(Token)); FIND; CALCFIELDS(Token); TokenExists := Token.HASVALUE; CurrPage.UPDATE(FALSE); ViewUpdateRefreshToken - OnAction() ViewAndUpdateToken(FIELDNO("Refresh Token")); FIND; CALCFIELDS("Refresh Token"); RefreshTokenExists := "Refresh Token".HASVALUE; CurrPage.UPDATE(FALSE); LOCAL ViewAndUpdateToken(FieldNo : Integer) MyText := ReadTokenFromBLOB(FieldNo); InputLongTextTest.SetText(MyText); IF InputLongTextTest.RUNMODAL = ACTION::OK THEN BEGIN NewText := InputLongTextTest.GetText; IF NewText <> MyText THEN //write value to BLOB field WriteTokenToBLOB(FieldNo,NewText); END;
Code in Setup table:
–> For Writing the long text into the BLOB field:
WriteTokenToBLOB(FieldNo : Integer;NewText : Text) RecRef.GETTABLE(Rec); FieldRef := RecRef.FIELD(FieldNo); FieldRef.CALCFIELD; TempBlob.INIT; FieldRef.VALUE := TempBlob.Blob; //clear token IF NewText <> '' THEN BEGIN TempBlob.Blob.CREATEOUTSTREAM(OutStr); BinaryWriter := BinaryWriter.BinaryWriter(OutStr,Encoding.UTF8); BinaryWriter.Write(NewText); BinaryWriter.Close; FieldRef.VALUE := TempBlob.Blob; END; RecRef.MODIFY;
Variables:
Name |
DataType |
Subtype |
FieldRef |
FieldRef |
|
RecRef |
RecordRef |
|
TempBlob |
Record |
TempBlob |
BinaryWriter |
DotNet |
System.IO.BinaryWriter.’mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ |
OutStr |
OutStream |
|
Encoding |
DotNet |
System.Text.Encoding.’mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ |
EmptyTempBlob |
Record |
TempBlob |
–> For Reading the long text from the BLOB field:
ReadTokenFromBLOB(FieldNo : Integer) : Text RecRef.GETTABLE(Rec); FieldRef := RecRef.FIELD(FieldNo); FieldRef.CALCFIELD; TempBlob.INIT; TempBlob.Blob := FieldRef.VALUE; IF NOT TempBlob.Blob.HASVALUE THEN EXIT(''); TempBlob.Blob.CREATEINSTREAM(InStr); BinaryReader := BinaryReader.BinaryReader(InStr,Encoding.UTF8); IF NOT ISNULL(BinaryReader) THEN BEGIN //read value from BLOB field IF BinaryReader.BaseStream.Length > 0 THEN TokenText := BinaryReader.ReadString; BinaryReader.Close; END; EXIT(TokenText);
Variables:
Name |
DataType |
Subtype |
InStr |
InStream |
|
BinaryReader |
DotNet |
System.IO.BinaryReader.’mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ |
Encoding |
DotNet |
System.Text.Encoding.’mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ |
FieldRef |
FieldRef |
|
TokenText |
Text |
|
RecRef |
RecordRef |
|
TempBlob |
Record |
TempBlob |
Code in page that displays the long text.
SetText(pMyText : Text) MyText := pMyText; GetText() : Text EXIT(MyText);
Conclusion
Hope this example helps you understand how you can read/write data from/to multiple blob fields in a generic way.