Skip to main content
Answer

How to Properly Delete a Selected Row from the Database in Acumatica

  • March 26, 2025
  • 4 replies
  • 173 views

Forum|alt.badge.img

        public SelectFrom<CustomTable01>.View FilterView;

        

        public PXFilter<CustomFilte> Filter;


        public virtual IEnumerable deleteLine(PXAdapter adapter)
        {

    /// Code to retrieve the PXResultset

                    foreach (var CustomTable01Row in CustomTable01Rows)
                    {
                   Method 1 --------- this.FilterView.Delete(CustomTable01Row);
                  

                   Method 2 --------- this.FilterView.Cache.Delete(CustomTable01Row);

                   Method 3 --------- this.FilterView.Delete(CustomTable01Row);

                                               this.Persist();


                   Method 4 --------- this.FilterView.Cache.Delete(CustomTable01Row);

                                               this.Actions.PressSave();
                        
                    }
    }


I created a custom screen with a filter with a results grid. When a user selects a line and presses an action button, I want to delete the selected row from the database. I retrieved the relevant row in the data access component (DAC) and attempted four different deletion methods. Methods 1 and 2 resulted in the row being deleted only from the user interface (UI). Upon screen refresh, the row reappeared. Methods 3 and 4 produced the following error. How can I fix this and delete the selected line form the database? Any detailed instructions, tips, or code snippets would be greatly appreciated. Thank you!

PX.Data.PXLockViolationException

Error: Another process has deleted the 'PTProductionPlanOrderHeaderTable' record. Your changes will be lost.

Best answer by Django

I feel like there’s more code than what we’re seeing. Can you show us all the code that relates to deleteLine?

First question before I go further - is there a reason you’re not using the standard [X] button that the grid view will make available to you?

Moving on, since your deletion logic is designed for a user to click on a row and then click your action button, you don’t need to use the IEnumerable version of the PXAction method. Try changing it to:

public PXAction<CustomTable01> DeleteLine;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Delete Line", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]

protected virtual void deleteLine ()

{

}

This way you’re not needing to do anything with the contents of the adapter which I think might be related to your issue.

 

4 replies

Forum|alt.badge.img+7
  • Captain II
  • March 26, 2025

Method 1 followed up with a call to .Save (or .PressSave) should work.

But you shouldn’t need to be looping through the records. As long as your grid properties are keeping the current row in sync with the dataset you can delete the currently highlighted record.

e.g.

var curRow = FilterView.Current;

this.FilterView.Delete(curRow);

this.Actions.PressSave();

 


Forum|alt.badge.img

Hi ​@Django ,

I tried your code as follows.
            var row = FilterView.Current;
            this.FilterView.Delete(row);
            this.Actions.PressSave();

But still the following error occurs. 
 

PX.Data.PXLockViolationException

Error: Another process has deleted the 'PTProductionPlanOrderHeaderTable' record. Your changes will be lost.


Forum|alt.badge.img+7
  • Captain II
  • Answer
  • March 27, 2025

I feel like there’s more code than what we’re seeing. Can you show us all the code that relates to deleteLine?

First question before I go further - is there a reason you’re not using the standard [X] button that the grid view will make available to you?

Moving on, since your deletion logic is designed for a user to click on a row and then click your action button, you don’t need to use the IEnumerable version of the PXAction method. Try changing it to:

public PXAction<CustomTable01> DeleteLine;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Delete Line", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]

protected virtual void deleteLine ()

{

}

This way you’re not needing to do anything with the contents of the adapter which I think might be related to your issue.

 


harutyungevorgyan
Jr Varsity I
Forum|alt.badge.img+2

Hello ​@RKarunarathne51 ,

I'm not entirely sure about the specifics of your use case, so I can’t say why the standard delete (X) button available on every grid in Acumatica isn't suitable in your case. However, if you're implementing custom logic and relying on the Current row, there's one important detail to keep in mind: ensure that the grid has the SyncPosition property enabled in the ASPX definition.

To verify and enable this:

  1. Open your customization project.

  2. Navigate to the Screens section and select your screen.

  3. Choose the grid you're working with.

  4. In the Layout Properties, find the SyncPosition property and set it to True.

This setting ensures that when a user selects a row in the grid, the corresponding Current record is properly updated in the code-behind, allowing your logic to behave as expected.
 

Regarding the error message:

"Another process has deleted the 'PTProductionPlanOrderHeaderTable' record. Your changes will be lost."

This error typically occurs when attempting to modify or delete a record that has already been updated or removed in the database, resulting in a mismatch between the cached version in memory and the actual record in the database.

Acumatica uses a special field called Tstamp (timestamp) to track the version of a record. The framework checks this field during any update or delete operation to detect whether the record has been changed by another process. If a mismatch is found, Acumatica throws this error to prevent unintentional data loss.

In your case, if SyncPosition is not enabled in the grid configuration, the Current record may not properly update when the user selects a different row. As a result, your code may attempt to delete a stale record — one that has already been removed or modified in the background — leading to this exception triggered by the Tstamp mismatch.

By enabling SyncPosition, you ensure that the Current record in the code-behind always reflects the user's selection in the UI, helping to prevent these types of synchronization errors.

Let me know if you have any questions or need further clarification — I'm happy to help!