Solved

Advice on updating all rows in a grid after a change is made to a field in that grid

  • 8 April 2022
  • 6 replies
  • 771 views

Userlevel 6
Badge +3

My goal is to update the Percent field to be the calculated value based on the weight divided by the total of all weights.  So, if I change the weight on line one to 3, I want the percent for both lines to be updated to 50%.

I’m just looking for a general approach to do this.  The only way I would know to do it is to use the field updated event or the row updated event to trigger a call to cycle through all the records, get the total weight, then cycle through the records again and update the percent field on it.

Any suggestions greatly appreciated.

icon

Best answer by Dmitrii Naumov 11 April 2022, 21:38

View original

6 replies

Userlevel 7
Badge +5

Hi @joe21 

 

I think using RowUpdated in that case is indeed the way to go. 

I don’t see any other option. 

 

P.S. Please don’t use FieldUpdated for that purpose. In the FieldUpdated event you should only update fields of the same record but never fields of other records. 

Userlevel 6
Badge +3

I was able to use the rowselected event to cycle through the lines in the grid and show the percentages that were updated.

The issue is that the isdirty is not being set to true for the rows other than the current row I am updating in the rowselected handler.

I setup my own _isDirty property so that the code will only fire when someone updates the Weight field in the grid.  The FieldUpdated handler sets the _isDirty flag to true so that the percentages get recalculated.

Please don’t confuse MY _isDirty with the IsDirty on the actual row.  I guess my property name might be confusing to someone reading my code.

  protected void _(Events.RowSelected<ICAllocationAccounts> e)
        {

            if (_isDirty == false) return;

            ICAllocationAccounts row = e.Row;

            if (row.AccountSubID != null && row.BranchID != null)
            {
                int totalWeight = 0;
                //int weight = 0;
                int itemCount = 0;
                int itemCounter = 1;
                decimal percentRemaining = 100;

                foreach (ICAllocationAccounts item in AllocationAccounts.Select())
                {
                    if (item.Weight != null)
                    {
                        totalWeight += (int)item.Weight;
                        itemCount++;
                    }
                }

                foreach (ICAllocationAccounts item in AllocationAccounts.Select())
                {
                    if (itemCounter == itemCount)
                    {
                        item.Percent = percentRemaining;
                    }
                    else
                    {
                        item.Percent = Math.Round((decimal)((decimal)item.Weight / (decimal)totalWeight * 100), 2);
                        percentRemaining -= (decimal)item.Percent;
                        itemCounter++;
                    }
                }

            }

            AllocationAccounts.View.RequestRefresh();
            _isDirty = false;
        }
 

Starting here:

If I change the Weight on the 3rd row to 1, it redisplays the percentages correctly.

But when I save only the last row is actually updated to the DB.

Any ideas on how I can force the entire grid to be saved when someone presses the Save button?  Right now, only the row that is updated gets saved.

Userlevel 7
Badge +5

@joe21  I don’t really understand why you need to do it in RowSelected. 

Your initial idea about RowUpdated was good. 

RowSelected solution actually is much worse because it’s probably more performance heavy, and because you now have to do dirty tricks with IsDirty.

 

I’d really not recommend doing it in rowSelected

Userlevel 6
Badge +3

I changed to the RowUpdated handler.  I can see that this is the better option.  However, I still cannot find a way to change the isdirty flag on the rows that are being changed.  It changes the display value in the View/grid but the two other rows are not being seen as changed.  I’m thinking maybe I just delete the rows and re-add them?  Seems like there must be a better way than doing that (if I can even do that).  I’m going to see if I can do that rather than update them.  

Userlevel 7
Badge +5

What you need is Cache.MarkUpdated(row) after you made the change

Userlevel 6
Badge +3

Thank you @Dmitrii Naumov!  I knew it was something simple.  One more brick in my Acumatica foundation of knowledge!  :-)

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved