Wednesday, April 01, 2026

Overconfident AI gets it wrong again

I wrote1 a few days ago: I would also like to define metadata for the database. For example, if a report uses the field 'name' from the table 'customers' then automatically that field should have the title 'customer name' (in Hebrew) Similarly, 'surname' and 'forename' from table 'people' or 'name' from table 'therapists'. The fact that I want the title in Hebrew is incidental; even in English, the default name for customers.name is 'name', not 'customer name'. I put this to CoPilot who replied that this would be very easy to do: it requires a dictionary that translates between table names and Hebrew titles, and that the source for the dictionary would be a property of each field called 'origin'. The origin propery of a field containing a customer name would be CUSTOMERS.NAME.

I left this idea for a few days while I concentrated on list boxes, but yesterday I returned to continue work on this idea. I linked the 'find dictionary entry' procedure to a simple report and saw ... that it didn't work. The origin of a field CUSTOMERS.NAME was simply NAME and of course I have to distinguish between customer name, therapist name and activities.name, etc. CoPilot said that the table name didn't appear because the query was very simple and didn't invoke a join. So I looked at a more complicated query and saw that the origin property was empty for half of the fields! Only fields from the base table (ie the table after the keyword FROM) had origins, whereas the rest didn't.

OK, said CoPilot, you need the OriginTabName and OriginColName properties. "These do exist and will compile." Except they don't exist. After several rounds of CoPilot offering names of properties that sound plausible but don't exist, I told CoPilot that we were getting nowhere. CP agreed, saying that FireDAC doesn't expose sufficient metadata in order to provide a solution for what I wanted. Thank you very much. It wouldn't hurt to say once in a while that "I got it wrong".

In the end, I suggested and implemented a much simpler - and unfortunately, less automatic - solution: I created a stringlist and populated it with the Hebrew translations of 'customer name', 'contact name', 'person surname', etc. Each value has a specific number attached to it which is simply the offset within the stringlist: stringlist[1] = 'customer name', etc. In the FDQueries and FDMemTables in my code, I assign one of these values to a field's tag propery and then do the lookup on this property. In the extremely complicated form for sending an email, upon which I worked, at one stage it is necessary to display a list of therapists. Instead of having to title each field manually, I simply marked the tags as 56 and 58 and got the displaylabels that I wanted.

In conclusion: there are some things that CoPilot is good at, like seeing that a datasource was not enabled2, or for building an ancestral dual list box dialog3. But for more creative solutions, CP is not particularly good and is even frequently wrong. And it still maintains that "This is reliable, simple, and works with all your existing forms". Yeah, right (the one time that two positives make a negative).

I've been so wrapped up in all this chat coding for the last few days that I didn't notice that this is blog #2100! The next blog will contain the traditional look at the previous 100 blogs.

Internal links
[1] 2097
[2] 2094
[3] 2099



This day in blog history:

Blog #Date TitleTags
138401/04/2021You and your action research projectDBA
191801/04/2025Is this me or a double?Personal

Tuesday, March 31, 2026

More about dual list boxes

After a minimal amount of research, I discovered that the dual listbox is regarded as a very good solution when one wants to select and organise options. I did some work with CoPilot on the subject last night; most of the time went on creating an ancestral form for the dual listbox dialog and a small amount of time working on a form that inherits from the ancestor. This morning I spent some time improving the visual aspects of the form and fixing a few bugs that had crept in (mainly misnaming errors).

Above is pictured an example of the form when it is populated with data. Just to make things slightly more difficult, it is of course drawn right-to-left. Until now, if I was feeling adventurous, I would place a bevel around a listbox or grid, slightly improving the appearance, but it struck me that it would be better to use a coloured panel and place the listbox on top of the panel - that's what gives the blue frame surrounding both list boxes. 

The form that inherits from the ancestor now contains about twenty lines of text - and that's all! The only things that differ between various descendant forms are their captions and the specific queries for loading the list boxes and saving the changes.

type TAddXtraRateActs = class(TDualListBox) private public procedure Execute (anxtra: longint; const aname: string); end; implementation {$R *.dfm} uses managedm; Procedure TAddXtraRateActs.Execute (anxtra: longint; const aname: string); begin dm.ProgLog (178); LeftID:= anxtra; caption:= ' הוספת פעילויות לבונוס עבור ' + aname; qDistList.sql.text:= 'select activities.name, activities.id ' + 'from activities inner join xtrarateact ' + 'on activities.id = xtrarateact.act ' + 'where xtrarateact.xtra = :LeftID'; qSrchList.sql.text:= 'select activities.id, activities.name ' + 'from activities where not exists ' + '(select 1 from xtrarateact ' + 'where xtrarateact.act = activities.id ' + 'and xtrarateact.xtra = :LeftID)'; qInsert.sql.text:= 'insert into xtrarateact (xtra, act) ' + 'values (:LeftID, :RightID)'; qDelete.sql.text:= 'delete from xtrarateact where xtra = :LeftID ' + 'and act = :RightID'; Initialise; // load the lists only after there is valid SQL in the queries showmodal end;

That's it! Converting existing forms to this new format is a bit awkward but not difficult. It is important during the change-over to guard the sql statements from being lost, although I do have backups in the form of the original non-unicode program.



This day in blog history:

Blog #Date TitleTags
12331/03/2008Lots of things to doProgramming, Psychology, Van der Graaf Generator, Ian Rankin, Dog, DVD, Brian Viner, Management exams
34431/03/2011Intellectual stimulation and frustrationERP, MBA, HRM, Dan Ariely
46731/03/2012Sequencing "Darkness" / 2MIDI, Van der Graaf Generator, Home recording
81931/03/2015New mobile computerComputers