На этом шаге мы приведем два примера использования вариантных переменных.
Приведем примеры использования вариантных переменных.
Пример 1. Здесь демонстрируется присваивание одной и той же вариантной переменной VariantVar значений различных типов. При сознании формы
методом TForm1.FormCreate в качестве исходного для VariantVar устанавливается значение строкового типа. А в обработчике события нажатия
на кнопку TForm1.Button1Click поочередно присваиваются значения целого, вещественного, булевского и строкового типов. Обратим внимание на
выражение:
VarType(VariantVar) and varTypeMask
в котором используется стандартная функция VarType и маска varTypeMask. Результатом этого выражения является код типа значения вариантной переменной VariantVar.
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; Label2: TLabel; Edit2: TEdit; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} var VariantVar : Variant; procedure TForm1.FormCreate(Sender: TObject); begin VariantVar:=' Это - строка'; Edit1.Text:=' String'; Edit2.Text:=VariantVar; end; procedure TForm1.Button1Click(Sender: TObject); var S : string; I,J: Word; begin j:= VarType(VariantVar); I := j and varTypeMask; case I of varString: begin {Следующий тип - Integer} VariantVar:=-32767; Edit1.Text:=' Integer'; Str (VariantVar:5:0, S); Edit2.Text:= S; end; varInteger: begin {Следующий тип - Double} VariantVar:=1.7E300; Edit1.Text:=' Double'; Str(VariantVar:16:10, S); Edit2.Text:= S; end; varDouble: begin {Следующий тип - WordBool} VariantVar:=False; Edit1.Text:=' WordBool'; Str(VariantVar:3:0, S); Edit2.Text:= S+' (то есть False)' end; varBoolean: begin {Следующий тип - String} VariantVar:=' Это - строка'; Edit1.Text:=' String'; Edit2.Text:=VariantVar; end; end; end; end.
Текст этого примера можно взять здесь.
Заметим, что при выводе на экран значения вариантной переменной, имеющей текущий булевский тип, в поле редактирования Edit2 появляется не символьное обозначение булевского значения (False, True), a его числовой эквивалент.
То есть, для False выводится константа, равная нулю, а для True - константа, не равная нулю.
Рис.2. Вывод значения переменной логического типа
Пример 2. Здесь показана возможность прямого использования предопределенного типа TVarData, описывающего структуру вариантных переменных,
для выполнения действий, аналогичных приведенных в первом примере. Второй пример будет отличаться от предыдущего только некоторыми операторами в методах
TForm1.FormCreate и TForm1.Button1Click, которые примут следующий вид:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; Label2: TLabel; Edit2: TEdit; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} var VariantVar : Variant; procedure TForm1.FormCreate(Sender: TObject); var AString : AnsiString; begin TVarData(VariantVar).VType:=varString; AString := ' Это - строка'; TVarData(VariantVar).VString:=Pointer(AString); Edit1.Text:=' String'; Edit2.Text:=VariantVar; end; procedure TForm1.Button1Click(Sender: TObject); var S : string; AString : AnsiString; begin case TVarData(VariantVar).VType of varString: begin {Следующий тип - Integer} TVarData(VariantVar).VType:=varInteger; TVarData(VariantVar).VInteger:=-32767; Edit1.Text:=' Integer'; Str (VariantVar:5:0, S); Edit2.Text:= S; end; varInteger: begin {Следующий тип - Double} TVarData(VariantVar).VType:=varDouble; TVarData(VariantVar).VDouble:=1.7E300; Edit1.Text:=' Double'; Str(VariantVar:16:10, S); Edit2.Text:= S; end; varDouble: begin {Следующий тип - WordBool} TVarData(VariantVar).VType:=varBoolean; TVarData(VariantVar).VBoolean:=False; Edit1.Text:=' WordBool'; Str(VariantVar:3:0, S); Edit2.Text:= S+' (то есть False)' end; varBoolean: begin {Следующий тип - String} TVarData(VariantVar).VType:=varString; AString:=' Это - строка'; TVarData(VariantVar).VString:=Pointer(AString); Edit1.Text:=' String'; Edit2.Text:=VariantVar; end; end; end; end.
Текст этого примера можно взять здесь.
Снова обратим внимание на выражение оператора выбора case
TVarData(VariantVar).VType
которое, в отличие от первого примера, берет код типа значения вариантной переменной VariantVar непосредственно из поля VType записи типа TVarData.
Как нетрудно заметить, во втором примере для присваивания вариантной переменной VariantVar значения нового типа в поле VType заносится константа, определяющая тип
нового значения, а в поле записи TVarData, соответствующее новому типу, записывается собственно значение. Например, для типа Double эти операторы имеют такой вид:
TVarData(VariantVar).VType:=varDouble; TVarData(VariantVar).VDouble:=1.7E300;
Кроме того, отметим также особенность присваивания строкового значения прямо в поле VString. Поскольку это поле в типе TVarData описывается как бестиповый указатель Pointer,
то строковую константу приходится сначала записывать в переменную типа AnsiString, который допускает преобразование к типу Pointer:
TVarData(VariantVar).VType:=varString; AString := ' Это - строка'; TVarData(VariantVar) .VString:=Pointer(AString);
При запуске на выполнение проект второго примера работает также, как и первый.
Со следующего шага мы начнем рассматривать операции и выражения.