Options

Recref between companies

KTA8KTA8 Member Posts: 394
I'm using recref to copy data between companies not copying the key because I want that to be perform by the insert in the destination company but it looks like the insert it's working in the current company

Best Answer

Answers

  • Options
    Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    CHANGECOMPANY function works only in context of the rec variable it's been called on.

    If you do somerec.CHANGECOMPANY(somecompany) and then somerec.INSERT then somerec content will be inserted into somecompany. But if you call somerec.INSERT(TRUE) then all the code excecuted in OnInsert trigger will run in context of current company.
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • Options
    KTA8KTA8 Member Posts: 394
    CHANGECOMPANY function works only in context of the rec variable it's been called on.

    If you do somerec.CHANGECOMPANY(somecompany) and then somerec.INSERT then somerec content will be inserted into somecompany. But if you call somerec.INSERT(TRUE) then all the code excecuted in OnInsert trigger will run in context of current company.

    RecordRef doesn't have that function, at least in 2015 version
  • Options
    Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    In RecordRef you can specify company in OPEN function. But my answer is not about or specific to CHANGECOMPANY function, but gives you insight about generic NAV behaviour when you change company on a record variable.
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • Options
    KTA8KTA8 Member Posts: 394
    In RecordRef you can specify company in OPEN function. But my answer is not about or specific to CHANGECOMPANY function, but gives you insight about generic NAV behaviour when you change company on a record variable.

    I'm using open fuction but the insert use the from company insted the destination company.

    I've somenthing like this:


    RecRefOld.OPEN(IDTabla,FALSE,OldCompany);
    FldRefOld:=RecRefOld.FIELD(ID);
    FldRefOld.SETFILTER(Filter);
    IF (RecRefOld.FINDFIRST) THEN BEGIN
    RecRefNew.OPEN(IDTable,FALSE,NewCompany);

    IDKeyNew:=RecRefNew.CURRENTKEYINDEX();
    KeyRefNew:=RecRefNew.KEYINDEX(IDKeyNew);
    FldRefNew:=KeyRefNew.FIELDINDEX(1);

    Field.RESET;
    Field.SETRANGE(TableNo,RecRefOld.NUMBER);
    Field.SETRANGE(Enabled,TRUE);
    Field.SETRANGE(Class,Field.Class::Normal);
    Field.SETFILTER(Type,'<>%1',Field.Type::BLOB);
    IF Field.FINDSET THEN BEGIN
    REPEAT
    IF NOT (Field."No."=FldRefNew.NUMBER) THEN BEGIN
    FldRefNew := RecRefNew.FIELD(Field."No.");
    FldRefOld := RecRefOld.FIELD(Field."No.");
    FldRefNew.VALUE := FldRefOld.VALUE;
    END;
    UNTIL Field.NEXT = 0;
    END;

    RecRefNew.INSERT(TRUE);
    RecRefNew.CLOSE();
    END;

  • Options
    KTA8KTA8 Member Posts: 394
    The following line:
    RecRefNew.INSERT(TRUE);
    
    is, or can be the problem.

    As I've said the data in your RecRefNew will go to the NewCompany, but any code executed in OnInsert trigger will run in context of current company.

    For example, if a code in OnInsert triggre accesses any other table to update a field in a RecRefNew before insergin it this code will pickup the data from current company, not from the NewCompany.

    This is how it works. If you working with cross-company data no triggers should be called.

    Thanks, I didn't find that restriction anywhere. So, I guess that I would have to find a abstract way to interact with seriesmanagement.
  • Options
    Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    The workaround someone proposed in another thread regarding exactly the same problem was to use webservices.
    Convert your record to a XML (of JSON) form, make NAV to call itself with prepared data. Call the webservice in destination company, in call handling code convert your XML/JSON param back to a 'record' form, and then you can use INSERT(TRUE) as it would run in the context of company called.
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • Options
    GabMemGabMem Member Posts: 2
    If you don't want to publish a webservice for this, with newer versions (>=2013) it's possibile to use STARTSESSION in a different company or a SCHEDULED TASK (>=2017) with immediate execution in the other company.
  • Options
    JohnHunterJohnHunter Member Posts: 45
    GabMem is right:

    CREATETASK(CodeunitId, FailureCodeunitId[, IsReady][, Company][, NotBefore][, RecordID])

    Takes CompanyID as parameter.
  • Options
    Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    and how do you pass a record to be inserted in the CREATETASK call?
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • Options
    JohnHunterJohnHunter Member Posts: 45
    edited 2018-01-20
    CodeunitId - its yours custom CodeUnit, do whatever you like.. pass single record, buffer, store in separate table, catch them through ChangeLogMgt etc.

    i would do similar to InterCompany Postings, Outbox/Inbox, then TaskSend which runs through all Outbox records and sends to Destination Company and creates TaskReceive for all InboxRecords.
  • Options
    Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    So how do you pass the record to be inserted into your custom codeunit?
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • Options
    JohnHunterJohnHunter Member Posts: 45
    [RecordID] if that`s what you mean, but sounds its not "one record", but a repetitive Set.

    1. create outbox records.
    2. create TASK to send them all in one go to destination companies Inbox.
    3. within 2 create tasks (per. each company involved) to receive all Inbox records in destination company and do whatever you need to do with them Insert(TRUE) etc.
Sign In or Register to comment.