Monday, June 21, 2021

Neat hack - but is it useful? (Management program)

Over the past few years, I have slowly been moving reports in the OP's management program from a simple SQL query with maybe one or two parameters (sometimes with a list of customers or therapists on one side and the required data for the chosen customer/therapist, and sometimes via two dates) to a more dynamic form, in which a form/screen/window has what Delphi calls a pagecontrol with two tabs (as shown in the picture on the left), where one tab has a form with various parameters and the other tab shows the result of the query. I see now that I wrote about this eight (!) years ago so I won't go into too many details here.

I see also that I posted the code that shows how the parameters are added, but not the basic query, which for the above form would be

select therapists.name, interviews.curdate, interviews.score, people.forename, people.surname, coalesce (people.origzehut, people.zehut) as origzehut, dockets.id, ranks.name as rname, people.id as pid from interviews inner join therapists on therapists.id = interviews.therapist inner join people on people.id = interviews.pid inner join dockets on dockets.id = people.docket left join ranks on dockets.recommendation = ranks.id where 1 = 1

The parameters are added after the 'where 1 = 1' line, such as 'and therapists.id = :p1'. When I remember, I try to add a similar parameter tab to every new report.

Last Friday we were talking about adding more fields to a different report when suddenly I thought to myself that it would be a neat hack to add saved queries to the parameter tab. The idea is very simple: let's say that I've filled in the parameters for a query (e.g. select all the interviews held during 2020 that had a score of 5 - that's three fields) and I want to repeat this query at some point in the future, maybe choosing a different therapist (I don't have a way of choosing two or three therapists; it's either one or all). I want to save this query so that I can restore it again with minimal effort. Obviously (or not), the parameters stay on the screen until one exits the screen, so repeated queries with different therapists don't require new input (apart from choosing the therapist). But should one close the screen or run the query on another day, the values must be chosen again. Saved queries allows one to restore the parameter values.

This is less a technological problem (how to save the values and later restore them) and more a user interface problem: the user must be able to save, restore, update and delete queries, preferably whilst seeing the saved parameter values.

After thinking about this for about an hour or more, I came to the conclusion that the requirements would be a list box (showing the names of the saved queries), a button allowing one to save the values (that's the '+' button on the right hand side underneath the list box), a button allowing one to update the values (that's the middle button) and one button to delete saved queries (the '-' button on the left). Restoring/choosing a query is done simply by double clicking on the query name.

Pressing the '+' button brings up a dialog box in which one gives a name for the query, and then the parameter values (those that are not default, e.g. empty) are saved. My original data design had a 'savedquery' table consisting of an id, program number and query name, along with a son table with a pointer to the father id, the tab order of the field being saved and the value of the field being saved. During testing, I belatedly realised that the management program is multi-user, and so I added a field for the user to the 'savedquery' table. This way, two users can have different saved queries for the same screen with the same name, but with different values, and each user will get the values that she saved, and not those of another user.

I originally developed the necessary code as part of my example screen; once it was finished, I considered how to make the code more generic so that I don't have to write it again. Certain parts have to be modified per screen (saving and restoring the value of a given parameter) but no small amount is generic. I think about 60-65% of the code is generic and 35% specific.

Whilst writing this blog and looking at the code, I have just realised how I can make the entire saving and restoring procedures totally generic. Hurray!

I have my suspicions that no one is going to use this feature, but I enjoyed the technical challenge of writing it!

No comments: