Delphi create letters with for loop

796 views Asked by At

As you know in Excel column names are letters. When it reaches Z it continues with AA-AB-AC. Is it possible to make a similar function in Delphi XE7 + for loop?

I've tried:

var
i:integer;
str:string;
begin
str:='a';
for i := 0 to 26-1 do
begin
inc (str,1);
memo1.Lines.Add(str);
end;

but it returned:

[dcc32 Error] FBarkodsuzIndesignVerisiOlustur.pas(249): E2064 Left side cannot be assigned to

I assume that's because str is not an integer.

I can convert numbers to letters with this function:

function numberToString(number: Integer): String;
begin
    Result := '';
    if (number < 1) or (number > 26) then
        Exit;

    Result := 'abcdefghijklmnopqrstuvwxyz'[number];
end;

But I have no idea how we can create letters like AA when it exceeds 26.

Also with below approach, it creates 26 letters just fine but when it exceeds 26 it starts to use characters like brackets:

  for i := 0 to 27-1 do
  begin
   memo1.Lines.Add(Char(Ord('a') + i));
  end;

Output of it:

a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{

when it reach to Z it'll continue as "AA" "BB" "CC" and so on like Excel creates column names.

1

There are 1 answers

6
David Heffernan On BEST ANSWER

This is the function that I use for the task.

function SpreadSheetColName(const Col: Integer): string;
var
  c: Char;
begin
  Assert(Col >= 0);
  if Col<26 then begin
    c := 'A';
    Inc(c, Col);
    Result := c;
  end else begin
    Result := SpreadSheetColName(Col div 26 - 1) + SpreadSheetColName(Col mod 26);
  end;
end;

Note that it uses zero based indices. I would suggest that you also use zero based indices as a general rule throughout your programming.

If you can't bring yourself to do that, then a one based version would look like this:

function SpreadSheetColName(const Col: Integer): string;

  function SpreadSheetColNameZeroBased(const Col: Integer): string;
  var
    c: Char;
  begin
    Assert(Col >= 0);
    if Col<26 then begin
      c := 'A';
      Inc(c, Col);
      Result := c;
    end else begin
      Result := SpreadSheetColNameZeroBased(Col div 26 - 1) + SpreadSheetColNameZeroBased(Col mod 26);
    end;
  end;

begin
  Result := SpreadSheetColNameZeroBased(Col - 1);
end;