Today I will write about something that I meant to include in the previous
post but forgot: when does one need a TFDMemTable (hereinafter, TMT)? After
all, one can define a TFDQuery, include an SQL query to retrieve data from
the database, connect the query to a datasource and thence to a grid: the
data will be displayed. Also, in a simple 'edit' form, there's no need for a
TMT.
I have identified two cases when a TMT is required:
-
If the grid that displays the data has an OnTitleClick event - this
allows the user to sort the data.
-
If the form allows the addition or deletion of data.
According to CoPilot, a TFDQuery doesn't have indexes whereas a TMT does. So
when I migrate units with a grid, I first check to see whether the grid has
an OnTitleClick event; if so, I know that I need to a TMT. Incidentally,
there is a new flag that has to be set in the grid's options - OnTitleClick.
This flag didn't exist in Delphi 7, and I came across it in one of the first
units that I migrated. I was clicking on the title bar but the event did not
fire ... because this new flag was not set.
If the grid does not have an OnTitleClick event, I check whether the form
has a qGetOne query - this means that data has to be added - or a qDelete
query. In the case of qGetOne, previously I used to iterate over the fields
of the query and add them one by one to the clientdataset. A TMT has a new
method, AppendRecord, that allows for the data to be added in one statement
(never mind that beneath the hood, the data is still being added field by
field). I have used this everywhere, apart from one or two special cases
where AppendRecord seemed not to be appropriate.
The TMT comes 'naked' without fields. Here is my methodology for adding
them (this may not be optimal). First I check that the query can be opened -
it frequently happens that fields are defined automatically as ftString when
they should be defined as ftWideString. So I fix all these before I even
start with the TMT. When the query is defined properly, I open the
'fielddefs' property of the TMT and begin to add fields. The size of the
fields is very important when the field in the query is a ftWideString; the
default size is 20 but this should be changed to match the size of the
query's field. When all the fields have been defined in the 'fielddefs'
property, I then open the TMT's fields editor. This will be empty so I press
on 'add all fields' and the fields that I added in the 'fielddefs' property
now become persistent fields. I then iterate over the fields in the query,
copying their displaynames to the TMT's fields, and finally I delete all the
persistent fields of the query. I do this in order to highlight any use in
the code of these persistent fields - it has happened that I received
bizarre results when debugging and I discovered that these came from usage
of the query's persistent fields. As the grid displays data coming from the
TMT and not the query, progressing through the TMT gives different data in
the persistent fields, whereas the query's persistent fields stay the
same.
I wrote about changing column widths in a grid and saving them. I came
across a very interesting problem with this: every form has a minimum width
that is hard coded. I changed the column widths of one grid so much that the
new width was less than the minimum width; as a result, there was a huge
space on the left hand side of the grid before data appeared. How could I
fix this? I made two additions: I converted the procedure that saves the
column widths into a function that returns the total width with an extra 72
pixels for the scroll bar. I then wrote a procedure in the ancestor form
that saves this new width. When the form is opened, this new width is
compared to the minimum width, and if it is less, then the minimum width
becomes this new width. Slightly messy but it works. Part of the problem is
that the code for saving and restoring column widths is in a different unit
from the ancestor form. Maybe I should move this code to the ancestor form -
but not every form descends from this ancestor and maybe I would want to
save column widths on such a form (unlikely).
This day in blog history: