fields.inc 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. TFields and related components implementations.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {Procedure DumpMem (P : Pointer;Size : Longint);
  13. Var i : longint;
  14. begin
  15. Write ('Memory dump : ');
  16. For I:=0 to Size-1 do
  17. Write (Pbyte(P)[i],' ');
  18. Writeln;
  19. end;}
  20. { ---------------------------------------------------------------------
  21. TFieldDef
  22. ---------------------------------------------------------------------}
  23. Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string;
  24. ADataType: TFieldType; ASize: Word; ARequired: Boolean; AFieldNo: Longint);
  25. begin
  26. Inherited Create(AOwner);
  27. {$ifdef dsdebug }
  28. Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')');
  29. {$endif}
  30. FName:=Aname;
  31. FDisplayName := '';
  32. FDatatype:=ADatatype;
  33. FSize:=ASize;
  34. FRequired:=ARequired;
  35. FPrecision:=-1;
  36. FFieldNo:=AFieldNo;
  37. end;
  38. Destructor TFieldDef.Destroy;
  39. begin
  40. Inherited destroy;
  41. end;
  42. procedure TFieldDef.Assign(APersistent: TPersistent);
  43. var fd: TFieldDef;
  44. begin
  45. fd := nil;
  46. if APersistent is TFieldDef then
  47. fd := APersistent as TFieldDef;
  48. if Assigned(fd) then begin
  49. Collection.BeginUpdate;
  50. try
  51. Name := fd.Name;
  52. DataType := fd.DataType;
  53. Size := fd.Size;
  54. Precision := fd.Precision;
  55. FRequired := fd.Required;
  56. finally
  57. Collection.EndUpdate;
  58. end;
  59. end else
  60. inherited Assign(APersistent);
  61. end;
  62. Function TFieldDef.CreateField(AOwner: TComponent): TField;
  63. Var TheField : TFieldClass;
  64. begin
  65. {$ifdef dsdebug}
  66. Writeln ('Creating field '+FNAME);
  67. {$endif dsdebug}
  68. TheField:=GetFieldClass;
  69. if TheField=Nil then
  70. DatabaseErrorFmt(SUnknownFieldType,[FName]);
  71. Result:=Thefield.Create(AOwner);
  72. Try
  73. Result.Size:=FSize;
  74. Result.Required:=FRequired;
  75. Result.FFieldName:=FName;
  76. Result.FDisplayLabel:=FDisplayName;
  77. Result.FFieldNo:=Self.FieldNo;
  78. Result.SetFieldType(DataType);
  79. Result.FReadOnly:= (faReadOnly in Attributes);
  80. {$ifdef dsdebug}
  81. Writeln ('TFieldDef.CReateField : Trying to set dataset');
  82. {$endif dsdebug}
  83. {$ifdef dsdebug}
  84. Writeln ('TFieldDef.CReateField : Result Fieldno : ',Result.FieldNo,' Self : ',FieldNo);
  85. {$endif dsdebug}
  86. Result.Dataset:=TFieldDefs(Collection).Dataset;
  87. If Result is TFloatField then
  88. TFloatField(Result).Precision:=FPrecision;
  89. except
  90. Result.Free;
  91. Raise;
  92. end;
  93. end;
  94. procedure TFieldDef.SetAttributes(AValue: TFieldAttributes);
  95. begin
  96. FAttributes := AValue;
  97. Changed(False);
  98. end;
  99. procedure TFieldDef.SetDataType(AValue: TFieldType);
  100. begin
  101. FDataType := AValue;
  102. Changed(False);
  103. end;
  104. procedure TFieldDef.SetPrecision(const AValue: Longint);
  105. begin
  106. FPrecision := AValue;
  107. Changed(False);
  108. end;
  109. procedure TFieldDef.SetSize(const AValue: Word);
  110. begin
  111. FSize := AValue;
  112. Changed(False);
  113. end;
  114. procedure TFieldDef.SetRequired(const AValue: Boolean);
  115. begin
  116. FRequired := AValue;
  117. Changed(False);
  118. end;
  119. function TFieldDef.GetDisplayName: string;
  120. begin
  121. Result := FDisplayName;
  122. if Result = '' then
  123. Result := Fname;
  124. end;
  125. procedure TFieldDef.SetDisplayName(const AValue: string);
  126. begin
  127. if (AValue <> '') and (AnsiCompareText(AValue, DisplayName) <> 0) and
  128. (Collection is TOwnedCollection) and
  129. (TFieldDefs(Collection).IndexOf(AValue) >= 0) then
  130. DatabaseErrorFmt(SDuplicateName, [AValue, Collection.ClassName]);
  131. FName := AValue;
  132. end;
  133. Function TFieldDef.GetFieldClass : TFieldClass;
  134. begin
  135. //!! Should be owner as tdataset but that doesn't work ??
  136. If Assigned(Collection) And
  137. (Collection is TFieldDefs) And
  138. Assigned(TFieldDefs(Collection).Dataset) then
  139. Result:=TFieldDefs(Collection).Dataset.GetFieldClass(FDataType)
  140. else
  141. Result:=Nil;
  142. end;
  143. { ---------------------------------------------------------------------
  144. TFieldDefs
  145. ---------------------------------------------------------------------}
  146. {
  147. destructor TFieldDefs.Destroy;
  148. begin
  149. FItems.Free;
  150. // This will destroy all fielddefs since we own them...
  151. Inherited Destroy;
  152. end;
  153. }
  154. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType);
  155. begin
  156. Add(AName,ADatatype,0,False);
  157. end;
  158. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize : Word);
  159. begin
  160. Add(AName,ADatatype,ASize,False);
  161. end;
  162. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word;
  163. ARequired: Boolean);
  164. begin
  165. If Length(AName)=0 Then
  166. DatabaseError(SNeedFieldName);
  167. // the fielddef will register itself here as a owned component.
  168. // fieldno is 1 based !
  169. BeginUpdate;
  170. try
  171. TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,Count+1);
  172. finally
  173. EndUpdate;
  174. end;
  175. end;
  176. function TFieldDefs.GetItem(Index: Longint): TFieldDef;
  177. begin
  178. Result := TFieldDef(inherited Items[Index]);;
  179. end;
  180. function TFieldDefs.GetDataset: TDataset;
  181. begin
  182. Result := TDataset(GetOwner);
  183. end;
  184. procedure TFieldDefs.SetItem(Index: Longint; const AValue: TFieldDef);
  185. begin
  186. inherited Items[Index] := AValue;
  187. end;
  188. procedure TFieldDefs.SetItemName(AItem: TCollectionItem);
  189. begin
  190. if AItem is TFieldDef then
  191. with AItem as TFieldDef do
  192. if Name = '' then
  193. Name := Dataset.Name + Copy(ClassName, 2, 5) + IntToStr(ID+1)
  194. else inherited SetItemName(AItem);
  195. end;
  196. constructor TFieldDefs.Create(ADataset: TDataset);
  197. begin
  198. Inherited Create(TPersistent(ADataset), TFieldDef);
  199. end;
  200. procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
  201. Var I : longint;
  202. begin
  203. Clear;
  204. For i:=0 to FieldDefs.Count-1 do
  205. With FieldDefs[i] do
  206. Add(Name,DataType,Size,Required);
  207. end;
  208. {
  209. procedure TFieldDefs.Clear;
  210. Var I : longint;
  211. begin
  212. For I:=FItems.Count-1 downto 0 do
  213. TFieldDef(Fitems[i]).Free;
  214. FItems.Clear;
  215. end;
  216. }
  217. function TFieldDefs.Find(const AName: string): TFieldDef;
  218. Var I : longint;
  219. begin
  220. I:=IndexOf(AName);
  221. If I=-1 Then
  222. DataBaseErrorFmt(SUnknownField,[AName,DataSet.Name]);
  223. Result:=Items[i];
  224. end;
  225. function TFieldDefs.IndexOf(const AName: string): Longint;
  226. Var I : longint;
  227. begin
  228. For I:=0 to Count-1 do
  229. If AnsiCompareText(Items[I].Name,AName)=0 then
  230. begin
  231. Result:=I;
  232. Exit;
  233. end;
  234. Result:=-1;
  235. end;
  236. procedure TFieldDefs.Update;
  237. begin
  238. DataSet.InitFieldDefs;
  239. end;
  240. Function TFieldDefs.AddFieldDef : TFieldDef;
  241. begin
  242. Result:=TFieldDef.Create(Self,'',ftUnknown,0,False,Count+1);
  243. end;
  244. { ---------------------------------------------------------------------
  245. TField
  246. ---------------------------------------------------------------------}
  247. Const
  248. SBoolean = 'Boolean';
  249. SDateTime = 'TDateTime';
  250. SFloat = 'Float';
  251. SInteger = 'Integer';
  252. SVariant = 'Variant';
  253. SString = 'String';
  254. constructor TField.Create(AOwner: TComponent);
  255. begin
  256. Inherited Create(AOwner);
  257. FVisible:=True;
  258. FValidChars:=[#0..#255];
  259. FProviderFlags := [pfInUpdate,pfInWhere];
  260. end;
  261. destructor TField.Destroy;
  262. begin
  263. IF Assigned(FDataSet) then
  264. begin
  265. FDataSet.Active:=False;
  266. if Assigned(FFields) then
  267. FFields.Remove(Self);
  268. end;
  269. FLookupList.Free;
  270. Inherited Destroy;
  271. end;
  272. function TField.AccessError(const TypeName: string): EDatabaseError;
  273. begin
  274. Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);
  275. end;
  276. procedure TField.Assign(Source: TPersistent);
  277. begin
  278. if Source = nil then Clear
  279. else if Source is TField then begin
  280. Value := TField(Source).Value;
  281. end else
  282. inherited Assign(Source);
  283. end;
  284. procedure TField.AssignValue(const AValue: TVarRec);
  285. procedure Error;
  286. begin
  287. DatabaseErrorFmt(SFieldValueError, [DisplayName]);
  288. end;
  289. begin
  290. with AValue do
  291. case VType of
  292. vtInteger:
  293. AsInteger := VInteger;
  294. vtBoolean:
  295. AsBoolean := VBoolean;
  296. vtChar:
  297. AsString := VChar;
  298. vtExtended:
  299. AsFloat := VExtended^;
  300. vtString:
  301. AsString := VString^;
  302. vtPointer:
  303. if VPointer <> nil then Error;
  304. vtPChar:
  305. AsString := VPChar;
  306. vtObject:
  307. if (VObject = nil) or (VObject is TPersistent) then
  308. Assign(TPersistent(VObject))
  309. else
  310. Error;
  311. vtAnsiString:
  312. AsString := string(VAnsiString);
  313. // vtCurrency:
  314. // AsCurrency := VCurrency^;
  315. vtVariant:
  316. if not VarIsClear(VVariant^) then Self.Value := VVariant^;
  317. vtWideString:
  318. AsString := WideString(VWideString);
  319. vtInt64:
  320. Self.Value := VInt64^;
  321. else
  322. Error;
  323. end;
  324. end;
  325. procedure TField.Change;
  326. begin
  327. If Assigned(FOnChange) Then
  328. FOnChange(Self);
  329. end;
  330. procedure TField.CheckInactive;
  331. begin
  332. If Assigned(FDataSet) then
  333. FDataset.CheckInactive;
  334. end;
  335. procedure TField.Clear;
  336. begin
  337. if FieldKind in [fkData, fkInternalCalc] then
  338. SetData(Nil);
  339. end;
  340. procedure TField.DataChanged;
  341. begin
  342. FDataset.DataEvent(deFieldChange,ptrint(Self));
  343. end;
  344. procedure TField.FocusControl;
  345. begin
  346. FDataSet.DataEvent(deFocusControl,ptrint(Self));
  347. end;
  348. procedure TField.FreeBuffers;
  349. begin
  350. // Empty. Provided for backward compatibiliy;
  351. // TDataset manages the buffers.
  352. end;
  353. function TField.GetAsBoolean: Boolean;
  354. begin
  355. AccessError(SBoolean);
  356. end;
  357. function TField.GetAsDateTime: TDateTime;
  358. begin
  359. AccessError(SdateTime);
  360. end;
  361. function TField.GetAsFloat: Double;
  362. begin
  363. AccessError(SDateTime);
  364. end;
  365. function TField.GetAsLongint: Longint;
  366. begin
  367. AccessError(SInteger);
  368. end;
  369. function TField.GetAsVariant: Variant;
  370. begin
  371. AccessError(SVariant);
  372. end;
  373. function TField.GetAsInteger: Integer;
  374. begin
  375. Result:=GetAsLongint;
  376. end;
  377. function TField.GetAsString: string;
  378. begin
  379. AccessError(SString);
  380. end;
  381. function TField.GetOldValue: Variant;
  382. var SaveState : TDatasetState;
  383. begin
  384. SaveState := FDataset.State;
  385. try
  386. FDataset.SetTempState(dsOldValue);
  387. Result := GetAsVariant;
  388. finally
  389. FDataset.RestoreState(SaveState);
  390. end;
  391. end;
  392. function TField.GetNewValue: Variant;
  393. var SaveState : TDatasetState;
  394. begin
  395. SaveState := FDataset.State;
  396. try
  397. FDataset.SetTempState(dsNewValue);
  398. Result := GetAsVariant;
  399. finally
  400. FDataset.RestoreState(SaveState);
  401. end;
  402. end;
  403. procedure TField.SetNewValue(const AValue: Variant);
  404. var SaveState : TDatasetState;
  405. begin
  406. SaveState := FDataset.State;
  407. try
  408. FDataset.SetTempState(dsNewValue);
  409. SetAsVariant(AValue);
  410. finally
  411. FDataset.RestoreState(SaveState);
  412. end;
  413. end;
  414. function TField.GetCurValue: Variant;
  415. var SaveState : TDatasetState;
  416. begin
  417. SaveState := FDataset.State;
  418. try
  419. FDataset.SetTempState(dsCurValue);
  420. Result := GetAsVariant;
  421. finally
  422. FDataset.RestoreState(SaveState);
  423. end;
  424. end;
  425. function TField.GetCanModify: Boolean;
  426. begin
  427. Result:=Not ReadOnly;
  428. If Result then
  429. begin
  430. Result:=Assigned(DataSet);
  431. If Result then
  432. Result:= DataSet.CanModify;
  433. end;
  434. end;
  435. function TField.GetData(Buffer: Pointer): Boolean;
  436. begin
  437. Result:=GetData(Buffer,True);
  438. end;
  439. function TField.GetData(Buffer: Pointer; NativeFormat : Boolean): Boolean;
  440. begin
  441. IF FDataset=Nil then
  442. DatabaseErrorFmt(SNoDataset,[FieldName]);
  443. If FVAlidating then
  444. begin
  445. result:=Not(FValueBuffer=Nil);
  446. If Result then
  447. Move (FValueBuffer^,Buffer^ ,DataSize);
  448. end
  449. else
  450. Result:=FDataset.GetFieldData(Self,Buffer,NativeFormat);
  451. end;
  452. function TField.GetDataSize: Word;
  453. begin
  454. Result:=0;
  455. end;
  456. function TField.GetDefaultWidth: Longint;
  457. begin
  458. Result:=10;
  459. end;
  460. function TField.GetDisplayName : String;
  461. begin
  462. If FDisplayLabel<>'' then
  463. result:=FDisplayLabel
  464. else
  465. Result:=FFieldName;
  466. end;
  467. Function TField.IsDisplayStored : Boolean;
  468. begin
  469. Result:=(DisplayLabel<>FieldName);
  470. end;
  471. function TField.GetLookupList: TLookupList;
  472. begin
  473. if not Assigned(FLookupList) then
  474. FLookupList := TLookupList.Create;
  475. Result := FLookupList;
  476. end;
  477. procedure TField.CalcLookupValue;
  478. begin
  479. if FLookupCache then
  480. Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields])
  481. else if (FLookupDataSet <> nil) and FLookupDataSet.Active then
  482. Value := FLookupDataSet.Lookup(FLookupKeyFields,
  483. FDataSet.FieldValues[FKeyFields], FLookupResultField);
  484. end;
  485. function TField.getIndex : longint;
  486. begin
  487. If Assigned(FDataset) then
  488. Result:=FDataset.FFieldList.IndexOf(Self)
  489. else
  490. Result:=-1;
  491. end;
  492. function TField.GetAsCurrency: Currency;
  493. begin
  494. Result := GetAsFloat;
  495. end;
  496. procedure TField.SetAlignment(const AValue: TAlignMent);
  497. begin
  498. if FAlignment <> AValue then
  499. begin
  500. FAlignment := Avalue;
  501. PropertyChanged(false);
  502. end;
  503. end;
  504. procedure TField.SetIndex(AValue: Integer);
  505. begin
  506. if FFields <> nil then FFields.SetFieldIndex(Self, AValue)
  507. end;
  508. procedure TField.SetAsCurrency(AValue: Currency);
  509. begin
  510. SetAsFloat(AValue);
  511. end;
  512. function TField.GetIsNull: Boolean;
  513. begin
  514. Result:=Not(GetData (Nil));
  515. end;
  516. function TField.GetParentComponent: TComponent;
  517. begin
  518. Result := DataSet;
  519. end;
  520. procedure TField.GetText(var AText: string; ADisplayText: Boolean);
  521. begin
  522. AText:=GetAsString;
  523. end;
  524. function TField.HasParent: Boolean;
  525. begin
  526. HasParent:=True;
  527. end;
  528. function TField.IsValidChar(InputChar: Char): Boolean;
  529. begin
  530. // FValidChars must be set in Create.
  531. Result:=InputChar in FValidChars;
  532. end;
  533. procedure TField.RefreshLookupList;
  534. var SaveActive: Boolean;
  535. begin
  536. if (FLookupDataSet <> nil) And (FLookupKeyFields <> '') And
  537. (FlookupResultField <> '') And (FKeyFields <> '') then begin
  538. SaveActive := FLookupDataSet.Active;
  539. with FLookupDataSet do
  540. try
  541. Active := True;
  542. FFields.CheckFieldNames(FLookupKeyFields);
  543. FieldByName(FLookupResultField);
  544. LookupList.Clear;
  545. DisableControls;
  546. try
  547. First;
  548. while not Eof do begin
  549. FLookupList.Add(FieldValues[FLookupKeyFields],
  550. FieldValues[FLookupResultField]);
  551. Next;
  552. end;
  553. finally
  554. EnableControls;
  555. end;
  556. finally
  557. Active := SaveActive;
  558. end;
  559. end;
  560. end;
  561. procedure TField.Notification(AComponent: TComponent; Operation: TOperation);
  562. begin
  563. Inherited Notification(AComponent,Operation);
  564. if (Operation = opRemove) and (AComponent = FLookupDataSet) then
  565. FLookupDataSet := nil;
  566. end;
  567. procedure TField.PropertyChanged(LayoutAffected: Boolean);
  568. begin
  569. If (FDataset<>Nil) and (FDataset.Active) then
  570. If LayoutAffected then
  571. FDataset.DataEvent(deLayoutChange,0)
  572. else
  573. FDataset.DataEvent(deDatasetchange,0);
  574. end;
  575. procedure TField.ReadState(Reader: TReader);
  576. begin
  577. inherited ReadState(Reader);
  578. if Reader.Parent is TDataSet then
  579. DataSet := TDataSet(Reader.Parent);
  580. end;
  581. procedure TField.SetAsBoolean(AValue: Boolean);
  582. begin
  583. AccessError(SBoolean);
  584. end;
  585. procedure TField.SetAsDateTime(AValue: TDateTime);
  586. begin
  587. AccessError(SDateTime);
  588. end;
  589. procedure TField.SetAsFloat(AValue: Double);
  590. begin
  591. AccessError(SFloat);
  592. end;
  593. procedure TField.SetAsVariant(AValue: Variant);
  594. begin
  595. if VarIsNull(AValue) then
  596. Clear
  597. else
  598. try
  599. SetVarValue(AValue);
  600. except
  601. on EVariantError do DatabaseErrorFmt(SFieldValueError, [DisplayName]);
  602. end;
  603. end;
  604. procedure TField.SetAsLongint(AValue: Longint);
  605. begin
  606. AccessError(SInteger);
  607. end;
  608. procedure TField.SetAsInteger(AValue: Integer);
  609. begin
  610. SetAsLongint(AValue);
  611. end;
  612. procedure TField.SetAsString(const AValue: string);
  613. begin
  614. AccessError(SString);
  615. end;
  616. procedure TField.SetData(Buffer: Pointer);
  617. begin
  618. SetData(Buffer,True);
  619. end;
  620. procedure TField.SetData(Buffer: Pointer; NativeFormat : Boolean);
  621. begin
  622. If Not Assigned(FDataset) then
  623. EDatabaseError.CreateFmt(SNoDataset,[FieldName]);
  624. FDataSet.SetFieldData(Self,Buffer, NativeFormat);
  625. end;
  626. Procedure TField.SetDataset (AValue : TDataset);
  627. begin
  628. {$ifdef dsdebug}
  629. Writeln ('Setting dataset');
  630. {$endif}
  631. If AValue=FDataset then exit;
  632. If Assigned(FDataset) Then
  633. begin
  634. FDataset.CheckInactive;
  635. FDataset.FFieldList.Remove(Self);
  636. end;
  637. If Assigned(AValue) then
  638. begin
  639. AValue.CheckInactive;
  640. AValue.FFieldList.Add(Self);
  641. end;
  642. FDataset:=AValue;
  643. end;
  644. procedure TField.SetDataType(AValue: TFieldType);
  645. begin
  646. FDataType := AValue;
  647. end;
  648. procedure TField.SetFieldType(AValue: TFieldType);
  649. begin
  650. //!! To be implemented
  651. end;
  652. procedure TField.SetParentComponent(AParent: TComponent);
  653. begin
  654. if not (csLoading in ComponentState) then
  655. DataSet := AParent as TDataSet;
  656. end;
  657. procedure TField.SetSize(AValue: Word);
  658. begin
  659. CheckInactive;
  660. CheckTypeSize(AValue);
  661. FSize:=AValue;
  662. end;
  663. procedure TField.SetText(const AValue: string);
  664. begin
  665. AsString:=AValue;
  666. end;
  667. procedure TField.SetVarValue(const AValue: Variant);
  668. begin
  669. AccessError(SVariant);
  670. end;
  671. procedure TField.Validate(Buffer: Pointer);
  672. begin
  673. If assigned(OnValidate) Then
  674. begin
  675. FValueBuffer:=Buffer;
  676. FValidating:=True;
  677. Try
  678. OnValidate(Self);
  679. finally
  680. FValidating:=False;
  681. end;
  682. end;
  683. end;
  684. class function Tfield.IsBlob: Boolean;
  685. begin
  686. Result:=False;
  687. end;
  688. class procedure TField.CheckTypeSize(AValue: Longint);
  689. begin
  690. If (AValue<>0) and Not IsBlob Then
  691. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  692. end;
  693. // TField private methods
  694. procedure TField.SetEditText(const AValue: string);
  695. begin
  696. if Assigned(OnSetText) then
  697. OnSetText(Self, AValue)
  698. else
  699. SetText(AValue);
  700. end;
  701. function TField.GetEditText: String;
  702. begin
  703. SetLength(Result, 0);
  704. if Assigned(OnGetText) then
  705. OnGetText(Self, Result, False)
  706. else
  707. GetText(Result, False);
  708. end;
  709. function TField.GetDisplayText: String;
  710. begin
  711. SetLength(Result, 0);
  712. if Assigned(OnGetText) then
  713. OnGetText(Self, Result, True)
  714. else
  715. GetText(Result, True);
  716. end;
  717. procedure TField.SetDisplayLabel(const AValue: string);
  718. begin
  719. if FDisplayLabel<>Avalue then
  720. begin
  721. FDisplayLabel:=Avalue;
  722. PropertyChanged(true);
  723. end;
  724. end;
  725. procedure TField.SetDisplayWidth(const AValue: Longint);
  726. begin
  727. if FDisplayWidth<>AValue then
  728. begin
  729. FDisplayWidth:=AValue;
  730. PropertyChanged(True);
  731. end;
  732. end;
  733. function TField.GetDisplayWidth: integer;
  734. begin
  735. if FDisplayWidth=0 then
  736. result:=GetDefaultWidth
  737. else
  738. result:=FDisplayWidth;
  739. end;
  740. procedure TField.SetReadOnly(const AValue: Boolean);
  741. begin
  742. if (FReadOnly<>Avalue) then
  743. begin
  744. FReadOnly:=AValue;
  745. PropertyChanged(True);
  746. end;
  747. end;
  748. procedure TField.SetVisible(const AValue: Boolean);
  749. begin
  750. if FVisible<>Avalue then
  751. begin
  752. FVisible:=AValue;
  753. PropertyChanged(True);
  754. end;
  755. end;
  756. { ---------------------------------------------------------------------
  757. TStringField
  758. ---------------------------------------------------------------------}
  759. constructor TStringField.Create(AOwner: TComponent);
  760. begin
  761. Inherited Create(AOwner);
  762. SetDataType(ftString);
  763. Size:=20;
  764. end;
  765. class procedure TStringField.CheckTypeSize(AValue: Longint);
  766. begin
  767. If (AValue<1) or (AValue>dsMaxStringSize) Then
  768. databaseErrorFmt(SInvalidFieldSize,[AValue])
  769. end;
  770. function TStringField.GetAsBoolean: Boolean;
  771. Var S : String;
  772. begin
  773. S:=GetAsString;
  774. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  775. end;
  776. function TStringField.GetAsDateTime: TDateTime;
  777. begin
  778. Result:=StrToDateTime(GetAsString);
  779. end;
  780. function TStringField.GetAsFloat: Double;
  781. begin
  782. Result:=StrToFloat(GetAsString);
  783. end;
  784. function TStringField.GetAsLongint: Longint;
  785. begin
  786. Result:=StrToInt(GetAsString);
  787. end;
  788. function TStringField.GetAsString: string;
  789. begin
  790. If Not GetValue(Result) then
  791. Result:='';
  792. end;
  793. function TStringField.GetAsVariant: Variant;
  794. Var s : string;
  795. begin
  796. If GetValue(s) then
  797. Result:=s
  798. else
  799. Result:=Null;
  800. end;
  801. function TStringField.GetDataSize: Word;
  802. begin
  803. Result:=Size+1;
  804. end;
  805. function TStringField.GetDefaultWidth: Longint;
  806. begin
  807. result:=Size;
  808. end;
  809. Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  810. begin
  811. AText:=GetAsString;
  812. end;
  813. function TStringField.GetValue(var AValue: string): Boolean;
  814. Var Buf : TStringFieldBuffer;
  815. begin
  816. Result:=GetData(@Buf);
  817. If Result then
  818. AValue:=Buf;
  819. end;
  820. procedure TStringField.SetAsBoolean(AValue: Boolean);
  821. begin
  822. If AValue Then
  823. SetAsString('T')
  824. else
  825. SetAsString('F');
  826. end;
  827. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  828. begin
  829. SetAsString(DateTimeToStr(AValue));
  830. end;
  831. procedure TStringField.SetAsFloat(AValue: Double);
  832. begin
  833. SetAsString(FloatToStr(AValue));
  834. end;
  835. procedure TStringField.SetAsLongint(AValue: Longint);
  836. begin
  837. SetAsString(intToStr(AValue));
  838. end;
  839. procedure TStringField.SetAsString(const AValue: string);
  840. Const NullByte : char = #0;
  841. begin
  842. IF Length(AValue)=0 then
  843. SetData(@NullByte)
  844. else
  845. SetData(@AValue[1]);
  846. end;
  847. procedure TStringField.SetVarValue(const AValue: Variant);
  848. begin
  849. SetAsString(AValue);
  850. end;
  851. { ---------------------------------------------------------------------
  852. TNumericField
  853. ---------------------------------------------------------------------}
  854. constructor TNumericField.Create(AOwner: TComponent);
  855. begin
  856. Inherited Create(AOwner);
  857. AlignMent:=taRightJustify;
  858. end;
  859. procedure TNumericField.RangeError(AValue, Min, Max: Double);
  860. begin
  861. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  862. end;
  863. procedure TNumericField.SetDisplayFormat(const AValue: string);
  864. begin
  865. If FDisplayFormat<>AValue then
  866. begin
  867. FDisplayFormat:=AValue;
  868. PropertyChanged(True);
  869. end;
  870. end;
  871. procedure TNumericField.SetEditFormat(const AValue: string);
  872. begin
  873. If FEDitFormat<>AValue then
  874. begin
  875. FEDitFormat:=AVAlue;
  876. PropertyChanged(True);
  877. end;
  878. end;
  879. { ---------------------------------------------------------------------
  880. TLongintField
  881. ---------------------------------------------------------------------}
  882. constructor TLongintField.Create(AOwner: TComponent);
  883. begin
  884. Inherited Create(AOwner);
  885. SetDatatype(ftinteger);
  886. FMinRange:=Low(LongInt);
  887. FMaxRange:=High(LongInt);
  888. FValidchars:=['+','-','0'..'9'];
  889. end;
  890. function TLongintField.GetAsFloat: Double;
  891. begin
  892. Result:=GetAsLongint;
  893. end;
  894. function TLongintField.GetAsLongint: Longint;
  895. begin
  896. If Not GetValue(Result) then
  897. Result:=0;
  898. end;
  899. function TLongintField.GetAsVariant: Variant;
  900. Var L : Longint;
  901. begin
  902. If GetValue(L) then
  903. Result:=L
  904. else
  905. Result:=Null;
  906. end;
  907. function TLongintField.GetAsString: string;
  908. Var L : Longint;
  909. begin
  910. If GetValue(L) then
  911. Result:=IntTostr(L)
  912. else
  913. Result:='';
  914. end;
  915. function TLongintField.GetDataSize: Word;
  916. begin
  917. Result:=SizeOf(Longint);
  918. end;
  919. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  920. var l : longint;
  921. fmt : string;
  922. begin
  923. Atext:='';
  924. If Not GetValue(l) then exit;
  925. If ADisplayText or (FEditFormat='') then
  926. fmt:=FDisplayFormat
  927. else
  928. fmt:=FEditFormat;
  929. If length(fmt)<>0 then
  930. AText:=FormatFloat(fmt,L)
  931. else
  932. Str(L,AText);
  933. end;
  934. function TLongintField.GetValue(var AValue: Longint): Boolean;
  935. Var L : Longint;
  936. P : PLongint;
  937. begin
  938. P:=@L;
  939. Result:=GetData(P);
  940. If Result then
  941. Case Datatype of
  942. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  943. ftword : Avalue:=Pword(P)^;
  944. ftsmallint : AValue:=PSmallint(P)^;
  945. end;
  946. end;
  947. procedure TLongintField.SetAsFloat(AValue: Double);
  948. begin
  949. SetAsLongint(Round(Avalue));
  950. end;
  951. procedure TLongintField.SetAsLongint(AValue: Longint);
  952. begin
  953. If CheckRange(AValue) then
  954. SetData(@AValue)
  955. else
  956. RangeError(Avalue,FMinrange,FMaxRange);
  957. end;
  958. procedure TLongintField.SetVarValue(const AValue: Variant);
  959. begin
  960. SetAsLongint(AValue);
  961. end;
  962. procedure TLongintField.SetAsString(const AValue: string);
  963. Var L,Code : longint;
  964. begin
  965. If length(AValue)=0 then
  966. Clear
  967. else
  968. begin
  969. Val(AVAlue,L,Code);
  970. If Code=0 then
  971. SetAsLongint(L)
  972. else
  973. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  974. end;
  975. end;
  976. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  977. begin
  978. result := true;
  979. if (FMaxValue=0) then
  980. begin
  981. if (AValue>FMaxRange) Then result := false;
  982. end
  983. else
  984. if AValue>FMaxValue then result := false;
  985. if (FMinValue=0) then
  986. begin
  987. if (AValue<FMinRange) Then result := false;
  988. end
  989. else
  990. if AValue<FMinValue then result := false;
  991. end;
  992. Procedure TLongintField.SetMaxValue (AValue : longint);
  993. begin
  994. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  995. FMaxValue:=AValue
  996. else
  997. RangeError(AValue,FMinRange,FMaxRange);
  998. end;
  999. Procedure TLongintField.SetMinValue (AValue : longint);
  1000. begin
  1001. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1002. FMinValue:=AValue
  1003. else
  1004. RangeError(AValue,FMinRange,FMaxRange);
  1005. end;
  1006. { ---------------------------------------------------------------------
  1007. TLargeintField
  1008. ---------------------------------------------------------------------}
  1009. constructor TLargeintField.Create(AOwner: TComponent);
  1010. begin
  1011. Inherited Create(AOwner);
  1012. SetDatatype(ftLargeint);
  1013. FMinRange:=Low(Largeint);
  1014. FMaxRange:=High(Largeint);
  1015. FValidchars:=['+','-','0'..'9'];
  1016. end;
  1017. function TLargeintField.GetAsFloat: Double;
  1018. begin
  1019. Result:=GetAsLargeint;
  1020. end;
  1021. function TLargeintField.GetAsLargeint: Largeint;
  1022. begin
  1023. If Not GetValue(Result) then
  1024. Result:=0;
  1025. end;
  1026. function TLargeIntField.GetAsVariant: Variant;
  1027. Var L : Largeint;
  1028. begin
  1029. If GetValue(L) then
  1030. Result:=L
  1031. else
  1032. Result:=Null;
  1033. end;
  1034. function TLargeintField.GetAsLongint: Longint;
  1035. begin
  1036. Result:=GetAsLargeint;
  1037. end;
  1038. function TLargeintField.GetAsString: string;
  1039. Var L : Largeint;
  1040. begin
  1041. If GetValue(L) then
  1042. Result:=IntTostr(L)
  1043. else
  1044. Result:='';
  1045. end;
  1046. function TLargeintField.GetDataSize: Word;
  1047. begin
  1048. Result:=SizeOf(Largeint);
  1049. end;
  1050. procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean);
  1051. var l : largeint;
  1052. fmt : string;
  1053. begin
  1054. Atext:='';
  1055. If Not GetValue(l) then exit;
  1056. If ADisplayText or (FEditFormat='') then
  1057. fmt:=FDisplayFormat
  1058. else
  1059. fmt:=FEditFormat;
  1060. If length(fmt)<>0 then
  1061. AText:=FormatFloat(fmt,L)
  1062. else
  1063. Str(L,AText);
  1064. end;
  1065. function TLargeintField.GetValue(var AValue: Largeint): Boolean;
  1066. type
  1067. PLargeint = ^Largeint;
  1068. Var P : PLargeint;
  1069. begin
  1070. P:=@AValue;
  1071. Result:=GetData(P);
  1072. end;
  1073. procedure TLargeintField.SetAsFloat(AValue: Double);
  1074. begin
  1075. SetAsLargeint(Round(Avalue));
  1076. end;
  1077. procedure TLargeintField.SetAsLargeint(AValue: Largeint);
  1078. begin
  1079. If CheckRange(AValue) then
  1080. SetData(@AValue)
  1081. else
  1082. RangeError(Avalue,FMinrange,FMaxRange);
  1083. end;
  1084. procedure TLargeintField.SetAsLongint(AValue: Longint);
  1085. begin
  1086. SetAsLargeint(Avalue);
  1087. end;
  1088. procedure TLargeintField.SetAsString(const AValue: string);
  1089. Var L : largeint;
  1090. code : longint;
  1091. begin
  1092. If length(AValue)=0 then
  1093. Clear
  1094. else
  1095. begin
  1096. Val(AVAlue,L,Code);
  1097. If Code=0 then
  1098. SetAsLargeint(L)
  1099. else
  1100. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  1101. end;
  1102. end;
  1103. procedure TLargeintField.SetVarValue(const AValue: Variant);
  1104. begin
  1105. SetAsLargeint(AValue);
  1106. end;
  1107. Function TLargeintField.CheckRange(AValue : largeint) : Boolean;
  1108. begin
  1109. result := true;
  1110. if (FMaxValue=0) then
  1111. begin
  1112. if (AValue>FMaxRange) Then result := false;
  1113. end
  1114. else
  1115. if AValue>FMaxValue then result := false;
  1116. if (FMinValue=0) then
  1117. begin
  1118. if (AValue<FMinRange) Then result := false;
  1119. end
  1120. else
  1121. if AValue<FMinValue then result := false;
  1122. end;
  1123. Procedure TLargeintField.SetMaxValue (AValue : largeint);
  1124. begin
  1125. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1126. FMaxValue:=AValue
  1127. else
  1128. RangeError(AValue,FMinRange,FMaxRange);
  1129. end;
  1130. Procedure TLargeintField.SetMinValue (AValue : largeint);
  1131. begin
  1132. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1133. FMinValue:=AValue
  1134. else
  1135. RangeError(AValue,FMinRange,FMaxRange);
  1136. end;
  1137. { TSmallintField }
  1138. function TSmallintField.GetDataSize: Word;
  1139. begin
  1140. Result:=SizeOf(SmallInt);
  1141. end;
  1142. constructor TSmallintField.Create(AOwner: TComponent);
  1143. begin
  1144. inherited Create(AOwner);
  1145. SetDataType(ftSmallInt);
  1146. FMinRange:=-32768;
  1147. FMaxRange:=32767;
  1148. end;
  1149. { TWordField }
  1150. function TWordField.GetDataSize: Word;
  1151. begin
  1152. Result:=SizeOf(Word);
  1153. end;
  1154. constructor TWordField.Create(AOwner: TComponent);
  1155. begin
  1156. inherited Create(AOwner);
  1157. SetDataType(ftWord);
  1158. FMinRange:=0;
  1159. FMaxRange:=65535;
  1160. FValidchars:=['+','0'..'9'];
  1161. end;
  1162. { TAutoIncField }
  1163. constructor TAutoIncField.Create(AOwner: TComponent);
  1164. begin
  1165. Inherited Create(AOWner);
  1166. SetDataType(ftAutoInc);
  1167. FReadOnly:=True;
  1168. end;
  1169. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  1170. begin
  1171. DataBaseError(SCantSetAutoIncfields);
  1172. end;
  1173. { TFloatField }
  1174. function TFloatField.GetAsFloat: Double;
  1175. begin
  1176. If Not GetData(@Result) Then
  1177. Result:=0.0;
  1178. end;
  1179. function TFloatField.GetAsVariant: Variant;
  1180. Var f : Double;
  1181. begin
  1182. If GetData(@f) then
  1183. Result := f
  1184. else
  1185. Result:=Null;
  1186. end;
  1187. function TFloatField.GetAsLongint: Longint;
  1188. begin
  1189. Result:=Round(GetAsFloat);
  1190. end;
  1191. function TFloatField.GetAsString: string;
  1192. Var R : Double;
  1193. begin
  1194. If GetData(@R) then
  1195. Result:=FloatToStr(R)
  1196. else
  1197. Result:='';
  1198. end;
  1199. function TFloatField.GetDataSize: Word;
  1200. begin
  1201. Result:=SizeOf(Double);
  1202. end;
  1203. procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean);
  1204. Var
  1205. fmt : string;
  1206. E : Double;
  1207. begin
  1208. TheText:='';
  1209. If Not GetData(@E) then exit;
  1210. If ADisplayText or (Length(FEditFormat) = 0) Then
  1211. Fmt:=FDisplayFormat
  1212. else
  1213. Fmt:=FEditFormat;
  1214. If fmt<>'' then
  1215. TheText:=FormatFloat(fmt,E)
  1216. else
  1217. TheText:=FloatToStrF(E,ffgeneral,FPrecision,0);
  1218. end;
  1219. procedure TFloatField.SetAsFloat(AValue: Double);
  1220. begin
  1221. If CheckRange(AValue) then
  1222. SetData(@Avalue)
  1223. else
  1224. RangeError(AValue,FMinValue,FMaxValue);
  1225. end;
  1226. procedure TFloatField.SetAsLongint(AValue: Longint);
  1227. begin
  1228. SetAsFloat(Avalue);
  1229. end;
  1230. procedure TFloatField.SetAsString(const AValue: string);
  1231. Var R : Double;
  1232. begin
  1233. try
  1234. R := StrToFloat(AValue);
  1235. SetAsFloat(R);
  1236. except
  1237. DatabaseErrorFmt(SNotAFloat, [AValue]);
  1238. end;
  1239. end;
  1240. procedure TFloatField.SetVarValue(const AValue: Variant);
  1241. begin
  1242. SetAsFloat(Avalue);
  1243. end;
  1244. constructor TFloatField.Create(AOwner: TComponent);
  1245. begin
  1246. Inherited Create(AOwner);
  1247. SetDatatype(ftfloat);
  1248. FPrecision:=15;
  1249. FValidChars := [DecimalSeparator, '+', '-', '0'..'9', 'E', 'e'];
  1250. end;
  1251. Function TFloatField.CheckRange(AValue : Double) : Boolean;
  1252. begin
  1253. If (FMinValue<>0) or (FmaxValue<>0) then
  1254. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  1255. else
  1256. Result:=True;
  1257. end;
  1258. { TCurrencyField }
  1259. Constructor TCurrencyField.Create(AOwner: TComponent);
  1260. begin
  1261. inherited Create(AOwner);
  1262. SetDataType(ftCurrency);
  1263. end;
  1264. procedure TCurrencyField.GetText(var TheText: string; ADisplayText: Boolean);
  1265. Var
  1266. fmt : string;
  1267. ff: TFloatFormat;
  1268. E : Double;
  1269. begin
  1270. TheText:='';
  1271. If Not GetData(@E) then exit;
  1272. If ADisplayText or (Length(FEditFormat) = 0) Then
  1273. Fmt:=FDisplayFormat
  1274. else
  1275. Fmt:=FEditFormat;
  1276. if ADisplayText then
  1277. ff := ffCurrency
  1278. else
  1279. ff := ffFixed;
  1280. If fmt<>'' then
  1281. TheText:=FormatFloat(fmt, E)
  1282. else
  1283. TheText:=FloatToStrF(E, ff, FPrecision, CurrencyDecimals);
  1284. end;
  1285. { TBooleanField }
  1286. function TBooleanField.GetAsBoolean: Boolean;
  1287. var b : wordbool;
  1288. begin
  1289. If GetData(@b) then
  1290. result := b
  1291. else
  1292. Result:=False;
  1293. end;
  1294. function TBooleanField.GetAsVariant: Variant;
  1295. Var b : wordbool;
  1296. begin
  1297. If GetData(@b) then
  1298. Result := b
  1299. else
  1300. Result:=Null;
  1301. end;
  1302. function TBooleanField.GetAsString: string;
  1303. Var B : wordbool;
  1304. begin
  1305. If Getdata(@B) then
  1306. Result:=FDisplays[False,B]
  1307. else
  1308. result:='';
  1309. end;
  1310. function TBooleanField.GetDataSize: Word;
  1311. begin
  1312. Result:=SizeOf(wordBool);
  1313. end;
  1314. function TBooleanField.GetDefaultWidth: Longint;
  1315. begin
  1316. Result:=Length(FDisplays[false,false]);
  1317. If Result<Length(FDisplays[false,True]) then
  1318. Result:=Length(FDisplays[false,True]);
  1319. end;
  1320. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  1321. var b : wordbool;
  1322. begin
  1323. b := AValue;
  1324. SetData(@b);
  1325. end;
  1326. procedure TBooleanField.SetAsString(const AValue: string);
  1327. Var Temp : string;
  1328. begin
  1329. Temp:=UpperCase(AValue);
  1330. if Temp='' then
  1331. Clear
  1332. else if pos(Temp, FDisplays[True,True])=1 then
  1333. SetAsBoolean(True)
  1334. else if pos(Temp, FDisplays[True,False])=1 then
  1335. SetAsBoolean(False)
  1336. else
  1337. DatabaseErrorFmt(SNotABoolean,[AValue]);
  1338. end;
  1339. procedure TBooleanField.SetVarValue(const AValue: Variant);
  1340. begin
  1341. SetAsBoolean(AValue);
  1342. end;
  1343. constructor TBooleanField.Create(AOwner: TComponent);
  1344. begin
  1345. Inherited Create(AOwner);
  1346. SetDataType(ftBoolean);
  1347. DisplayValues:='True;False';
  1348. end;
  1349. Procedure TBooleanField.SetDisplayValues(AValue : String);
  1350. Var I : longint;
  1351. begin
  1352. If FDisplayValues<>AValue then
  1353. begin
  1354. I:=Pos(';',AValue);
  1355. If (I<2) or (I=Length(AValue)) then
  1356. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  1357. FdisplayValues:=AValue;
  1358. // Store display values and their uppercase equivalents;
  1359. FDisplays[False,True]:=Copy(AValue,1,I-1);
  1360. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  1361. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  1362. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  1363. PropertyChanged(True);
  1364. end;
  1365. end;
  1366. { TDateTimeField }
  1367. procedure TDateTimeField.SetDisplayFormat(const AValue: string);
  1368. begin
  1369. if FDisplayFormat<>AValue then begin
  1370. FDisplayFormat:=AValue;
  1371. PropertyChanged(True);
  1372. end;
  1373. end;
  1374. function TDateTimeField.GetAsDateTime: TDateTime;
  1375. begin
  1376. If Not GetData(@Result,False) then
  1377. Result:=0;
  1378. end;
  1379. procedure TDateTimeField.SetVarValue(const AValue: Variant);
  1380. begin
  1381. SetAsDateTime(AValue);
  1382. end;
  1383. function TDateTimeField.GetAsVariant: Variant;
  1384. Var d : tDateTime;
  1385. begin
  1386. If Getdata(@d,False) then
  1387. Result := d
  1388. else
  1389. Result:=Null;
  1390. end;
  1391. function TDateTimeField.GetAsFloat: Double;
  1392. begin
  1393. Result:=GetAsdateTime;
  1394. end;
  1395. function TDateTimeField.GetAsString: string;
  1396. begin
  1397. GetText(Result,False);
  1398. end;
  1399. function TDateTimeField.GetDataSize: Word;
  1400. begin
  1401. Result:=SizeOf(TDateTime);
  1402. end;
  1403. procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean);
  1404. Var R : TDateTime;
  1405. F : String;
  1406. begin
  1407. If Not Getdata(@R,False) then
  1408. TheText:=''
  1409. else
  1410. begin
  1411. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  1412. F:=FDisplayFormat
  1413. else
  1414. Case DataType of
  1415. ftTime : F:=ShortTimeFormat;
  1416. ftDate : F:=ShortDateFormat;
  1417. else
  1418. F:='c'
  1419. end;
  1420. TheText:=FormatDateTime(F,R);
  1421. end;
  1422. end;
  1423. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  1424. begin
  1425. SetData(@Avalue,False);
  1426. end;
  1427. procedure TDateTimeField.SetAsFloat(AValue: Double);
  1428. begin
  1429. SetAsDateTime(AValue);
  1430. end;
  1431. procedure TDateTimeField.SetAsString(const AValue: string);
  1432. Var R : TDateTime;
  1433. begin
  1434. R:=StrToDateTime(AVAlue);
  1435. SetData(@R,False);
  1436. end;
  1437. constructor TDateTimeField.Create(AOwner: TComponent);
  1438. begin
  1439. Inherited Create(AOwner);
  1440. SetDataType(ftDateTime);
  1441. end;
  1442. { TDateField }
  1443. constructor TDateField.Create(AOwner: TComponent);
  1444. begin
  1445. Inherited Create(AOwner);
  1446. SetDataType(ftDate);
  1447. end;
  1448. { TTimeField }
  1449. constructor TTimeField.Create(AOwner: TComponent);
  1450. begin
  1451. Inherited Create(AOwner);
  1452. SetDataType(ftTime);
  1453. end;
  1454. procedure TTimeField.SetAsString(const AValue: string);
  1455. Var R : TDateTime;
  1456. begin
  1457. R:=StrToTime(AVAlue);
  1458. SetData(@R);
  1459. end;
  1460. { TBinaryField }
  1461. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  1462. begin
  1463. // Just check for really invalid stuff; actual size is
  1464. // dependent on the record...
  1465. If AValue<1 then
  1466. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1467. end;
  1468. function TBinaryField.GetAsString: string;
  1469. begin
  1470. Setlength(Result,DataSize);
  1471. GetData(Pointer(Result));
  1472. end;
  1473. procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean);
  1474. begin
  1475. TheText:=GetAsString;
  1476. end;
  1477. procedure TBinaryField.SetAsString(const AValue: string);
  1478. Var Buf : PChar;
  1479. Allocated : Boolean;
  1480. begin
  1481. Allocated:=False;
  1482. If Length(AVAlue)=DataSize then
  1483. Buf:=PChar(Avalue)
  1484. else
  1485. begin
  1486. GetMem(Buf,DataSize);
  1487. Move(Pchar(Avalue)[0],Buf^,DataSize);
  1488. Allocated:=True;
  1489. end;
  1490. SetData(Buf);
  1491. If Allocated then
  1492. FreeMem(Buf,DataSize);
  1493. end;
  1494. procedure TBinaryField.SetText(const AValue: string);
  1495. begin
  1496. SetAsString(Avalue);
  1497. end;
  1498. procedure TBinaryField.SetVarValue(const AValue: Variant);
  1499. begin
  1500. SetAsString(Avalue);
  1501. end;
  1502. constructor TBinaryField.Create(AOwner: TComponent);
  1503. begin
  1504. Inherited Create(AOwner);
  1505. end;
  1506. { TBytesField }
  1507. function TBytesField.GetDataSize: Word;
  1508. begin
  1509. Result:=Size;
  1510. end;
  1511. constructor TBytesField.Create(AOwner: TComponent);
  1512. begin
  1513. Inherited Create(AOwner);
  1514. SetDataType(ftBytes);
  1515. Size:=16;
  1516. end;
  1517. { TVarBytesField }
  1518. function TVarBytesField.GetDataSize: Word;
  1519. begin
  1520. Result:=Size+2;
  1521. end;
  1522. constructor TVarBytesField.Create(AOwner: TComponent);
  1523. begin
  1524. INherited Create(AOwner);
  1525. SetDataType(ftvarbytes);
  1526. Size:=16;
  1527. end;
  1528. { TBCDField }
  1529. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  1530. begin
  1531. If not (AValue in [1..4]) then
  1532. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1533. end;
  1534. function TBCDField.GetAsCurrency: Currency;
  1535. Var C : system.Currency;
  1536. begin
  1537. if GetData(@C) then
  1538. result := C;
  1539. end;
  1540. function TBCDField.GetAsVariant: Variant;
  1541. Var c : system.Currency;
  1542. begin
  1543. If GetData(@c) then
  1544. Result := c
  1545. else
  1546. Result:=Null;
  1547. end;
  1548. function TBCDField.GetAsFloat: Double;
  1549. begin
  1550. result := GetAsCurrency;
  1551. end;
  1552. function TBCDField.GetAsLongint: Longint;
  1553. begin
  1554. result := round(GetAsCurrency);
  1555. end;
  1556. function TBCDField.GetAsString: string;
  1557. var c : system.currency;
  1558. begin
  1559. If GetData(@C) then
  1560. Result:=CurrToStr(C)
  1561. else
  1562. Result:='';
  1563. end;
  1564. function TBCDField.GetValue(var AValue: Currency): Boolean;
  1565. begin
  1566. Result := GetData(@AValue);
  1567. end;
  1568. function TBCDField.GetDataSize: Word;
  1569. begin
  1570. result := sizeof(currency);
  1571. end;
  1572. function TBCDField.GetDefaultWidth: Longint;
  1573. begin
  1574. if precision > 0 then result := precision
  1575. else result := 10;
  1576. end;
  1577. procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean);
  1578. var
  1579. c : system.currency;
  1580. fmt: String;
  1581. begin
  1582. if GetData(@C) then begin
  1583. if aDisplayText or (FEditFormat='') then
  1584. fmt := FDisplayFormat
  1585. else
  1586. fmt := FEditFormat;
  1587. if fmt<>'' then
  1588. TheText := FormatFloat(fmt,C)
  1589. else if fCurrency then begin
  1590. if aDisplayText then
  1591. TheText := FloatToStrF(C, ffCurrency, FPrecision, 2{digits?})
  1592. else
  1593. TheText := FloatToStrF(C, ffFixed, FPrecision, 2{digits?});
  1594. end else
  1595. TheText := FloatToStrF(C, ffGeneral, FPrecision, 0{digits?});
  1596. end else
  1597. TheText := '';
  1598. end;
  1599. procedure TBCDField.SetAsCurrency(AValue: Currency);
  1600. begin
  1601. If CheckRange(AValue) then
  1602. setdata(@AValue)
  1603. else
  1604. RangeError(AValue,FMinValue,FMaxvalue);
  1605. end;
  1606. procedure TBCDField.SetVarValue(const AValue: Variant);
  1607. begin
  1608. SetAsCurrency(AValue);
  1609. end;
  1610. Function TBCDField.CheckRange(AValue : Currency) : Boolean;
  1611. begin
  1612. If (FMinValue<>0) or (FmaxValue<>0) then
  1613. Result:=(AValue>=FMinValue) and (AVAlue<=FMaxValue)
  1614. else
  1615. Result:=True;
  1616. end;
  1617. procedure TBCDField.SetAsFloat(AValue: Double);
  1618. begin
  1619. SetAsCurrency(AValue);
  1620. end;
  1621. procedure TBCDField.SetAsLongint(AValue: Longint);
  1622. begin
  1623. SetAsCurrency(AValue);
  1624. end;
  1625. procedure TBCDField.SetAsString(const AValue: string);
  1626. begin
  1627. SetAsCurrency(strtocurr(AValue));
  1628. end;
  1629. constructor TBCDField.Create(AOwner: TComponent);
  1630. begin
  1631. Inherited Create(AOwner);
  1632. FMaxvalue := 0;
  1633. FMinvalue := 0;
  1634. SetDataType(ftBCD);
  1635. FPrecision := 15;
  1636. Size:=4;
  1637. end;
  1638. { TBlobField }
  1639. procedure TBlobField.AssignTo(Dest: TPersistent);
  1640. begin
  1641. //!! To be implemented
  1642. end;
  1643. Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream;
  1644. begin
  1645. Result:=FDataset.CreateBlobStream(Self,Mode);
  1646. end;
  1647. procedure TBlobField.FreeBuffers;
  1648. begin
  1649. end;
  1650. function TBlobField.GetAsString: string;
  1651. var
  1652. Stream: TStream;
  1653. begin
  1654. Stream := GetBlobStream(bmRead);
  1655. if Stream <> nil then
  1656. With Stream do
  1657. try
  1658. SetLength(Result,Size);
  1659. ReadBuffer(Pointer(Result)^,Size);
  1660. finally
  1661. Free
  1662. end
  1663. else
  1664. Result := '(blob)';
  1665. end;
  1666. function TBlobField.GetBlobSize: Longint;
  1667. var
  1668. Stream: TStream;
  1669. begin
  1670. Stream := GetBlobStream(bmread);
  1671. if Stream <> nil then
  1672. With Stream do
  1673. try
  1674. Result:=Size;
  1675. finally
  1676. Free;
  1677. end
  1678. else
  1679. result := 0;
  1680. end;
  1681. function TBlobField.GetIsNull: Boolean;
  1682. begin
  1683. If Not Modified then
  1684. result:= inherited GetIsnull
  1685. else
  1686. With GetBlobStream(bmread) do
  1687. try
  1688. Result:=(Size=0);
  1689. Finally
  1690. Free;
  1691. end;
  1692. end;
  1693. procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean);
  1694. begin
  1695. TheText:=GetAsString;
  1696. end;
  1697. procedure TBlobField.SetAsString(const AValue: string);
  1698. begin
  1699. With GetBlobStream(bmwrite) do
  1700. try
  1701. WriteBuffer(Pointer(Avalue)^,Length(Avalue));
  1702. finally
  1703. Free;
  1704. end;
  1705. end;
  1706. procedure TBlobField.SetText(const AValue: string);
  1707. begin
  1708. SetAsString(AValue);
  1709. end;
  1710. procedure TBlobField.SetVarValue(const AValue: Variant);
  1711. begin
  1712. SetAsString(AValue);
  1713. end;
  1714. constructor TBlobField.Create(AOwner: TComponent);
  1715. begin
  1716. Inherited Create(AOWner);
  1717. SetDataType(ftBlob);
  1718. end;
  1719. procedure TBlobField.Assign(Source: TPersistent);
  1720. begin
  1721. //!! To be implemented
  1722. end;
  1723. procedure TBlobField.Clear;
  1724. begin
  1725. GetBlobStream(bmWrite).free;
  1726. end;
  1727. class function TBlobField.IsBlob: Boolean;
  1728. begin
  1729. Result:=True;
  1730. end;
  1731. procedure TBlobField.LoadFromFile(const FileName: string);
  1732. Var S : TFileStream;
  1733. begin
  1734. S:=TFileStream.Create(FileName,fmOpenRead);
  1735. try
  1736. LoadFromStream(S);
  1737. finally
  1738. S.Free;
  1739. end;
  1740. end;
  1741. procedure TBlobField.LoadFromStream(Stream: TStream);
  1742. begin
  1743. With GetBlobStream(bmWrite) do
  1744. Try
  1745. CopyFrom(Stream,0);
  1746. finally
  1747. Free;
  1748. end;
  1749. end;
  1750. procedure TBlobField.SaveToFile(const FileName: string);
  1751. Var S : TFileStream;
  1752. begin
  1753. S:=TFileStream.Create(FileName,fmCreate);
  1754. try
  1755. SaveToStream(S);
  1756. finally
  1757. S.Free;
  1758. end;
  1759. end;
  1760. procedure TBlobField.SaveToStream(Stream: TStream);
  1761. Var S : TStream;
  1762. begin
  1763. S:=GetBlobStream(bmRead);
  1764. Try
  1765. Stream.CopyFrom(S,0);
  1766. finally
  1767. S.Free;
  1768. end;
  1769. end;
  1770. procedure TBlobField.SetFieldType(AValue: TFieldType);
  1771. begin
  1772. If AValue in [Low(TBlobType)..High(TBlobType)] then
  1773. SetDatatype(Avalue);
  1774. end;
  1775. { TMemoField }
  1776. constructor TMemoField.Create(AOwner: TComponent);
  1777. begin
  1778. Inherited Create(AOwner);
  1779. SetDataType(ftMemo);
  1780. end;
  1781. { TGraphicField }
  1782. constructor TGraphicField.Create(AOwner: TComponent);
  1783. begin
  1784. Inherited Create(AOwner);
  1785. SetDataType(ftGraphic);
  1786. end;
  1787. { TFields }
  1788. Constructor TFields.Create(ADataset : TDataset);
  1789. begin
  1790. FDataSet:=ADataset;
  1791. FFieldList:=TList.Create;
  1792. FValidFieldKinds:=[fkData..fkInternalcalc];
  1793. end;
  1794. Destructor TFields.Destroy;
  1795. begin
  1796. if FFieldList <> nil then Clear;
  1797. FFieldList.Free;
  1798. inherited Destroy;
  1799. end;
  1800. Procedure Tfields.Changed;
  1801. begin
  1802. if (FDataSet <> nil) and not (csDestroying in FDataSet.ComponentState) then
  1803. FDataSet.DataEvent(deFieldListChange, 0);
  1804. If Assigned(FOnChange) then
  1805. FOnChange(Self);
  1806. end;
  1807. Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField);
  1808. begin
  1809. If Not (FieldKind in ValidFieldKinds) Then
  1810. DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]);
  1811. end;
  1812. Function Tfields.GetCount : Longint;
  1813. begin
  1814. Result:=FFieldList.Count;
  1815. end;
  1816. Function TFields.GetField (Index : longint) : TField;
  1817. begin
  1818. Result:=Tfield(FFieldList[Index]);
  1819. end;
  1820. procedure Tfields.SetField(Index: Integer; Value: TField);
  1821. begin
  1822. Fields[Index].Assign(Value);
  1823. end;
  1824. Procedure TFields.SetFieldIndex (Field : TField;Value : Integer);
  1825. Var Old : Longint;
  1826. begin
  1827. Old := FFieldList.indexOf(Field);
  1828. If Old=-1 then
  1829. Exit;
  1830. // Check value
  1831. If Value<0 Then Value:=0;
  1832. If Value>=Count then Value:=Count-1;
  1833. If Value<>Old then
  1834. begin
  1835. FFieldList.Delete(Old);
  1836. FFieldList.Insert(Value,Field);
  1837. Field.PropertyChanged(True);
  1838. Changed;
  1839. end;
  1840. end;
  1841. Procedure TFields.Add(Field : TField);
  1842. begin
  1843. CheckFieldName(Field.FieldName);
  1844. FFieldList.Add(Field);
  1845. Field.FFields:=Self;
  1846. Changed;
  1847. end;
  1848. Procedure TFields.CheckFieldName (Const Value : String);
  1849. begin
  1850. If FindField(Value)<>Nil then
  1851. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  1852. end;
  1853. Procedure TFields.CheckFieldNames (Const Value : String);
  1854. Var I : longint;
  1855. S,T : String;
  1856. begin
  1857. T:=Value;
  1858. Repeat
  1859. I:=Pos(';',T);
  1860. If I=0 Then I:=Length(T)+1;
  1861. S:=Copy(T,1,I-1);
  1862. Delete(T,1,I);
  1863. // Will raise an error if no such field...
  1864. FieldByName(S);
  1865. Until (T='');
  1866. end;
  1867. Procedure TFields.Clear;
  1868. begin
  1869. with FFieldList do
  1870. while Count > 0 do begin
  1871. TField(Last).FDataSet := Nil;
  1872. TField(Last).Free;
  1873. FFieldList.Delete(Count - 1);
  1874. end;
  1875. Changed;
  1876. end;
  1877. Function TFields.FindField (Const Value : String) : TField;
  1878. Var S : String;
  1879. I : longint;
  1880. begin
  1881. Result:=Nil;
  1882. S:=UpperCase(Value);
  1883. For I:=0 To FFieldList.Count-1 do
  1884. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1885. Begin
  1886. {$ifdef dsdebug}
  1887. Writeln ('Found field ',Value);
  1888. {$endif}
  1889. Result:=TField(FFieldList[I]);
  1890. Exit;
  1891. end;
  1892. end;
  1893. Function TFields.FieldByName (Const Value : String) : TField;
  1894. begin
  1895. Result:=FindField(Value);
  1896. If result=Nil then
  1897. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  1898. end;
  1899. Function TFields.FieldByNumber(FieldNo : Integer) : TField;
  1900. Var i : Longint;
  1901. begin
  1902. Result:=Nil;
  1903. For I:=0 to FFieldList.Count-1 do
  1904. If FieldNo=TField(FFieldList[I]).FieldNo then
  1905. begin
  1906. Result:=TField(FFieldList[i]);
  1907. Exit;
  1908. end;
  1909. end;
  1910. Procedure TFields.GetFieldNames (Values : TStrings);
  1911. Var i : longint;
  1912. begin
  1913. Values.Clear;
  1914. For I:=0 to FFieldList.Count-1 do
  1915. Values.Add(Tfield(FFieldList[I]).FieldName);
  1916. end;
  1917. Function TFields.IndexOf(Field : TField) : Longint;
  1918. begin
  1919. Result:=FFieldList.IndexOf(Field);
  1920. end;
  1921. procedure TFields.Remove(Value : TField);
  1922. begin
  1923. FFieldList.Remove(Value);
  1924. Value.FFields := nil;
  1925. Changed;
  1926. end;