After Updating to Delphi 10 Seattle and the corresponding new GridPack I encounter an error with the auto alignment in my grids. It should be easy to reproduce by dropping a TAdvGrid on a Form, enable AutoNumAlign and enable editing.
The FormatSettings.DecimalSeperator is "." on my system. When I type certain numbers/text I get the following alignment:
Text --> Alignment
sssdf --> left
33 --> right
-33 --> right
3,4 --> right
3.4 --> left
-3.4 --> right
-3,4 --> right
The most annoying thing is: For positive values the point is not interpreted as decimal separator. Instead the whole cell is interpreted as text.
Additionally, the comma is interpreted as decimal separator instead, which should not be the case.
Is that a bug in the Grid Pack? Or am I doing something wrong?
Was retested with a default grid on the form initialized with:
Thanks for your quick response! Unfortunately, the error persists with my system config, even if I do exactly the same as you did.
I use now the dynamic approach as workaround:
procedure TForm1.AdvStringGrid1GetAlignment(Sender: TObject; ARow,
ACol: Integer; var HAlign: TAlignment; var VAlign: TVAlignment);
var
myFloat : double;
myInt : integer;
begin
if ( (TryStrToInt(advstringgrid1.Cells[ACol, ARow], myInt)) OR
(TryStrToFloat(advstringgrid1.Cells[ACol, ARow], myFloat)) ) then
HAlign := taRightJustify
else
HAlign := taCenter;
end;
This works fine!
It is unclear why my test code works here and not for you. Are you sure you effectively compile & link with the latest version?
I am quite sure that compiling and linking works well. I digged a bit deeper and found this:
In the function TAdvStringGrid.GetCellAlignment in AdvGrid Unit the IsType function is used (27966):
if IsType(SysUtils.Trim(s)) in [AdvUtil.atNumeric,AdvUtil.atFloat,AdvUtil.atScientific] then
begin
HAlign := taRightJustify;
end;
With s='3.4' the IsType function returns atDate as type. Consequently, I jump to unit AdvUtil where IsType function is defined (I attached a copy of my IsType function at the end of this post).
For reproduction I give you my system variables that are taken at runtime in debug mode from this function:
ThousandSeparator = ','
DecimalSeparator = '.'
DateSeparator = '.'
TimeSeparator = ':'
As far as I can see the problem seems to be that the DateSeparator and DecimalSeparator are both the same. Hence, both booleans isD and isF are true after looping through the string in the first part of the function. And date is always preferred against floats.
Can you reproduce this behaviour? I think it should be possible to use the same sign as decimal and date separator. Thanks!
---------------
My IsType function (v6.3.8.0):
---------------
function IsType(s:string): TAutoType;
var
i: Integer;
isI,isF,isS,isD,isT: Boolean;
th,de,mi,ds,ts,ld,lt: Integer;
isE: boolean;
begin
Result := atString;
if s = '' then Exit;
isI := True;
isF := True;
isS := True;
isE := False;
isD := Pos(DateSeparator,s) > 0;
isT := Pos(TimeSeparator,s) > 0;
th := -1;
ld := -1;
lt := -1;
de := 0;
mi := 0;
ds := 0;
ts := 0;
for i := 1 to Length(s) do
begin
if not CheckSignedNum(s) then
isI := False;
if (s = 'e') or (s = 'E') then
begin
if isE then
isS := false;
isE := true;
end;
// - sign must be first char
if (i > 1) and (s = '-') then
begin
isI := false;
isF := false;
end;
if (i = 1) and ((s = 'e') or (s = 'E')) then
isS := false;
if (i = 1) and not CheckNum(s) then
begin
isT := false;
isD := false;
end;
if (i = length(s)) and ( (s = 'e') or (s = 'E') or (s = '+') or (s = '-') ) then
isS := false;
if not (CheckNum(s) or (s = '-') or (s = ThousandSeparator) or (s = DecimalSeparator) ) then
isF := False;
if not (CheckNum(s) or (s = DateSeparator)) then
isD := False;
if not (CheckNum(s) or (s = TimeSeparator)) then
isT := False;
if not (CheckSignedFloatNum(s) and (s <> ThousandSeparator)) then
isS := False;
if (s = ThousandSeparator) and (i - th < 4) and (th <> -1) then
isF := False;
if (s = ThousandSeparator) then
th := i;
if (s = DateSeparator) then
begin
inc(ds);
if (ds > 2) or (ld = i - 1) then
isD := false;
ld := i;
end;
if (s = TimeSeparator) then
begin
inc(ts);
if (ts > 2) or (lt = i - 1) then
isT := false;
lt := i;
end;
if (s = DecimalSeparator) then
Inc(de);
if (s = '-') then
Inc(mi);
end;
if isI then
Result := atNumeric
else
begin
if isF and not isE then
Result := atFloat;
if isS and isE then
begin
if mi = 2 then
mi := 1;
Result := atScientific;
end;
end;
if isT then
Result := atTime
else
if isD then
Result := atDate
else
if (mi > 1) or (de > 1) then
Result := atString;
end;
We've applied a fix for this exceptional case. Next update will have this fix.