На этом шаге мы приведем два примера использования вариантных переменных.
Приведем примеры использования вариантных переменных.
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. Вывод значения переменной логического типа
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);
При запуске на выполнение проект второго примера работает также, как и первый.
Со следующего шага мы начнем рассматривать операции и выражения.