Hi Jane,
I tested 6 alternatives to find possible solutions, 3 worked (Fields default collation on Table Definition, Overriding Binary Collation, Dictionary field option SELECTNAME), 1 worked with some caveats (PROP:SQLOrder) and 2 doesn’t worked (File and View PROP:NAME)
This is the easiest and (seemingly) safest solution. On external name of each NOCASE field, repeat its name | SELECTNAME=its name COLLATE NOCASE, eg:
LastName | SELECTNAME=LastName COLLATE NOCASE
Setting directly as:
LastName COLLATE NOCASE
causes an error 47 invalid structure when opening the table
(Edit.: And issuing this programatically (Customer{PROP:NAME,fieldno}=‘fieldname COLLATE NOCASE’ after the file is OPEN works for the Browse but fails in the Form for INSERT/UPDATE.
Customer{PROP:NAME,fieldno}='fieldname | SELECTNAME=fieldname COLLATE NOCASE'
like the dictionary field option in this way, this works either before(but in the same thread) and after opening the file. No problems with browse or form.
The SELECTNAME change its name on the PROJECTION (SELECTed column names) and SELECTION (WHERE) and ORDER BY clause. Also on UPDATE queries WHERE clause (edited)
View’s columns PROP:NAME (Browse Box Behavior / SQLAdvanced ) only changes in PROJECTION but not in WHERE/ORDER BY so it doesn’t help.
Regarding PROP:SQLOrder :
-it over complicate things
-has limitations: the string sent is final, it doesn’t work for reverse order (Clarion doesn’t parse the string to insert DESC order by) so it needs to be redefined even when the user changes the scrolling direction:
BRW1.Fetch PROCEDURE(BYTE Direction)
CODE
ResetCount += 1
CurrentOrder = BRW1::View:Browse{PROP:ORDER}
IF SetSqlOrder AND INSTRING(')',BRW1::View:Browse{PROP:ORDER},1,1)
SSCurrentOrder.FromString(BRW1::View:Browse{PROP:ORDER})
SSCurrentOrder.ReplaceInContent('CUS:','A.') !Fixed strings for simplicity
SSCurrentOrder.ReplaceInContent('UPPER(','')
SSCurrentOrder.ReplaceInContent(')',' COLLATE NOCASE ASC ')
IF INSTRING('-',BRW1::View:Browse{PROP:ORDER},1,1) <> 0 XOR Direction <> FillForward
IF INSTRING('ASC',SSCurrentOrder.ToString(),1,1) !this has a simplified logic only to show the idea
SSCurrentOrder.ReplaceInContent(' ASC ,',' DESC *') !it doesn't cover all the combinations, like
SSCurrentOrder.ReplaceInContent(',',' DESC *') !mixed - and + without any UPPER
SSCurrentOrder.ReplaceInContent('*',',')
SSCurrentOrder.ReplaceInContent(' ASC ',' DESC ')
ELSE
SSCurrentOrder.ReplaceInContent(',',' DESC ,')
SSCurrentOrder.Append(' DESC ')
END
END
SSCurrentOrder.ReplaceInContent(' ASC ','')
SSCurrentOrder.ReplaceInContent('+','')
SSCurrentOrder.ReplaceInContent('-','')
BRW1::View:Browse{PROP:SQLORDER} = SSCurrentOrder.ToString()
CurrentSQLOrder = SSCurrentOrder.ToString()
ELSE
BRW1::View:Browse{PROP:SQLORDER} = ''
CurrentSQLOrder = ''
END
PARENT.Fetch(Direction)
-the worst caveat with this approach is that the WHERE clause doesn’t use COLLATE, it is generated as:
SELECT A.GUID, A.CUSTOMERNUMBER, A.COMPANYGUID,FirstName COLLATE NOCASE,LastName COLLATE NOCASE, A.STREET, A.CITY, A.STATE, A.POSTALCODE, A.PHONE, A.MOBILEPHONE, A.EMAIL FROM Customer A WHERE ( A.LASTNAME >= ? ) AND ( ( A.LASTNAME > ? ) OR ( ( A.FIRSTNAME >= ? ) )) ORDER BY A.LASTNAME COLLATE NOCASE,A.FIRSTNAME COLLATE NOCASE
thus causing to repeat records in a loop when scrolling and the highlighted record (currentchoice) sets over a name which location with the other collation is diffent (van de Canten vs Venere)
I attach Carl’s example posted with the dictionary and application changes
TestInvoiceSQLiteCollateNOCASE.zip (255,9 KB)
, and SQLite database with sample content
Invoice.zip (360,4 KB)