Multi Update for the selected records in Form clicked

Hi, I have a requirement where i need to update the Product receipt date for all the records selected in PurchEditlines form at once, while posting product receipt.

I would appreciate assistance in coding a solution that allows me to retrieve only the selected records and update their receipt dates upon a button click. Could you please provide guidance or code snippets to achieve this efficiently? Thank you."

Here is the code snippet i have used

[FormControlEventHandler(formControlStr(PurchEditLines, SetReceiptDate), FormControlEventType::Clicked)]
public static void SetReceiptDate_OnClicked(FormControl sender, FormControlEventArgs e)
{

    Dialog dialog = new Dialog("Set Receipt Date");
   
    DialogField dateField = dialog.addField(extendedTypeStr(TransDate), "Product receipt date");
    dateField.label("Product receipt date");

    
    DialogButton dialogResult = dialog.run();
  
    utcdatetime selectedDate;

    if (dialogResult == DialogButton::Ok)
    {
        
       
        // Update the field for the selected orders 

        
        info("Update to the field value %1", DateTimeUtil::toStr(selectedDate));
    }
    
}

You can use MultiSelectionHelper class to iterate selected records.

By the way, this may be a good scenario for drop dialog.

Hi Martin,
I tried with these code but its not working , can you please help?

utcdatetime selectedDate;

            if (dialogResult == DialogButton::Yes)
            {
                selectedDate = dateField.value();
               
                MultiSelectionHelper selectionHelper = MultiSelectionHelper::construct();
                selectionHelper.parmDataSource(mainDataSource);

                Common purchParmTable = selectionHelper.getFirst();

                while (purchParmTable.RecId)
                {
                   
                    purchParmTable.fieldSet(fieldNum(PurchParmTable, DocumentDate), selectedDate);
                  
                    purchParmTable.update();
                    info("Updated record with receipt date " + DateTimeUtil::toStr(selectedDate));

                    purchParmTable = selectionHelper.getNext();
                }                  
                sender.formRun().dataSource().reread();

I’m sorry, but I have no solution for “its not working”, because it can mean anything. What is the actual problem? What did you find when you debugged your code, before giving up and asking here?

Also, please show us all the relevant code. For example, you’re using mainDataSource variable but you neither showed us nor explained what value you put there.

Hi Martin,
My apologies for any confusion caused by my previous comments.
To recap, the solution involves enabling the “multiSelect” property and incorporating a code snippet within the onclicked event handler. This code efficiently iterates through the selected records, updating the relevant field based on the user’s input.

[FormControlEventHandler(formControlStr(PurchEditLines, SetReceiptDate), FormControlEventType::Clicked)]
public static void SetReceiptDate_OnClicked(FormControl sender, FormControlEventArgs e)
{
Dialog dialog = new Dialog(“Set Receipt Date”);

    DialogField dateField = dialog.addField(extendedTypeStr(TransDate), "Product receipt date");
    dateField.label("Update receipt date");        
    DialogButton dialogResult = dialog.run();
   
    utcdatetime selectedDate;
    if (dialogResult == DialogButton::Yes)
    {
        selectedDate = dateField.value();

        // Get the PurchParmTable table buffer
        PurchParmTable purchParmTable;
        FormRun form = sender.formRun();
        FormDataSource PurchParmTable_ds = form.dataSource(FormDataSourceStr(PurchEditLines,PurchParmTable)) as FormDataSource;
       
        if (PurchParmTable_ds && PurchParmTable_ds.recordsMarked().lastIndex() > 0)
        {
            // Get the array of selected records
            Array markedRecords = PurchParmTable_ds.recordsMarked();
            
            // Iterate through selected records
            ttsbegin;
            for (int i = 1; i <= markedRecords.lastIndex(); i++)
            {
                // Get the PurchParmTable buffer for the current selected record
                purchParmTable = PurchParmTable_ds.cursor();

                if (purchParmTable)
                {
                    PurchParmTable_ds.object(fieldNum(PurchParmTable, DocumentDate)).setValue(selectedDate);                        
                }
                PurchParmTable_ds.executeQuery();
            }
            ttscommit;
        }
        else
        {
            warning("Please select the records.");
        }
    }
    else
    {          
        info("Update cancelled");
    }
}

I would greatly appreciate your time in reviewing this solution. Also if you have any insights or suggestions regarding potential improvements or alternative approaches, please do let me know

You didn’t mention any problem, so I guess it’s working for you.

I would follow my suggestion to use MultiSelectionHelper class.
I would use purchParmTable.DocumentDate = selectedDate (and update the record) instead of PurchParmTable_ds.object(fieldNum(PurchParmTable, DocumentDate)).setValue(selectedDate).
I wonder if your code ever saves the change.
The type of selectedDate variable is wrong. You want date, not utcDateTime.
Calling executeQuery() for each record is a bug, IMHO.

1 Like

Hi Martin,

I’m encountering issues when updating multiple records in Dynamics 365 Finance and Operations. I need assistance with the code to reliably select and update multiple records in Dynamics 365 Finance and Operations. The current implementation occasionally updates only a subset of the selected records. Could you provide guidance on improving the code for selecting and updating multiple records?

I think I did - please see my previous reply.

Even after modifying the code as you suggested, I’m facing the same issue.
I see there is issue with the loop.
The loop is selecting the same record again and again. Can you please guide me on this?

Please show me your current code.

[FormControlEventHandler(formControlStr(PurchEditLines, SetReceiptDate), FormControlEventType::Clicked)]
public static void SetReceiptDate_OnClicked(FormControl sender, FormControlEventArgs e)
{
    // Display a dialog asking the user to enter a date
    Dialog dialog = new Dialog("Set Receipt Date");

    // Add a date field to the dialog
    DialogField dateField = dialog.addField(extendedTypeStr(TransDate), "Product receipt date");
    dateField.label("Product receipt date");

    // Show the dialog with OK and Cancel buttons
    DialogButton dialogResult = dialog.run();

    // Declare a variable to store the selected date
    date selectedDate;

    // Check if the user clicked 'OK'
    if (dialogResult == DialogButton::Yes)
    {
        selectedDate = dateField.value();

        // Get the PurchParmTable table buffer
        PurchParmTable purchParmTable;
        FormRun form = sender.formRun();
        FormDataSource PurchParmTable_ds = form.dataSource(FormDataSourceStr(PurchEditLines,PurchParmTable)) as FormDataSource;

        // Check if the main datasource is valid and has selected records
        if (PurchParmTable_ds && PurchParmTable_ds.recordsMarked().lastIndex() > 0)
        {
            // Get the array of selected records
            Array markedRecords = PurchParmTable_ds.recordsMarked();
            
            // Iterate through selected records
            ttsbegin;
            for (int i = 1; i <= markedRecords.lastIndex(); i++)
            {
                // Get the PurchParmTable buffer for the current selected record
                purchParmTable = PurchParmTable_ds.cursor();

                if (purchParmTable)
                {
                    purchParmTable.DocumentDate = selectedDate;
		purchParmTable.update();                       
                }
                
            }
            ttscommit;

        }
        else
        {
            warning("Please select the records.");
        }
    }
    else
    {
        // User clicked 'Cancel', display cancellation message
        info("Update cancelled");
    }
}

Here is my current code,

Am trying to update all these 3 records at once, by selecting all. But document date is not getting updated.

Let me suggest for the third time: use MultiSelectionHelper class to iterate selected records.

I did tried using MultiSelectionHelper, But this updates only a subset of the selected records.

[FormControlEventHandler(formControlStr(PurchEditLines, SetReceiptDate), FormControlEventType::Clicked)]
public static void SetReceiptDate_OnClicked(FormControl sender, FormControlEventArgs e)
{
    // Display a dialog asking the user to enter a date
    Dialog dialog = new Dialog("Set Receipt Date");

    // Add a date field to the dialog
    DialogField dateField = dialog.addField(extendedTypeStr(TransDate), "Product receipt date");
    dateField.label("Product receipt date");

    // Show the dialog with OK and Cancel buttons
    DialogButton dialogResult = dialog.run();

    // Declare a variable to store the selected date
    date selectedDate;

    // Check if the user clicked 'OK'
    if (dialogResult == DialogButton::Yes)
    {
        selectedDate = dateField.value();

        // Get the PurchParmTable table buffer
        PurchParmTable purchParmTable;
        FormRun form = sender.formRun();
        FormDataSource PurchParmTable_ds = form.dataSource(FormDataSourceStr(PurchEditLines, PurchParmTable)) as FormDataSource;

        // Check if the main datasource is valid and has selected records
        if (PurchParmTable_ds && PurchParmTable_ds.recordsMarked().lastIndex() > 0)
        {

            MultiSelectionHelper selectionHelper = MultiSelectionHelper::construct();                
            selectionHelper.parmDatasource(PurchParmTable_ds);

            // Get the first selected record
            purchParmTable = selectionHelper.getFirst();

            // Iterate through selected records using MultiSelectionHelper
            while (purchParmTable)
            {
                // Update the PurchParmTable buffer with the selected date
                purchParmTable.DocumentDate = selectedDate;                   
                purchParmTable.update();

                // Move to the next selected record
                purchParmTable = selectionHelper.getNext();
            }
        }
        else
        {
            warning("Please select the records.");
        }
    }
    else
    {
        // User clicked 'Cancel', display cancellation message
        info("Update cancelled");
    }
}

Let me split the dialog handling and the data update to two methods, so we can focus on the relevant thing more easily. Let me also remove recordsMarked() and use purely MultiSelectionHelper.

[FormControlEventHandler(formControlStr(PurchEditLines, SetReceiptDate), FormControlEventType::Clicked)]
public static void setReceiptDate_OnClicked(FormControl sender, FormControlEventArgs e)
{
    // Display a dialog asking the user to enter a date
    Dialog dialog = new Dialog("Set Receipt Date");

    // Add a date field to the dialog
    DialogField dateField = dialog.addField(extendedTypeStr(TransDate), "Product receipt date");
    dateField.label("Product receipt date");

    // Show the dialog with OK and Cancel buttons
    DialogButton dialogResult = dialog.run();

    // Check if the user clicked 'OK'
    if (dialogResult == DialogButton::Yes)
    {
        YourClass::setDocumentDate(
            dateField.value(),
            sender.formRun().dataSource(formDataSourceStr(PurchEditLines, PurchParmTable)));
    }
    else
    {
        // User clicked 'Cancel', display cancellation message
        info("Update cancelled");
    }
}

private static void setDocumentDate(date _documentDate, FormDataSource _purchParmTable_ds)
{
    MultiSelectionHelper selectionHelper = MultiSelectionHelper::construct();                
    selectionHelper.parmDatasource(_purchParmTable_ds);
    boolean recordSelected;

    while (purchParmTable)
    {
        recordSelected = true;
        purchParmTable.DocumentDate = _documentDate;                   
        if (purchParmTable.validateWrite())
        {
            purchParmTable.update();
        }

        purchParmTable = selectionHelper.getNext();
    }

    if (!recordSelected)
    {
        warning("Please select the records.");
    }
}

Please try it and if you see a problem, please tell us what happened when you debugged the code and how you selected the records. So far, you showed us a screenshot with a single record selected.

1 Like

After debugging the current code, I observed that the iteration is occurring three times, corresponding to the three lines in the form. In each iteration, the input date is being assigned to the document date. However, upon execution, only the last record seems to be updated.

I think the code does its job, you just need to load the updated data to the form. For example, call _purchParmTable_ds.research().

1 Like

Thank you so much for your time and support!
I’m able to see the values now.