AppSheet

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.