How to Prevent Duplicate Item Entries Inside a Parent-Child Form Relationship in AppSheet?
When building apps in AppSheet, one of the most common challenges in a parent-child form setup is avoiding duplicate entries.
Recently, while creating an Expiry Management System for a Medicine Distributor, I faced this issue.
The setup had a Parent table for overall Expiry records and a Child table called Expiry Details to capture multiple items under each expiry.
The problem was simple:
- Users could accidentally add the same Item multiple times under the same Expiry record.
- This would create confusion during reporting and billing.
- Instead of manually correcting these mistakes later, I wanted to stop the problem at the entry level itself —
both by blocking duplicates and by hiding already selected items from the dropdown itself.
Here’s how I solved it:
Step 1: Understand the Tables
In my case, the structure was:
- Parent Table: Expiry Management
- Child Table: Expiry Details
Key Fields:
- Expiry Id (Linking parent and child)
- Item (The actual item name)
- Other fields like Quantity, Company, Debit Note Quantity, etc.
Step 2: Block Duplicates Using Valid_If
First, to prevent duplicate saving, I added a Valid_If constraint to the [Item] field in the Expiry Details table.
Here’s the formula:
ISBLANK( FILTER( “Expiry Details”, AND( ([Item] = [_THISROW].[Item]), ([Expiry Id] = [_THISROW].[Expiry Id]) ) ) )
What this does:
- It checks if the Item already exists for the current Expiry Id.
- If yes, it blocks saving and shows an error.
- If no, it allows saving.
This ensures that no duplicate entries can be saved accidentally.
Step 3: Hide Already Selected Items From Dropdown
To make the user experience even smoother, I added one more improvement.
Instead of letting the user select a duplicate and then showing an error,
I directly hid the already selected items from the dropdown itself.
Here’s the formula I used in the Valid_If of the Item column:
SELECT( Items[Item Name], NOT( IN( [Item Name], SELECT( Expiry Details[Item], [Expiry Id] = [_THISROW].[Expiry Id] ) ) ) )
What this does:
- It fetches all items from the master Items table.
- It checks if any item has already been selected for the current Expiry Id.
- If yes, it removes that item from the available options.
So, the user can only see and pick from remaining (unselected) items.
Step 4: Points to Remember
- The table names inside SELECT() and FILTER() must match exactly with your actual table names (like Expiry Details, Items).
- Always use [Expiry Id] = [_THISROW].[Expiry Id] to restrict filtering only within the same parent record.
- Make sure Item field and Item Name field are properly related if you are pulling from a master Items table.
Outcome
After these two changes:
- The form only shows available items that haven’t been selected yet.
- The child records under each Expiry remain clean and do not repeat.
In AppSheet, parent-child relationships are very powerful. But without proper control, duplicate entries can easily spoil the data quality.
By combining a Valid_If block and dynamic item hiding, we can make the app not only more accurate but also more user-friendly.