[X++] TempDB refresh Data on FormDatasource

When using a TempDB as a FormDatasource and populating the data with a populateData method returning a Common i struggled to change the data when the caller changes.

In Dynamics AX it's a normal behavior on journal forms that the lines / details form changes displays the data related to the header record. When both forms are open simultaneously and selecting an other record on the header form, the lines form will refresh and display the related data.

The Scenario

My scenario was the following:

Header form

WMSShipment
Record: WMSShipment

Details form

WMSShipmentBasis
Record: WMSOrderTrans
TempDB: MyTmpDB

First code

In Class

I had a method in a class that looks like this:

public static MyTmpDB populateData(WMSShipmentId _shipmentId)
{
    InventDim                   inventDimSum;
    InventDim                   inventDim;
    WMSOrderTrans               wmsOrderTransSum;
    WMSOrderTrans               wmsOrderTrans;
    MyTmpDB      				myTmpDB;
    // ...

    while select sum(Qty), shipmentId, itemId, inventDimId from wmsOrderTransSum
        join plfInventConContainerId, InventDimId from inventDimSum
        group by wmsOrderTransSum.ItemId, wmsOrderTransSum.ShipmentId, inventDimSum.InventBatchId
        where wmsOrderTransSum.ShipmentId                  == _shipmentId
            && inventDimSum.InventDimId                    == wmsOrderTransSum.InventDimId
            && inventDimSum.InventBatchId
    {
        select firstOnly qty, ItemId, shipmentId, inventDimId from wmsOrderTrans
            join InventBatchId, inventDimId from inventDim
            where wmsOrderTrans.itemId == wmsOrderTransSum.itemId
                && wmsOrderTrans.shipmentId == wmsOrderTransSum.shipmentId
                && inventDim.inventDimId == wmsOrderTrans.inventDimId
                && inventDim.InventBatchId == inventDimSum.InventBatchId;
				
        myTmpDB.InventBatchId        = inventDim.InventBatchId;
        myTmpDB.ItemId               = wmsOrderTrans.ItemId;
		// ...
        myTmpDB.insert();
    }

    return myTmpDB;
}

This method selects needed data, inserts it to the table MyTmpDB and returns the instance with the data.

On Form

With the init method on the form the caller record is beeing stored:

public void init()
{
	// ...
	if (element.args() && element.args().dataset() == tableNum(WMSShipment) && element.args().record().isFormDataSource())
    {
        wmsShipmentCaller_ds = element.args().record().dataSource();
    }
    // ...
    super();
    
}

On the executeQuery method of DataSource WMSOrderTrans I populated the data to my tempDB FormDataSource:

public void executeQuery()
{
	super();
    if (wmsShipmentCaller_ds)
	{
	// Fill tmpDB:
    MyTmpDB.linkPhysicalTableInstance(MyTmpDB::populateData(wmsShipmentCaller_ds.cursor().(fieldNum(WMSShipment, ShipmentId))));
	}
}
Result

So if i open both forms and changed the shipment on the header, the data of WMSOrderTrans got refreshed but the data of my temp table remained the same.

The Problem

Calling linkPhysicalTableInstance a second time showed me an error that it's already linked.

New Code (Solution)

To make it work that way I first changed the method for populating the data to take the common as parameter, delete all records and insert the new ones:

public static void populateData2Buffer(WMSShipmentId _shipmentId, MyTmpDB _buffer)
{
    InventDim                   inventDimSum;
    InventDim                   inventDim;
    WMSOrderTrans               wmsOrderTransSum;
    WMSOrderTrans               wmsOrderTrans;
    
    // only refresh data if shipment changed
    if (_buffer.ShipmentId != _shipmentId)
    {
      delete_from _buffer;

      while select sum(Qty), shipmentId, itemId, inventDimId from wmsOrderTransSum
          join inventBatchId, InventDimId from inventDimSum
          group by wmsOrderTransSum.ItemId, wmsOrderTransSum.ShipmentId, inventDimSum.inventBatchId
          where wmsOrderTransSum.ShipmentId                  == _shipmentId
              && inventDimSum.InventDimId                    == wmsOrderTransSum.InventDimId
              && inventDimSum.inventBatchId        != ''
      {
          select firstOnly qty, ItemId, shipmentId, inventDimId from wmsOrderTrans
              join inventBatchId, inventDimId from inventDim
              where wmsOrderTrans.itemId == wmsOrderTransSum.itemId
                  && wmsOrderTrans.shipmentId == wmsOrderTransSum.shipmentId
                  && inventDim.inventDimId == wmsOrderTrans.inventDimId
                  && inventDim.inventBatchId == inventDimSum.inventBatchId;

          _buffer.inventBatchId        = inventDim.inventBatchId;
          _buffer.ItemId               = wmsOrderTrans.ItemId;
          // ...
          _buffer.insert();
      }
	}
}
On the form

I declared two variables:
For the last RecId to recognize the change
RefRecId lastShipmentRecId;
and for the buffer
MyTmpDB myTmp;

executeQuery:

public void executeQuery()
{
    super();
    if (wmsShipmentCaller_ds)
    {
          MyTmpDB::populateData2Buffer(wmsShipmentCaller_ds.cursor().(fieldNum(WMSShipment, ShipmentId)), myTmp);
          MyTmpDB.linkPhysicalTableInstance(myTmp);
      }
}

linkActive:

public void linkActive()
{
    super();
    MyTmpDB::populateData2Buffer(wmsShipmentCaller_ds.cursor().(fieldNum(WMSShipment, ShipmentId)), myTmp);
}

active:

public int active()
{
	int ret;
    
    ret = super();
    // ...
    MyTmpDB_ds.research();
    return ret;
}

And now the tempDB gets refreshed too when changing the record on the caller form.