"This runs a script to refresh the 2 portals to the Timesheets TO's, but it doesn't actually help."
It would probably help to know what that script actually does.
Presently all the script does is call Refresh Object twice, each one with the name of the appropriate portal. I put this script in in lieu of Refresh Window, as something may be needed to refresh the cached data in the portals.
I *think* this isn't working because the proper Clients record isn't becoming the active record in Clients, and therefore the relationships to the Timesheet tables is not properly updating.
Very likely. If you have multiple clients per agency, then all timesheets for all clients associated with that agency will be shown in the portal, no matter how many refreshes you execute. This is because of the way the relationships work; if you follow your Relationships Graph, there's an implied found set or filtering that goes on from Agencies -> Clients -> Timesheets. Just clicking a row in a portal does nothing to change that. What you're going to need to do is filter the portals based on just the client you want to see.
One way to do this is to create a global Client ID field and point that to a new set of TOs for billed and unbilled timesheets (using constants in the Agencies table to make up the filtering criteria). Another way would be a set of filtered portals that uses the filters to display just the billed / unbilled records, as needed. The key is, you have to grab the desired Client ID, stick it into the global field, and then refresh the window to make this work.
Bruce may have a slicker method.
That was indeed the issue. I didn't realize that the relationship basically carried with it an implied found set of all agencies. I modified the client ID field in the AGENCY table to be global, then modified the filter for both portals to add a match to the global field in the agency table. In the script that fires when I click on the clients portal, I put a step that sets the client ID field in the AGENCY table to the value of the client ID from the CLIENT table. Now all works properly. I didn't need to create new portals after all. I did need to add a refresh window script step with flush cached join results to force the portals to refresh.