Options

Transfering BLOBs

MasterOfDragonsMasterOfDragons Member Posts: 18
Hi everybody,

I have to transfer the contents of a BLOB-field into another one, but can't access the record directly, because I don't know, which table will be used, so I'm using RecordRef. How can I do this?

Thanks in advance
Master of Dragons

Comments

  • Options
    Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    I am not sure if this works but you may try to do a calcfields of the FieldRef and copy it to another FieldRef.

    This works with normal Records.
  • Options
    DenSterDenSter Member Posts: 8,304
    If you don't know which table to look in, how can you set the record reference?

    Have you tried just doing direct assignments? I don't know because I have not tried this myself, but I'd start here:
    RecOne.BlobField := RecTwo.BlobField;
    RecOne.MODIFY;
    
    If that doesn't work, you'll probably have to do something with the EXPORT and IMPORT methods of the blob field.
  • Options
    Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    Daniel,

    This is the way to do it via normal records, using calcfields.

    This is about RecordRef and FieldRef.

    :shock:
  • Options
    DenSterDenSter Member Posts: 8,304
    you set the rec ref -> link to a table
    you set the field ref -> link to a field
    you do the logic to get the record -> fieldref has a value

    Now you can access the value, and do assignments with it.
  • Options
    MasterOfDragonsMasterOfDragons Member Posts: 18
    Hi,
    DenSter wrote:
    If you don't know which table to look in, how can you set the record reference?
    instead of 'don't know' I should probably have said 'don't know in advance'. Both, source and destination table, are listed in a third table. From there I use the table no. to assign them to RecRefs.
    DenSter wrote:
    Have you tried just doing direct assignments? I don't know because I have not tried this myself, but I'd start here:
    RecOne.BlobField := RecTwo.BlobField;
    RecOne.MODIFY;
    
    If that doesn't work, you'll probably have to do something with the EXPORT and IMPORT methods of the blob field.
    This is, what I do for non-BLOB-fields:
    BFRef.VALUE(FRef.VALUE());
    
    BFRef is the destination, while FRef is the source. Both are FieldRefs.
    But that doesn't work for BLOBs...
  • Options
    Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    Have you tried the CALCFIELDS thingy?
  • Options
    MasterOfDragonsMasterOfDragons Member Posts: 18
    Have you tried the CALCFIELDS thingy?
    Yes, but unfortunately it doesn't seem to work :cry:
    I keep getting this error (translated (probably badly) by me):
    "A typeconversion of the expression BLOB to a BLOB value is not possible."
  • Options
    Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    In that case I am affraid it is not possible useing RecRef and FieldRef.

    It sounds a bit like a bug or something unforseen by Navision.

    What version are you using?
  • Options
    MasterOfDragonsMasterOfDragons Member Posts: 18
    What version are you using?
    I am using 4.00
  • Options
    Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    Just made a small test with SP1. Still does not work :(

    Looks like this is forgotten.
  • Options
    MasterOfDragonsMasterOfDragons Member Posts: 18
    Well, thanks anyway...
  • Options
    kinekine Member Posts: 12,562
    With using normal record variable I will use CREATEINSTREAM and CREATEOUTSTREAM to use streams to copy the data. Or simple way is EXPORT the value into some temporary file and IMPORT it back to second field...

    But because this functions is not possible to use in FieldRef... You can try assign the value into Variant variable and use IS... functions of this variable to check which type it is... may be it will say ISBINARY and than you will be able to do something.

    And in some cases you can use BFRef := FRef to assign the value of the field... sometime it is not working...
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • Options
    Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    kine wrote:
    With using normal record variable I will use CREATEINSTREAM and CREATEOUTSTREAM to use streams to copy the data. Or simple way is EXPORT the value into some temporary file and IMPORT it back to second field...

    With normal records you can just do an assignment or am I wrong?
    REC.CALCFIELDS(BLOB);
    Rec.BLOB := REc.BLOB2;
    
  • Options
    kinekine Member Posts: 12,562
    I do not know, may be yes... :-)

    But in case that it is not working, I will use the way of the streams or files. I didn't wrote it clearly.

    Thanks
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • Options
    Marije_BrummelMarije_Brummel Member, Moderators Design Patterns Posts: 4,262
    Hmm OK. :D

    Guess more roads lead to Rome. Let's take the touristic route 8)

    Oh boy, it is friday again. :mrgreen:
  • Options
    krikikriki Member, Moderator Posts: 9,096
    Bad news, I tried it with a File, a Variant, and all others I could think of, but without success.

    Without recordreferences it would be like this:
    recEmployee.GET('AH');
    recEmployee.CALCFIELDS(Picture);
    
    recItem.GET('1000');
    recItem.Picture := recEmployee.Picture;
    recItem.MODIFY(FALSE);
    

    With recordreferences, this is the only thing I could find :oops:
    // without records. Transfer a picture from Employee.Picture to Item.Picture
    rerEmployee.OPEN(DATABASE::Employee);
    firEmployee := rerEmployee.FIELD(1); // No.
    firEmployee.VALUE := 'AH';
    rerEmployee.FIND('=');
    firEmployee := rerEmployee.FIELD(19); // Picture
    firEmployee.CALCFIELD;
    
    rerItem.OPEN(DATABASE::Item);
    firItem := rerItem.FIELD(1); // No.
    firItem.VALUE := '1000';
    rerItem.FIND('=');
    
    PutFieldReferenceInBlob(firEmployee,rerItem,92);  // Picture
    rerItem.MODIFY(FALSE);
    
    Function 
    PutFieldReferenceInBlob(VAR IfirFieldreferenceFrom : FieldRef;VAR PrerRecordReferenceTo : RecordRef;IintFieldNoTo : Integer)
    // PutFieldReferenceInBlob
    // Puts a fieldreference that is a blob into a blob that is in a recordreference
    // PARAMETERS:
    //   IfirFieldreferenceFrom : fieldreference that is a BLOB
    //   PrerRecordReferenceTo : record reference in which is a BLOB-field in which the BLOB must be copied
    //   IintFieldNoTo : field ID of the BLOB-field in "PrerRecordReferenceTo" (needed in case there are more BLOB's in a table)
    
    IfirFieldreferenceFrom.CALCFIELD;
    
    CASE PrerRecordReferenceTo.NUMBER OF
      DATABASE::Item: BEGIN
        PrerRecordReferenceTo.SETTABLE(LrecItem);
        LrecItem.Picture := IfirFieldreferenceFrom.VALUE;
        PrerRecordReferenceTo.GETTABLE(LrecItem);
      END;
      DATABASE::Employee: BEGIN
        PrerRecordReferenceTo.SETTABLE(LrecEmployee);
        LrecEmployee.Picture := IfirFieldreferenceFrom.VALUE;
        PrerRecordReferenceTo.GETTABLE(LrecEmployee);
      END;
      ELSE
        ERROR('Function "PutFieldReferenceInBlob": Table %1 not programmed',PrerRecordReferenceTo.NUMBER);
    END;
    
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


  • Options
    tushaar99tushaar99 Member Posts: 35
    has anyone found a solution to this problem
    i am facing da same problem
    :cry:
    Regards,
    Tushaar
  • Options
    krikikriki Member, Moderator Posts: 9,096
    tushaar99 wrote:
    has anyone found a solution to this problem
    i am facing da same problem
    :cry:
    In my previous reply, I have given a solution and I am afraid there isn't another one.
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


  • Options
    qtcMikeqtcMike Member Posts: 1
    Hey guys.. after reading these posts and playing around with code a bit, I determined that getting the blob value out of a field reference is possible, but assigning a blob value into a field reference chokes.

    The code below will copy all values from a source table to a destination table that has a field with the same name as the current field of the source table (like transfer fields but using field names instead of IDs). So, here is how I did it:
      // Get reference to source
      RecRefSource.GETTABLE(SourceRecord);
    
      // Get reference to destination
      RecRefDestination.GETTABLE(DestinationRecord);
    
    
      // Loop through all fields in source table
      FOR i := 1 TO RecRefSource.FIELDCOUNT DO BEGIN
        // Get field reference of the current field in the source table
        FieldRefSource := RecRefSource.FIELDINDEX(i);
        
        // Loop through all fields in destination table
        FOR j := 1 TO RecRefDestination.FIELDCOUNT DO BEGIN
          // Get field reference of the matching field from the destination table
          FieldRefDestination := RecRefDestination.FIELDINDEX(j);
          
          // Do the names match?
          IF FieldRefDestination.NAME = FieldRefSource.NAME THEN BEGIN
            // Special case of blob field
            IF FieldRefSource.NAME = 'Picture' THEN BEGIN
              // Set the new value
              FieldRefSource.CALCFIELD;
              TempDestinationRecord.GET(RecRefDestination.FIELD(1).VALUE, RecRefDestination.FIELD(2).VALUE);
              TempDestinationRecord.Picture := FieldRefSource.VALUE;
              TempDestinationRecord.MODIFY;
            END ELSE
              // Validate in the new value
              FieldRefDestination.VALIDATE(FieldRefSource.VALUE);
    
            // Break loop
            j := RecRefDestination.FIELDCOUNT;
          END;
        END;
      END;
    

    The topical bit of code being:
    // Set the new value
    FieldRefSource.CALCFIELD;
    TempDestinationRecord.GET(RecRefDestination.FIELD(1).VALUE, RecRefDestination.FIELD(2).VALUE);
    TempDestinationRecord.Picture := FieldRefSource.VALUE;
    TempDestinationRecord.MODIFY;
    
  • Options
    Van_ScimanydVan_Scimanyd Member Posts: 8
    Hello,

    It is worth saying that one can do
    BlobFieldRef.VALUE := BlobFieldRef2.VALUE
    
    since NAV 6.0 SP1 (couldn't test on 6.0 but I think it works too)

    May be this could save 5min testing for someone else (and I hope it will account for this holy resurrection o:))
  • Options
    TomigsTomigs Member Posts: 85
    Excellent Van_Scimanyd,
    I just tried it in a NAV2016 database and worked great.

    Thanks very much. That is my code:
    DestinationRecordRef.SETTABLE(NAVSHAddition);
    SourceRecordRef.SETTABLE(CRMSalesOrderSync);
    SourceFieldRef := SourceRecordRef.FIELD(CRMSalesOrderSync.FIELDNO(cdss_specificationdetails));
    
    DestinationFieldRef := DestinationRecordRef.FIELD(NAVSHAddition.FIELDNO(SpecificationDetailsBLOB));
    //Transfer the blob
    DestinationFieldRef.VALUE := SourceFieldRef.VALUE; //**************
    DestinationRecordRef.GETTABLE(NAVSHAddition);
    
Sign In or Register to comment.