Tuesday, 26 September 2017

pointing the record to the current record(positionToRecord)

public void executeQuery()
        {
            qbrLoad.value(loadId);
            super();
            if (detailUnmatched)
            {
                element.args().lookupRecord(TMSFreightBillDetail::find(detailUnmatched.FreightBillRecId));
                tmsFreightBillDetail_ds.research(false);
            }
        }


it will give infinite loop.


try like below :

if (detailUnmatched)
{
    tmsFreightBillDetail_ds.positionToRecord(TMSFreightBillDetail::find(detailUnmatched.FreightBillRecId));
}

http://happydev/Teams/Client/Pages/Code%20Migration%20-%20FindRecord%20FindValue.docx



Code Migration – findRecord and findValue methods on FormDataSource




Overview


The findRecord(Common record) method finds a specific record in the data source and makes it the current record.

The findValue(FieldId field, str value) method find a specific value in a specific field in the data source and makes the corresponding record the current record. It uses the findRecord method for this.

The problem with these methods is that they use linear searching. This causes a large number of records to be loaded in memory and impacts performance.

Replacement APIs – positionToRecord and positionToRecordByValue


The framework team has made available replacement APIs for the findRecord and findValue methods. The new APIs have the same signature as the old APIs to ensure easy migration but work differently under the covers. Also note that while we expect these to cover most cases there are limitations (details below).

·         public boolean positionToRecord(Common _record)

Replacement for: public boolean findRecord(Common _record)



·         public boolean positionToRecordByValue(FieldId _field, str _value)

Replacement for: public boolean findValue(FieldId _field, str _value)

Details and Limitations of replacement APIs


The new APIs first try and look for the record in the cache. This part works without any restrictions on the underlying data sources. However if the record cannot be found in the cache the APIs will try to use positioning as long as the underlying data sources support it.

Some cases where positioning and therefore the APIs do not work are:

                     When a View is being used as a data source

                     When a Temp Table is being used as a data source

                     When a Union Query is being used

                     If firstOnly is being used

                     If an Order By does not exist

                     If all data sources (QueryBuildDataSource) are set as enabled = false

To keep things simple we have designed the API to always throw an exception when the underlying data source does not support positioning, even if the record is in the cache.



Migration


                     A fixer is being written by the Client team to replace all calls in supported scenarios to new APIs.

o   3650174: FindRecord/FindValue - Create upgrade rule/fixer

o   3650176: FindRecord/FindValue - Run upgrade rule/fixer

                     Application teams need to manually investigate and migrate the occurrences remaining after the fixer has been run.

                     Application teams will also need to migrate any findRecord and findValue override methods.

                     For cases where the new APIs do not work you could try using

o    element.args().lookupRecord(recordToFind) Followed by

o    FormDataSource.research(false);

FormDataSource is the data source that contains the record you want to find. Passing in a “false” argument to research causes it to not retain the current position since we want to change the position to the record we found using args.lookupRecord. It also avoids resetting sort order, ranges, etc.



Old Migration Notes from Application Teams


Note: These notes pre-date the introduction of the positionToRecord and positionToRecordByValue APIs and are kept here for reference only. You should try and use positionToRecord and positionToRecordByValue first. If that does not work for your scenario you could try one of the solutions listed here to see if it helps.

Pattern
Explanation
Solution
Lookup form
The form tries to find the record that the caller supplied via args.record()
Set args.lookupRecord() when opening the form.
Tmp = current.data();
DS.ExecuteQuery();
DS.FindRecord(tmp);


An action is triggered that updates/adds/removes multiple records other than the active record, and the form needs to be refreshed to show the new set of records while retaining position
Call DS.research(true)

The true argument tells the framework to retain current position.
An action is triggered that updates/adds/removes multiple records in a linked datasource, and the form needs to be refreshed to show the new set of records while retaining position.
Call research() on the linked datasource instead of main datasource. Consider research(true) if position should be retained in the linked datasource as well.
Tmp = current.data();
DS.research();
DS.FindRecord(tmp);
To refresh the current record, e.g. from a caller

element.doResearch();
Temporary records
Temporary records are recreated and form needs to find the same (but not identical) record after pointing form at new set of records
To be determined
Loop: FindValue+MarkRecord

To be determined
Using FindRecord() to find a record in root datasource

Element.args().lookupRecord(the record to find);
DS.research(false)

Note that this will cause the pagination to start with this record like in a lookup form, so even if there are only a few records, some of those records may be hidden from the user until the user pages left.
Using FindRecord() to find a record in an active/passive joined datasource
A form has 2 datasources: headerTable and lineTable. FindRecord is used on the lineTable instead of the parent table.

For instance, the ProjInvoiceJournal form supports a special case of lookup, where the form is called from a project transaction. In this case, the ProjInvoiceJournal form will show the invoice in which the transaction was billed, and also move to the specific invoice line that billed the calling transaction.

Another use case is in TrvExpenses. When an employee files an expense report, some expense types, like Hotel, may require an itemization of values. In this case, a table is shown and the user may declare how much was spent on each sub category (Room rate, laundry, internet, ..) per day. An itemization for a long stay may contain 50-100 entries. Each cell has its own RecId. When the user tries to edit/clear a cell value, findValue() is used to move the DS cursor to the desired record for update. Contact: pevezzac

Repro steps:
1.       In USSI
2.       Open Expense management > Common > My expenses > Expense reports
3.       Select the record 000030, Conference and click Expense lines
4.       In the hotel line, click Edit and open the Itemize tab
5.       Change the cell (Daily room rate; Tue, 26, Jan) value to 50
6.       Change the cell (Daily room rate; Tue, 27, Jan) value to 50
7.       Hit Save
Expected: The bottom of the page shows: Itemized cost = 410, Remaining = 40
To be determined. LookupRecord() + research(false) only works on root datasources. A solution is needed for the child datasource scenario.
Using findRecord/findValue for datasource bound to a view.
When the datasource is bound to a view it is losing the ordering on the query when using the lookupRecord/research replacement pattern. 

Need the ability to bind to a view sorted by the natural key of the view, such as a Name field, and then be able to find records without losing the query ordering.

Repro steps:
1.       Click New
2.       Enter the name New in the drop dialog and click Create
Expected:
The list is updated to show the New record and the record is selected in the list.




Additional notes on args.lookupRecord() + research(false) in a non-lookup scenario

 this will cause the pagination to start at the record set in lookup record, which may be confusing if there are multiple records, as the user might have the middle record selected and then afterwards, the top record (the same record) is now selected and a different set of records are in practice shown on the screen.


No comments:

Post a Comment

intercompany PO multiple product receipt by x++

public void processStampICPO(PackingSlipId _deliveryNote,                             Transdate _deliverydate,                             ...