Skip to main content

Notifications

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested answer

Pass TempDB between forms

(0) ShareShare
ReportReport
Posted on by 55

Problem

From A has 2 root datasources. One of them is a TempDB datasource. There is a display menuitem pointing to Form B.
Form B has the same 2 root datasources like Form A. Form B should use the TempDB Datasource to enable addtional functionality.
When I open Form B the regular Datasource is transferred correctly, but the TempDB datasource is not and therefore the addtional logic is not enabled.

Current implementation

[DataSource]
class MyTempDBTable
{
    /// 
    /// Init of TempDB Datasource of FormB
    /// 
    public void init()
    {
        super();
        
        FormRunDataHelper callerDataHelper = element.args().caller().dataHelper();
        FormDataSource callerFormDataSource = callerDataHelper.FindDataSource(tableStr(myTempDBTable));                        
        
        //RecID is correctly filled
        RefRecId currentRecid = callerFormDataSource.cursor().RecId;
        if(callerFormDataSource && currentRecid)
        {
            //Add query range
            SysQuery::findOrCreateRange(this.queryBuildDataSource(), fieldNum(myTempDBTable, RecId)).value(SysQuery::value(currentRecid));

            //Copy content of the buffer and link it to the current buffer
            MyTempDBTable myTempDBTableLocal = callerFormDataSource.cursor().data();
            MyTempDBTable.linkPhysicalTableInstance(myTempDBTableLocal);               
        }
    }
}

Runtime error on line MyTempDBTable.linkPhysicalTableInstance(myTempDBTableLocal):
Cannot execute the required database operation. The method is only applicable to TempDB table variables that are not linked to existing physical table instance

Standard code for linkPhysicalTableInstance()

[Form]
public class DMFEntityTemplateDefinitionLoadDialog extends FormRun
{
    private DMFEntityTemplateDefinitionLoad entityTemplateDefinitionLoad;

    public void init()
    {
        super();

        if (this.args() == null
            || !(this.args().caller() is DMFEntityTemplateDefinitionLoad))
        {
            throw error(Error::wrongUseOfFunction(funcName()));
        }

        entityTemplateDefinitionLoad = this.args().caller();

        DMFEntityTemplateDefinitionTmp.linkPhysicalTableInstance(DMFEntityTemplateDefinitionTmp::generateTmpData());
    }
    
    //more code
}

Questions

  1. How do I get the TempDB datasource from Form A and use it as the datasource on Form B without rebuilding the TempDB content (because it is already done for Form A and the record are not disposed)?
  2. Why is linkPhysicalTableInstance thowing this error?
  • BringYourOwnDeveloper Profile Picture
    55 on at
    RE: Pass TempDB between forms
    UPDATE: I made a mistake. In the current implementation I wrongfully assumed it was a TempDB temporary table (legacy code). Instead it was a InMemory table. Cannot execute the required database operation. The method is only applicable to TempDB table variables that are not linked to existing physical table instance error was fixed by these changes:            

    - MyTempDBTable.linkPhysicalTableInstance(myTempDBTableLocal);
      MyTempDBTable.setTmp(callerFormDataSource.cursor());
            

    In order to retain the correct cursor position for temp tables I also ran in a documented breaking change for the deprecated FormDataSource.findRecord(Common _common) (D365 Deprecated APIs).
    My final working implementation was:

    [DataSource]
    class MyTempDBTable
    {
        /// 
        /// Sync caller FormDatasource with this FormDatasource
        /// 
        public void init()
        {
            super();
           
            if(!this.canSyncFormDatasource())
            {
                return;
            }
           
            FormRunDataHelper callerDataHelper = element.args().caller().dataHelper();
            FormDataSource callerFormDataSource = callerDataHelper.FindDataSource(tableStr(MyTempDBTable));                        
            RefRecId currentRecid = callerFormDataSource.cursor().RecId;
            if(callerFormDataSource && currentRecid)
            {       
                //Sync InMemory callerDatasource to this form
                MyTempDBTable.setTmpData(callerFormDataSource.cursor());
                
                //Update ranges
                SysQuery::findOrCreateRange(this.queryBuildDataSource(), fieldNum(MyTempDBTable, RecId)).value(SysQuery::value(currentRecid));
    
                //Set cursor to original caller cursor position
                this.executeQuery();
                element.args().lookupRecord(callerFormDataSource.cursor());
                MyTempDBTable_ds.research(false);
            }
        }
        
        protected boolean canSyncFormDatasource(Args _args = element.args())
        {
            if(!element.args())
            {
                return false;
            }
    
            if(!element.args().caller())
            {
                return false;
            }
    
            if(element.args().callerType() != UtilElementType::Form)
            {
                return false;
            }
    
            if(element.args().callerType() != UtilElementType::Form)
            {
                return false;
            }
    
            if(element.args().callerType() != UtilElementType::Form)
            {
                return false;
            }
    
            return true;
        }
        
        //Additional methods
    }


  • Suggested answer
    GirishS Profile Picture
    27,825 Moderator on at
    RE: Pass TempDB between forms

    Hi,

    Declare the buffer for temp table in the form declaration globally and try the same.

    [Form]
    public class FormName extends FormRun
    {
       MyTempDBTable myTempDBTableLocal 
       [DataSource]
        class MyTempDBTable
        {
            /// 
            /// Init of TempDB Datasource of FormB
            /// 
            public void init()
            {
                super();
            
                FormRunDataHelper callerDataHelper = element.args().caller().dataHelper();
                FormDataSource callerFormDataSource = callerDataHelper.FindDataSource(tableStr(myTempDBTable));                        
            
                //RecID is correctly filled
                RefRecId currentRecid = callerFormDataSource.cursor().RecId;
                if(callerFormDataSource && currentRecid)
                {
                    //Add query range
                    SysQuery::findOrCreateRange(this.queryBuildDataSource(), fieldNum(myTempDBTable, RecId)).value(SysQuery::value(currentRecid));
    
                    //Copy content of the buffer and link it to the current buffer
                    myTempDBTableLocal = callerFormDataSource.cursor().data();
                    MyTempDBTable.linkPhysicalTableInstance(myTempDBTableLocal);               
                }
            }
        } 
    }

    Thanks,

    Girish S,

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

🌸 Community Spring Festival 2025 Challenge 🌸

WIN Power Platform Community Conference 2025 tickets!

Jonas ”Jones” Melgaard – Community Spotlight

We are honored to recognize Jonas "Jones" Melgaard as our April 2025…

Kudos to the March Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 294,033 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 232,854 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,158 Moderator

Leaderboard

Product updates

Dynamics 365 release plans