Adel Khial
Adel Khial

Reputation: 424

How to simplify setting a variable multiple times?

I want to program an SQL query that filters dates, using the contents of a ComboBox, in the latter I want the months in letters, but I have to use numbers for the query, so I used this code:

procedure TAdh_Filter.RadioButton3Click(Sender: TObject);

var Param : integer;

begin
  if ComboBox1.Text = 'January' then begin Param := 1; end
  else if ComboBox1.Text = 'February' then begin Param := 2; end
  else if ComboBox1.Text = 'March' then begin Param := 3; end
  else if ComboBox1.Text = 'April' then begin Param := 4; end
  else if ComboBox1.Text = 'May' then begin Param := 5; end
  else if ComboBox1.Text = 'June' then begin Param := 6; end
  else if ComboBox1.Text = 'July' then begin Param := 7; end
  else if ComboBox1.Text = 'August' then begin Param := 8; end
  else if ComboBox1.Text = 'September' then begin Param := 9; end
  else if ComboBox1.Text = 'October' then begin Param := 10; end
  else if ComboBox1.Text = 'November' then begin Param := 11; end
  else if ComboBox1.Text = 'December' then begin Param := 12; end
end;

I would like to know if it's possible to simplify this.

Upvotes: 1

Views: 195

Answers (3)

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108948

A different solution is the following:

const
  MonthNames: array[1..12] of string = ('januari', 'februari', 'mars',
    'april', 'maj', 'juni', 'juli', 'augusti', 'september', 'oktober',
    'november', 'december');

function MonthToIndex(const MonthName: string): integer;
var
  i: Integer;
begin
  for i := low(MonthNames) to high(MonthNames) do
    if SameText(MonthNames[i], MonthName) then
      Exit(i);
  raise Exception.CreateFmt('Unknown month "%s".', [MonthName]);
end;

The benefit of this over David's is that it is stand-alone in the sense that it doesn't require a TComboBox filled with the strings in the right order.

Notice also that the use of SameText makes the function case-insensitive. For instance, SePtEmBeR will map to 9.

Certainly, in a real application, you might want your month names to be localised, and then this isn't optimal but if that isn't the case, then this solution is pretty neat.

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 612904

You should be using the combo box with the csDropDownList style. That means that only the values that you add to the combo can be selected. In which case you can read the value you need out of ItemIndex.

procedure TAdh_Filter.RadioButton3Click(Sender: TObject);
var 
  Param : integer;
begin
  Param := ComboBox1.ItemIndex + 1;
end;

If you are using any other style of combo box then the user will be able to input invalid months by typing in the combo. It doesn't sound as though that's desirable to you. However, if for some good reason you do not want to use csDropDownList then you will need to convert from month text to index, and include a validity check. If you really do need to do that, then you can simplify matters in comparison to the code in your question by using the code that @bummi provided here: Convert month name to number in Delphi?


Note also that your code runs the risk of failing to set Param. As a piece of general advice I'd suggest that you always include an else clause in an if statement like that, and that your else clause raises an exception. That way you will at least discover if, somehow, the month is not being recognised.

Upvotes: 4

bummi
bummi

Reputation: 27377

 Param := ComboBox1.ItemIndex + 1

Upvotes: 1

Related Questions