2008. március 28., péntek

Find a constant dynamically


Problem/Question/Abstract:

In my application, the user has a form where he is selecting from a list of options. That list of options corresponds to contant values. Is there a way to find the value of a constant when all you have is a string containing its name?

Example:

const
  TEST = 5;
  DELIVERED = 10
    { ... }

sChoice := listboxChoice.Text // -possible values are TEST and DELIVERED
iChoice = {missing method}(sChoice)

iChoice would be assigned the value of the constant of the same name as the user's selection. No, I can't change the declarations to be enumerated types or anything else. They have to be constants. I've seen examples of this sort of thing done for Enumerated types, objects and so on using RTTI. But I can't find an example of constants, and I can't figure it out.

Answer:

Solve 1:

If enumerations are okay (I don't see how you could use names of constants), try this to get mapping of enumeration from string to integer:

{ ... }
type
  TConstValues = (cvTest, cvDelivered);

var
  values = array[TConstValues] of integer = (5, 10);
  strings = array[TConstValues] of string = ('TEST', 'DELIVERED');

  { ... }

function GetConstValue(s: string): integer;
var
  t: TConstValues;
begin
  result := -1;
  for t := low(TConstValues) to high(TConstvalues) do
    if strings[t] = s then
    begin
      result := values[t];
      break;
    end;
end;


Solve 2:

This is a modification of Solve 1:

{ ... }
const
  TCVals: array[TConstValues] of integer = (-1, 5, 10);
  TCStrs: array[TConstValues] of string = ('UNKNOWN', 'TEST', 'DELIVERED');
  { ... }

function GetConstValue(s: string): integer;
var
  t: TConstValues;
begin
  t := high(TConstvalues);
  while (t > low(TConstValues)) and (CompareText(TCStrs[t], s) <> 0) do
    dec(t);
  Result := TCVals[t];
end;

Nincsenek megjegyzések:

Megjegyzés küldése