I'm trying to search for a specific record in 2Appsheet using a button action in my 1Appsheet.
The button works launching the 2Appsheet with desired View but are shown all existing records in that table and not only the record i've selected, why ?
LINKTOFORM("Name_of_the_view_in_2AppSheet",
"Name_of_the_column_in_2AppSheet", [_THISROW].[ID],
"2nd_AppSheet_Link")
Hi! Have you tried LINKTOAPP()? I take it you want to go to another app.
Yes, i'm trying it but seems it cannot pass a search for a record, or i'm missing something ?
LINKTOAPP("Name_of_the_view_in_2AppSheet",
"Name_of_the_column_in_2AppSheet", [_THISROW].[ID],
"2nd_AppSheet_Link")
I receive this error:
I think, Your issue is that LINKTOFORM() is used to open a form with pre-filled values, not to filter an existing view to show a specific record. That’s why all records are displayed instead of just the one you selected.
To open a specific record in 2AppSheet, you should use LINKTOROW() instead:
LINKTOROW([_THISROW].[ID], "Name_of_the_view_in_2AppSheet", "2nd_AppSheet_Link")
Explanation:
• LINKTOROW([_THISROW].[ID], "Name_of_the_view_in_2AppSheet", "2nd_AppSheet_Link")
• Opens the detail view of the record where [ID] matches _THISROW.[ID] in 2AppSheet.
• "2nd_AppSheet_Link" is the app ID or deep link to 2AppSheet.
If you want to filter a table view instead of opening a single record, you should use LINKTOFILTEREDVIEW():
LINKTOFILTEREDVIEW("Name_of_the_view_in_2AppSheet", "2nd_AppSheet_Link", [ID] = [_THISROW].[ID])
probable solution:
• Use LINKTOROW() for a single record detail view.
• Use LINKTOFILTEREDVIEW() to show only matching records in a table view.
Hi @Gustavo_Eduardo thanks for the reply.
Unfortunately:
LINKTOROW([_THISROW].[ID], "Name_of_the_view_in_2AppSheet", "2nd_AppSheet_Link")
continues to show all the records in my 2Appsheet App.
[_THISROW].[ID] is in effect the ID of my actual record in 1Appsheet.
And it needs to be = to a column (named "TEST") in my 2Appsheet
I should insert something more in the LINKTOROW query ?
LINKTOROW() should work if the ID from 1AppSheet matches exactly with the TEST column in 2AppSheet. However, since it’s still showing all records.
possible issues and solutionS:
1. Ensure “TEST” is the Key Column in 2AppSheet
• LINKTOROW([_THISROW].[ID], "Name_of_the_view_in_2AppSheet", "2nd_AppSheet_Link") works only if TEST is the key column of the table in 2AppSheet.
• check if TEST is set as the key If not, change it to the key column or use LOOKUP() to find the actual key:
LINKTOROW(
LOOKUP([_THISROW].[ID], "Table_in_2AppSheet", "TEST", "KeyColumn"),
"Name_of_the_view_in_2AppSheet",
"2nd_AppSheet_Link"
)
• This finds the actual key value from TEST and uses it to open the correct record.
2. Try Using LINKTOFILTEREDVIEW() Instead
If you still see all records, try filtering them:
LINKTOFILTEREDVIEW(
"Name_of_the_view_in_2AppSheet",
"2nd_AppSheet_Link",
[TEST] = [_THISROW].[ID]
)
• This ensures that only records where TEST = ID are displayed.
Final Solution
• ✅ If TEST is the key → Use LINKTOROW().
• ✅ If TEST is NOT the key → Use LOOKUP() inside LINKTOROW().
• ✅ If still not working → Use LINKTOFILTEREDVIEW().
Hi @Gustavo_Eduardo , thanks.
"TEST" is NOT the key (in my 2Appsheet), so i use both the solutions you've kindly suggested:
1 - Use LOOKUP() inside LINKTOROW().
and also
2 - Use LINKTOFILTEREDVIEW().
Ok, @Steve can you help us?
Just wonder: i should insert somewhere also the name of the sheet of my Appsheet2 Database, or is not necessary ?
I assume you have created a slice with the condition [TEST] = [_THISROW].[ID] and that you are using it in the action:
LINKTOFILTEREDVIEW(
"Name_of_Slice_View_in_2AppSheet",
"2nd_AppSheet_Link",
[TEST] = [_THISROW].[ID]
)
Regarding your question, I believe it is not necessary.
Please try removing "id",
Instead of:
LINKTOFORM("View_Name_in_2AppSheet",
"Column_Name_in_2AppSheet", [_THISROW].[ID],
"Link_2nd_AppSheet")
Try:
LINKTOFORM("View_Name_in_2AppSheet",
"Column_Name_in_2AppSheet", [_THISROW],
"Link_2nd_AppSheet")
Please also check that the application name is entered correctly (although I think you did it right because it doesn't return any errors).
Hi @Gustavo_Eduardo,
done it unfortunately it doesn't work it still open the second App correctly, but show all records.
Ok, at least we have discovered that "it doesn't work" I will be thinking about your possible solution, in the meantime, surely, other users with more knowledge than I have, will be able to respond.
I see that changing "View_Name_in_2AppSheet" it changes the views accordingly (opening correctly the 2App), so the issue is only the inability to show the record selected, it's really odd ... thanks in the meantime for all your help
I was thinking out loud again if creating a slice in application 2 would not be the solution, so that instead of filtering all the records it only filters those that meet a condition, then create a view that, instead of pointing to the entire table, points to the slice.
In the slice i've to insert a variable that should be the ID of my 1Appsheet that was saved in my Column "TEST" of my 2Appsheet ? But how to do "dinamically" ?
@FaCe The column in app 2 is a ref?
try this expression above but if it is a ref please check that the value is a part of this active and that it is set to editable “false”
No, the column "TEST" in app2 where's the ID (of app1) is a text.
And here's the setup:
I've made some progress ...
I see that if the view is a Form_detailed system view this formula works !
LINKTOROW([TEST], "Form_Detail",
"NameoftheApp-00000")
If instead the view is a Table_View it not works and it shows all the records: any idea on how to solve that?
My scenario is that i need to use a single record (in App1) to many (in App2) so i think i should have a table view to see them all, is it correct ?
The other issue is that LOOKUP not works to search from one App1 to App2 ... any help on that too ?
[editing]
, set this as y/n, initial value false.Create an action of type "Data: set the values of some columns in this row"
"TableInApp1"
[editing] = TRUE
"Mark Editing as True"
Create a second action of type "App: go to another app"
LINKTOVIEW("Filtered_View_in_2AppSheet", "2nd_AppSheet_Link")
"Go to App 2"
Now, create a grouped action that includes both actions:
"Test App 2"
"Mark Editing as True"
"Go to App 2"
"TableInApp2"
Row Filter Condition:
[Test] = ANY(
FILTER(
"TableInApp1",
[editing] = TRUE
)
)
We know that the row that is going to be brought is the one we clicked on.Save the Slice
and create a view based on it (Filtered_View_in_2AppSheet
).
[editing]
When Returning[editing] = FALSE
.When the user clicks a button in App 1, the action:
[editing] = TRUE
in App 1.[editing]
is reset to FALSE
.🔹 This should work Try it out and let me know how it goes.
Hi @Gustavo_Eduardo thank you so much for all your time and effort.
I see that the solution is not simple and something you've suggested is not the way i use the app i.e.:
Probably the best solution could be to integrate all my 4 Apps into one (i think i can leave the 4 excel sheets separately and probably in this way what i'd like to do it will be simpler ...)
As said thank you so much i really appreciate all your help
Of course! That is definitely the best option since a system-type application is easier to maintain when all modules are part of a single app. Additionally, in that case, there is no need to replicate the tables for each one (even though you might notice faster synchronization). In reality, maintenance will be astronomical, and your headache will be proportional to it.
Therefore, I suggest merging all your apps into a single one and managing everything from there unless it is absolutely necessary to do otherwise.
Happy developing!
Hi @Gustavo_Eduardo
i'm thinking again at your suggestion, how my 2App detect that is calling a Linktoview from my 1App and that i'm not simply opening my 2App alone ?
[Test] = ANY( FILTER( "TableInApp1", [editing] = TRUE ) )
I'd like to understand well that point and if possible avoiding the editing passage (cause when i'm in my 2App often i don't come back to 1App)
It’s very simple. Let me explain the idea @FaCe
The functionality I’m proposing works as follows:
While in App 1, imagine you tap on a record. The action created changes the editing column (which is of type Y/N) to true and then takes you to App 2.
In your table within App 2, you need to filter the values so that they match a value from the table in App 1—specifically, the value of the record you tapped. This is how you create a slice. This slice selects the values in test that are equal to the ID of the record being edited in App 1.
The view in App 2, where you’re redirected, is a simple table view based on the slice, instead of displaying all values, it only shows the one whose test value matches the record that has true in the editing column in the first table.
Now, you need to go back to App 1. To do this, you must create an action to return. That’s why I mentioned that you need to create a grouped action: first, to set editing to false, and then to navigate back to App 1.
In AppSheet, when launching a specific View from a button, all records from the table will be displayed unless you apply a filter to show only the selected record. The issue might be due to how the deep link is structured.
@Tijesuni have you some example / may you please elaborate a bit if your solution is different from the one shown by Gustavo ?
Did you find it difficult to do what I suggested? Let me know, maybe I can help you step by step.
Hi Gustavo, yes please i need some more help, thank you.
First there's a problem, cause i don't come back from App2 into App1, so what you've suggested seems not to be able to reproduce how i use the 2Apps.
Then i don't understand very well how this slice read the value for searching from tableinapp1:
[Test] = ANY( FILTER( "TableInApp1", [editing] = TRUE ) )
There's no way to pass using LINKTOVIEW (or other functionality) the value [_THISROW].[ID] (that is the ID of my App1Table) to the slice of App2?
I've these values (ID of App1Table) also saved in a column of App2Table so it will be simple to show in a Table view all the records containing this value, isn't it ?
Okay, to better understand what needs to be done, it would be ideal if you describe textually what you want to achieve (forget about formula configurations, views, actions, and bots). Let's start with the basics. Tell me about the user interaction flow, which views the user should go through, what type of views, what the UX/UI you want to achieve would be like.
Once you explain that, we can get to the point and solve the problem step by step.
I've 2Appsheet: AppSheet1 and AppSheet2
In AppSheet2 i've a column (named to simplify: ColumnIDAppsheet1) where i've saved the ID of AppSheet1
It's possibile that there're many records in this column with the same ID of Appsheet1.
Now i'd like using an action from AppSheet1 that takes the value of the record selected in Appsheet1: [_THISROW].[ID]
To show a table view in Appsheet2 filtering by this [_THISROW].[ID]
As said this value is available in AppSheet2: ColumnIDAppsheet1
Hope is clearer now my request, thank you so much
Ok. I'll look into it later. If I have any questions, I'll ask you.
I'm going to explain this step by step, without complications. Basically, what we want is for App 1 to open a view in App 2, but only showing the records that match the ID of the selected row in App 1.
First of all, the tables whose data you want to display in app 1 and app 2 (and any other app) must be present in those apps, i.e. if you want to view the table in app 1 and app 2 make sure to load them in both apps and configure the values in both apps (a lot of unnecessary hard work in my opinion).
The problem is that AppSheet does not allow filtering a view in another app directly. So, we need a small trick to make App 2 "know" which record to display.
To make this work, we need a column that marks which records should be displayed in App 2.
✅ Add a new column called [Editing]
.
✅ Regenerate the table structure in the AppSheet editor.
✅ Set [Editing]
as a Yes/No column with Initial Value = FALSE (so it always starts as "No").
This will act as a switch to determine which records should appear in App 2.
Now, in App 1, we need to create several actions to automate the process.
[Editing] = TRUE
.Create an action in App 1 of type "Execute an action on a set of rows".
This action will update the records in App 2 where the ID matches the selected row.
Use this expression in the action:
FILTER("Table_In_App2", [ColumnApp2_Ref_ID_of_Table1] = [_THISROW].[ID])
Configure this action to set [Editing] = TRUE
for those records in App 2.
Set Action 1 as the action to execute on these rows.
With this, when clicking on the action in App 1, it will set [Editing] = TRUE
in App 2 and open App 2 with the filtered view.
Now that App 1 is sending the correct data, we need to ensure that App 2 filters the records properly.
Create a slice in App 2 that only shows records where [Editing] = TRUE
.
Use this expression in the slice:
[Editing] = TRUE
Create a view based on this slice (it can be a table or another type).
So far, everything should work fine. BUT there’s a problem:
When you leave the filtered view in App 2, the records will still be marked as [Editing] = TRUE
, which could cause errors in future filters.
To fix this:
✅ Create a new action in App 2 that sets [Editing] = FALSE
for all records that are still "TRUE".
✅ Group this action with the one that takes you back to App 1 or another view in App 2.
This way, every time you leave the filtered view, the records will automatically be reset, keeping the system ready for the next query.
✔ App 1 marks which records should be displayed in App 2 using [Editing] = TRUE
.
✔ App 2 filters those records using a slice where [Editing] = TRUE
.
✔ When leaving the view, the records are reset back to [Editing] = FALSE
automatically.
Make the first configuration and then if you have problems with the action to set the records to false let me know and I will help you with that but go doing the first part which is getting your filtered view to be seen. Remember that you can manually edit the database until you have automated the values.
In short, we achieved what you wanted without breaking AppSheet! 🎉
Although, to be honest... this is like scratching your right ear with your left hand. 😆
But hey, it works! 🚀
@Gustavo_Eduardo thank you so much for all your invaluable help step by step i'm going to reproduce it in my app and i'll let you know.
One only doubt: if other users (with the same account in the same time use the App on other Computer executing the action on other records), there's a risk that the various flags on Editing Column go in "confusion" ?
Mmm… To be honest, I think so, because we’re filtering based on a single user, but not multiple users with the same UserEmail().
What we can do is implement it first and then adjust it later.
That being said, I imagine you would have a table of allowed users for each USEREMAIL(). So, I’m thinking of an EnumList-type column that reads the logged-in user at the time of selection, but let’s leave that configuration for “after implementation.”
In this case, I would even open another post after solving this one so that the topics are differentiated and you have separate access for each case and other users also contribute to this.
No we use our Apps in a little Office so access with the same email to the App on multiple different computers at the same time ...
Ok, in that case (thinking out loud and without trying it in any way but giving you an idea) I would add an Enumlist type column in which the active user at that time can be added and in the action where you set editing to true what I would do is add that column to configure. The action would be something like this:
[editing] = true
[userEnumlis] = [_this] + USERNAME()
In this way, the current user name would be added to the current content of the userEnumlist column and this would enable the view for that user because then in the slice I would put an AND()
Instead of [editing] = true, I would use
AND(
[editing] = true,
IN(
USERNAME(),
[userEnumlist]
)
)
Well, it goes without saying that when exiting both editing and the enumeration list they should be reset.
But the truth is that I have not tried it and I don't know if someone with more experience can help us both with this issue. Try it and tell me.
I still think you could add this functionality in case you have several USERNAME() associated with a single USEREMAIL()...
Remember that we created a column called "editing"? Well, you would have to add an enumlist of base type ref in users where you can temporarily store the name of the user who is requesting to go to the view. That way, not only will the user be asked to have the column be editing = true, but also that the username() be that of the active user.
This action is triggered when a user starts editing, adding them to the [activeUsers]
list.
[activeUsers]
UNIQUE([_THISROW_BEFORE].[activeUsers] + LIST([_THISROW].[user]))
Explanation:
✅ [_THISROW_BEFORE].[activeUsers]
→ Retrieves the list of users currently editing.
✅ LIST([_THISROW].[user])
→ Adds the current user.
✅ UNIQUE()
→ Ensures there are no duplicates.
How to trigger it:
This action is triggered after the form is saved, removing the user from [activeUsers]
.
[activeUsers]
UNIQUE([_THISROW].[activeUsers] - LIST([_THISROW].[user]))
Explanation:
✅ [_THISROW].[activeUsers]
→ The updated list after editing.
✅ LIST([_THISROW].[user])
→ The user that needs to be removed.
✅ -
→ Removes the user from the list.
✅ UNIQUE()
→ Ensures no accidental duplicates.
How to trigger it:
If a user enters edit mode and never saves, their name will remain in [activeUsers]
.
A possible solution is to add a [lastEditTimestamp]
column and a scheduled action to remove inactive users after a certain period.
IF(NOW() - [lastEditTimestamp] > "000:10:00", LIST(), [activeUsers])
This would remove users if more than 10 minutes have passed without saving changes.
Don't worry. I'm developing an app where I might have a similar problem (not regarding the table in a second app but regarding the simultaneous use)
We'll find a solution for sure. In the meantime, if you know something, let me know because it would also be useful to me.
User | Count |
---|---|
18 | |
11 | |
7 | |
4 | |
3 |