fields.inc 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561
  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. FFixedChar := False;
  764. Size:=20;
  765. end;
  766. class procedure TStringField.CheckTypeSize(AValue: Longint);
  767. begin
  768. If (AValue<1) or (AValue>dsMaxStringSize) Then
  769. databaseErrorFmt(SInvalidFieldSize,[AValue])
  770. end;
  771. function TStringField.GetAsBoolean: Boolean;
  772. Var S : String;
  773. begin
  774. S:=GetAsString;
  775. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  776. end;
  777. function TStringField.GetAsDateTime: TDateTime;
  778. begin
  779. Result:=StrToDateTime(GetAsString);
  780. end;
  781. function TStringField.GetAsFloat: Double;
  782. begin
  783. Result:=StrToFloat(GetAsString);
  784. end;
  785. function TStringField.GetAsLongint: Longint;
  786. begin
  787. Result:=StrToInt(GetAsString);
  788. end;
  789. function TStringField.GetAsString: string;
  790. begin
  791. If Not GetValue(Result) then
  792. Result:='';
  793. end;
  794. function TStringField.GetAsVariant: Variant;
  795. Var s : string;
  796. begin
  797. If GetValue(s) then
  798. Result:=s
  799. else
  800. Result:=Null;
  801. end;
  802. function TStringField.GetDataSize: Word;
  803. begin
  804. Result:=Size+1;
  805. end;
  806. function TStringField.GetDefaultWidth: Longint;
  807. begin
  808. result:=Size;
  809. end;
  810. Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  811. begin
  812. AText:=GetAsString;
  813. end;
  814. function TStringField.GetValue(var AValue: string): Boolean;
  815. Var Buf : TStringFieldBuffer;
  816. begin
  817. Result:=GetData(@Buf);
  818. If Result then
  819. AValue:=Buf;
  820. end;
  821. procedure TStringField.SetAsBoolean(AValue: Boolean);
  822. begin
  823. If AValue Then
  824. SetAsString('T')
  825. else
  826. SetAsString('F');
  827. end;
  828. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  829. begin
  830. SetAsString(DateTimeToStr(AValue));
  831. end;
  832. procedure TStringField.SetAsFloat(AValue: Double);
  833. begin
  834. SetAsString(FloatToStr(AValue));
  835. end;
  836. procedure TStringField.SetAsLongint(AValue: Longint);
  837. begin
  838. SetAsString(intToStr(AValue));
  839. end;
  840. procedure TStringField.SetAsString(const AValue: string);
  841. Const NullByte : char = #0;
  842. begin
  843. IF Length(AValue)=0 then
  844. SetData(@NullByte)
  845. else
  846. SetData(@AValue[1]);
  847. end;
  848. procedure TStringField.SetVarValue(const AValue: Variant);
  849. begin
  850. SetAsString(AValue);
  851. end;
  852. { ---------------------------------------------------------------------
  853. TNumericField
  854. ---------------------------------------------------------------------}
  855. constructor TNumericField.Create(AOwner: TComponent);
  856. begin
  857. Inherited Create(AOwner);
  858. AlignMent:=taRightJustify;
  859. end;
  860. procedure TNumericField.RangeError(AValue, Min, Max: Double);
  861. begin
  862. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  863. end;
  864. procedure TNumericField.SetDisplayFormat(const AValue: string);
  865. begin
  866. If FDisplayFormat<>AValue then
  867. begin
  868. FDisplayFormat:=AValue;
  869. PropertyChanged(True);
  870. end;
  871. end;
  872. procedure TNumericField.SetEditFormat(const AValue: string);
  873. begin
  874. If FEDitFormat<>AValue then
  875. begin
  876. FEDitFormat:=AVAlue;
  877. PropertyChanged(True);
  878. end;
  879. end;
  880. { ---------------------------------------------------------------------
  881. TLongintField
  882. ---------------------------------------------------------------------}
  883. constructor TLongintField.Create(AOwner: TComponent);
  884. begin
  885. Inherited Create(AOwner);
  886. SetDatatype(ftinteger);
  887. FMinRange:=Low(LongInt);
  888. FMaxRange:=High(LongInt);
  889. FValidchars:=['+','-','0'..'9'];
  890. end;
  891. function TLongintField.GetAsFloat: Double;
  892. begin
  893. Result:=GetAsLongint;
  894. end;
  895. function TLongintField.GetAsLongint: Longint;
  896. begin
  897. If Not GetValue(Result) then
  898. Result:=0;
  899. end;
  900. function TLongintField.GetAsVariant: Variant;
  901. Var L : Longint;
  902. begin
  903. If GetValue(L) then
  904. Result:=L
  905. else
  906. Result:=Null;
  907. end;
  908. function TLongintField.GetAsString: string;
  909. Var L : Longint;
  910. begin
  911. If GetValue(L) then
  912. Result:=IntTostr(L)
  913. else
  914. Result:='';
  915. end;
  916. function TLongintField.GetDataSize: Word;
  917. begin
  918. Result:=SizeOf(Longint);
  919. end;
  920. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  921. var l : longint;
  922. fmt : string;
  923. begin
  924. Atext:='';
  925. If Not GetValue(l) then exit;
  926. If ADisplayText or (FEditFormat='') then
  927. fmt:=FDisplayFormat
  928. else
  929. fmt:=FEditFormat;
  930. If length(fmt)<>0 then
  931. AText:=FormatFloat(fmt,L)
  932. else
  933. Str(L,AText);
  934. end;
  935. function TLongintField.GetValue(var AValue: Longint): Boolean;
  936. Var L : Longint;
  937. P : PLongint;
  938. begin
  939. P:=@L;
  940. Result:=GetData(P);
  941. If Result then
  942. Case Datatype of
  943. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  944. ftword : Avalue:=Pword(P)^;
  945. ftsmallint : AValue:=PSmallint(P)^;
  946. end;
  947. end;
  948. procedure TLongintField.SetAsFloat(AValue: Double);
  949. begin
  950. SetAsLongint(Round(Avalue));
  951. end;
  952. procedure TLongintField.SetAsLongint(AValue: Longint);
  953. begin
  954. If CheckRange(AValue) then
  955. SetData(@AValue)
  956. else
  957. RangeError(Avalue,FMinrange,FMaxRange);
  958. end;
  959. procedure TLongintField.SetVarValue(const AValue: Variant);
  960. begin
  961. SetAsLongint(AValue);
  962. end;
  963. procedure TLongintField.SetAsString(const AValue: string);
  964. Var L,Code : longint;
  965. begin
  966. If length(AValue)=0 then
  967. Clear
  968. else
  969. begin
  970. Val(AVAlue,L,Code);
  971. If Code=0 then
  972. SetAsLongint(L)
  973. else
  974. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  975. end;
  976. end;
  977. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  978. begin
  979. result := true;
  980. if (FMaxValue=0) then
  981. begin
  982. if (AValue>FMaxRange) Then result := false;
  983. end
  984. else
  985. if AValue>FMaxValue then result := false;
  986. if (FMinValue=0) then
  987. begin
  988. if (AValue<FMinRange) Then result := false;
  989. end
  990. else
  991. if AValue<FMinValue then result := false;
  992. end;
  993. Procedure TLongintField.SetMaxValue (AValue : longint);
  994. begin
  995. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  996. FMaxValue:=AValue
  997. else
  998. RangeError(AValue,FMinRange,FMaxRange);
  999. end;
  1000. Procedure TLongintField.SetMinValue (AValue : longint);
  1001. begin
  1002. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1003. FMinValue:=AValue
  1004. else
  1005. RangeError(AValue,FMinRange,FMaxRange);
  1006. end;
  1007. { ---------------------------------------------------------------------
  1008. TLargeintField
  1009. ---------------------------------------------------------------------}
  1010. constructor TLargeintField.Create(AOwner: TComponent);
  1011. begin
  1012. Inherited Create(AOwner);
  1013. SetDatatype(ftLargeint);
  1014. FMinRange:=Low(Largeint);
  1015. FMaxRange:=High(Largeint);
  1016. FValidchars:=['+','-','0'..'9'];
  1017. end;
  1018. function TLargeintField.GetAsFloat: Double;
  1019. begin
  1020. Result:=GetAsLargeint;
  1021. end;
  1022. function TLargeintField.GetAsLargeint: Largeint;
  1023. begin
  1024. If Not GetValue(Result) then
  1025. Result:=0;
  1026. end;
  1027. function TLargeIntField.GetAsVariant: Variant;
  1028. Var L : Largeint;
  1029. begin
  1030. If GetValue(L) then
  1031. Result:=L
  1032. else
  1033. Result:=Null;
  1034. end;
  1035. function TLargeintField.GetAsLongint: Longint;
  1036. begin
  1037. Result:=GetAsLargeint;
  1038. end;
  1039. function TLargeintField.GetAsString: string;
  1040. Var L : Largeint;
  1041. begin
  1042. If GetValue(L) then
  1043. Result:=IntTostr(L)
  1044. else
  1045. Result:='';
  1046. end;
  1047. function TLargeintField.GetDataSize: Word;
  1048. begin
  1049. Result:=SizeOf(Largeint);
  1050. end;
  1051. procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean);
  1052. var l : largeint;
  1053. fmt : string;
  1054. begin
  1055. Atext:='';
  1056. If Not GetValue(l) then exit;
  1057. If ADisplayText or (FEditFormat='') then
  1058. fmt:=FDisplayFormat
  1059. else
  1060. fmt:=FEditFormat;
  1061. If length(fmt)<>0 then
  1062. AText:=FormatFloat(fmt,L)
  1063. else
  1064. Str(L,AText);
  1065. end;
  1066. function TLargeintField.GetValue(var AValue: Largeint): Boolean;
  1067. type
  1068. PLargeint = ^Largeint;
  1069. Var P : PLargeint;
  1070. begin
  1071. P:=@AValue;
  1072. Result:=GetData(P);
  1073. end;
  1074. procedure TLargeintField.SetAsFloat(AValue: Double);
  1075. begin
  1076. SetAsLargeint(Round(Avalue));
  1077. end;
  1078. procedure TLargeintField.SetAsLargeint(AValue: Largeint);
  1079. begin
  1080. If CheckRange(AValue) then
  1081. SetData(@AValue)
  1082. else
  1083. RangeError(Avalue,FMinrange,FMaxRange);
  1084. end;
  1085. procedure TLargeintField.SetAsLongint(AValue: Longint);
  1086. begin
  1087. SetAsLargeint(Avalue);
  1088. end;
  1089. procedure TLargeintField.SetAsString(const AValue: string);
  1090. Var L : largeint;
  1091. code : longint;
  1092. begin
  1093. If length(AValue)=0 then
  1094. Clear
  1095. else
  1096. begin
  1097. Val(AVAlue,L,Code);
  1098. If Code=0 then
  1099. SetAsLargeint(L)
  1100. else
  1101. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  1102. end;
  1103. end;
  1104. procedure TLargeintField.SetVarValue(const AValue: Variant);
  1105. begin
  1106. SetAsLargeint(AValue);
  1107. end;
  1108. Function TLargeintField.CheckRange(AValue : largeint) : Boolean;
  1109. begin
  1110. result := true;
  1111. if (FMaxValue=0) then
  1112. begin
  1113. if (AValue>FMaxRange) Then result := false;
  1114. end
  1115. else
  1116. if AValue>FMaxValue then result := false;
  1117. if (FMinValue=0) then
  1118. begin
  1119. if (AValue<FMinRange) Then result := false;
  1120. end
  1121. else
  1122. if AValue<FMinValue then result := false;
  1123. end;
  1124. Procedure TLargeintField.SetMaxValue (AValue : largeint);
  1125. begin
  1126. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1127. FMaxValue:=AValue
  1128. else
  1129. RangeError(AValue,FMinRange,FMaxRange);
  1130. end;
  1131. Procedure TLargeintField.SetMinValue (AValue : largeint);
  1132. begin
  1133. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1134. FMinValue:=AValue
  1135. else
  1136. RangeError(AValue,FMinRange,FMaxRange);
  1137. end;
  1138. { TSmallintField }
  1139. function TSmallintField.GetDataSize: Word;
  1140. begin
  1141. Result:=SizeOf(SmallInt);
  1142. end;
  1143. constructor TSmallintField.Create(AOwner: TComponent);
  1144. begin
  1145. inherited Create(AOwner);
  1146. SetDataType(ftSmallInt);
  1147. FMinRange:=-32768;
  1148. FMaxRange:=32767;
  1149. end;
  1150. { TWordField }
  1151. function TWordField.GetDataSize: Word;
  1152. begin
  1153. Result:=SizeOf(Word);
  1154. end;
  1155. constructor TWordField.Create(AOwner: TComponent);
  1156. begin
  1157. inherited Create(AOwner);
  1158. SetDataType(ftWord);
  1159. FMinRange:=0;
  1160. FMaxRange:=65535;
  1161. FValidchars:=['+','0'..'9'];
  1162. end;
  1163. { TAutoIncField }
  1164. constructor TAutoIncField.Create(AOwner: TComponent);
  1165. begin
  1166. Inherited Create(AOWner);
  1167. SetDataType(ftAutoInc);
  1168. FReadOnly:=True;
  1169. end;
  1170. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  1171. begin
  1172. DataBaseError(SCantSetAutoIncfields);
  1173. end;
  1174. { TFloatField }
  1175. function TFloatField.GetAsFloat: Double;
  1176. begin
  1177. If Not GetData(@Result) Then
  1178. Result:=0.0;
  1179. end;
  1180. function TFloatField.GetAsVariant: Variant;
  1181. Var f : Double;
  1182. begin
  1183. If GetData(@f) then
  1184. Result := f
  1185. else
  1186. Result:=Null;
  1187. end;
  1188. function TFloatField.GetAsLongint: Longint;
  1189. begin
  1190. Result:=Round(GetAsFloat);
  1191. end;
  1192. function TFloatField.GetAsString: string;
  1193. Var R : Double;
  1194. begin
  1195. If GetData(@R) then
  1196. Result:=FloatToStr(R)
  1197. else
  1198. Result:='';
  1199. end;
  1200. function TFloatField.GetDataSize: Word;
  1201. begin
  1202. Result:=SizeOf(Double);
  1203. end;
  1204. procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean);
  1205. Var
  1206. fmt : string;
  1207. E : Double;
  1208. begin
  1209. TheText:='';
  1210. If Not GetData(@E) then exit;
  1211. If ADisplayText or (Length(FEditFormat) = 0) Then
  1212. Fmt:=FDisplayFormat
  1213. else
  1214. Fmt:=FEditFormat;
  1215. If fmt<>'' then
  1216. TheText:=FormatFloat(fmt,E)
  1217. else
  1218. TheText:=FloatToStrF(E,ffgeneral,FPrecision,0);
  1219. end;
  1220. procedure TFloatField.SetAsFloat(AValue: Double);
  1221. begin
  1222. If CheckRange(AValue) then
  1223. SetData(@Avalue)
  1224. else
  1225. RangeError(AValue,FMinValue,FMaxValue);
  1226. end;
  1227. procedure TFloatField.SetAsLongint(AValue: Longint);
  1228. begin
  1229. SetAsFloat(Avalue);
  1230. end;
  1231. procedure TFloatField.SetAsString(const AValue: string);
  1232. Var R : Double;
  1233. begin
  1234. try
  1235. R := StrToFloat(AValue);
  1236. SetAsFloat(R);
  1237. except
  1238. DatabaseErrorFmt(SNotAFloat, [AValue]);
  1239. end;
  1240. end;
  1241. procedure TFloatField.SetVarValue(const AValue: Variant);
  1242. begin
  1243. SetAsFloat(Avalue);
  1244. end;
  1245. constructor TFloatField.Create(AOwner: TComponent);
  1246. begin
  1247. Inherited Create(AOwner);
  1248. SetDatatype(ftfloat);
  1249. FPrecision:=15;
  1250. FValidChars := [DecimalSeparator, '+', '-', '0'..'9', 'E', 'e'];
  1251. end;
  1252. Function TFloatField.CheckRange(AValue : Double) : Boolean;
  1253. begin
  1254. If (FMinValue<>0) or (FmaxValue<>0) then
  1255. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  1256. else
  1257. Result:=True;
  1258. end;
  1259. { TCurrencyField }
  1260. Constructor TCurrencyField.Create(AOwner: TComponent);
  1261. begin
  1262. inherited Create(AOwner);
  1263. SetDataType(ftCurrency);
  1264. end;
  1265. procedure TCurrencyField.GetText(var TheText: string; ADisplayText: Boolean);
  1266. Var
  1267. fmt : string;
  1268. ff: TFloatFormat;
  1269. E : Double;
  1270. begin
  1271. TheText:='';
  1272. If Not GetData(@E) then exit;
  1273. If ADisplayText or (Length(FEditFormat) = 0) Then
  1274. Fmt:=FDisplayFormat
  1275. else
  1276. Fmt:=FEditFormat;
  1277. if ADisplayText then
  1278. ff := ffCurrency
  1279. else
  1280. ff := ffFixed;
  1281. If fmt<>'' then
  1282. TheText:=FormatFloat(fmt, E)
  1283. else
  1284. TheText:=FloatToStrF(E, ff, FPrecision, CurrencyDecimals);
  1285. end;
  1286. { TBooleanField }
  1287. function TBooleanField.GetAsBoolean: Boolean;
  1288. var b : wordbool;
  1289. begin
  1290. If GetData(@b) then
  1291. result := b
  1292. else
  1293. Result:=False;
  1294. end;
  1295. function TBooleanField.GetAsVariant: Variant;
  1296. Var b : wordbool;
  1297. begin
  1298. If GetData(@b) then
  1299. Result := b
  1300. else
  1301. Result:=Null;
  1302. end;
  1303. function TBooleanField.GetAsString: string;
  1304. Var B : wordbool;
  1305. begin
  1306. If Getdata(@B) then
  1307. Result:=FDisplays[False,B]
  1308. else
  1309. result:='';
  1310. end;
  1311. function TBooleanField.GetDataSize: Word;
  1312. begin
  1313. Result:=SizeOf(wordBool);
  1314. end;
  1315. function TBooleanField.GetDefaultWidth: Longint;
  1316. begin
  1317. Result:=Length(FDisplays[false,false]);
  1318. If Result<Length(FDisplays[false,True]) then
  1319. Result:=Length(FDisplays[false,True]);
  1320. end;
  1321. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  1322. var b : wordbool;
  1323. begin
  1324. b := AValue;
  1325. SetData(@b);
  1326. end;
  1327. procedure TBooleanField.SetAsString(const AValue: string);
  1328. Var Temp : string;
  1329. begin
  1330. Temp:=UpperCase(AValue);
  1331. if Temp='' then
  1332. Clear
  1333. else if pos(Temp, FDisplays[True,True])=1 then
  1334. SetAsBoolean(True)
  1335. else if pos(Temp, FDisplays[True,False])=1 then
  1336. SetAsBoolean(False)
  1337. else
  1338. DatabaseErrorFmt(SNotABoolean,[AValue]);
  1339. end;
  1340. procedure TBooleanField.SetVarValue(const AValue: Variant);
  1341. begin
  1342. SetAsBoolean(AValue);
  1343. end;
  1344. constructor TBooleanField.Create(AOwner: TComponent);
  1345. begin
  1346. Inherited Create(AOwner);
  1347. SetDataType(ftBoolean);
  1348. DisplayValues:='True;False';
  1349. end;
  1350. Procedure TBooleanField.SetDisplayValues(AValue : String);
  1351. Var I : longint;
  1352. begin
  1353. If FDisplayValues<>AValue then
  1354. begin
  1355. I:=Pos(';',AValue);
  1356. If (I<2) or (I=Length(AValue)) then
  1357. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  1358. FdisplayValues:=AValue;
  1359. // Store display values and their uppercase equivalents;
  1360. FDisplays[False,True]:=Copy(AValue,1,I-1);
  1361. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  1362. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  1363. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  1364. PropertyChanged(True);
  1365. end;
  1366. end;
  1367. { TDateTimeField }
  1368. procedure TDateTimeField.SetDisplayFormat(const AValue: string);
  1369. begin
  1370. if FDisplayFormat<>AValue then begin
  1371. FDisplayFormat:=AValue;
  1372. PropertyChanged(True);
  1373. end;
  1374. end;
  1375. function TDateTimeField.GetAsDateTime: TDateTime;
  1376. begin
  1377. If Not GetData(@Result,False) then
  1378. Result:=0;
  1379. end;
  1380. procedure TDateTimeField.SetVarValue(const AValue: Variant);
  1381. begin
  1382. SetAsDateTime(AValue);
  1383. end;
  1384. function TDateTimeField.GetAsVariant: Variant;
  1385. Var d : tDateTime;
  1386. begin
  1387. If Getdata(@d,False) then
  1388. Result := d
  1389. else
  1390. Result:=Null;
  1391. end;
  1392. function TDateTimeField.GetAsFloat: Double;
  1393. begin
  1394. Result:=GetAsdateTime;
  1395. end;
  1396. function TDateTimeField.GetAsString: string;
  1397. begin
  1398. GetText(Result,False);
  1399. end;
  1400. function TDateTimeField.GetDataSize: Word;
  1401. begin
  1402. Result:=SizeOf(TDateTime);
  1403. end;
  1404. procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean);
  1405. Var R : TDateTime;
  1406. F : String;
  1407. begin
  1408. If Not Getdata(@R,False) then
  1409. TheText:=''
  1410. else
  1411. begin
  1412. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  1413. F:=FDisplayFormat
  1414. else
  1415. Case DataType of
  1416. ftTime : F:=ShortTimeFormat;
  1417. ftDate : F:=ShortDateFormat;
  1418. else
  1419. F:='c'
  1420. end;
  1421. TheText:=FormatDateTime(F,R);
  1422. end;
  1423. end;
  1424. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  1425. begin
  1426. SetData(@Avalue,False);
  1427. end;
  1428. procedure TDateTimeField.SetAsFloat(AValue: Double);
  1429. begin
  1430. SetAsDateTime(AValue);
  1431. end;
  1432. procedure TDateTimeField.SetAsString(const AValue: string);
  1433. Var R : TDateTime;
  1434. begin
  1435. R:=StrToDateTime(AVAlue);
  1436. SetData(@R,False);
  1437. end;
  1438. constructor TDateTimeField.Create(AOwner: TComponent);
  1439. begin
  1440. Inherited Create(AOwner);
  1441. SetDataType(ftDateTime);
  1442. end;
  1443. { TDateField }
  1444. constructor TDateField.Create(AOwner: TComponent);
  1445. begin
  1446. Inherited Create(AOwner);
  1447. SetDataType(ftDate);
  1448. end;
  1449. { TTimeField }
  1450. constructor TTimeField.Create(AOwner: TComponent);
  1451. begin
  1452. Inherited Create(AOwner);
  1453. SetDataType(ftTime);
  1454. end;
  1455. procedure TTimeField.SetAsString(const AValue: string);
  1456. Var R : TDateTime;
  1457. begin
  1458. R:=StrToTime(AVAlue);
  1459. SetData(@R);
  1460. end;
  1461. { TBinaryField }
  1462. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  1463. begin
  1464. // Just check for really invalid stuff; actual size is
  1465. // dependent on the record...
  1466. If AValue<1 then
  1467. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1468. end;
  1469. function TBinaryField.GetAsString: string;
  1470. begin
  1471. Setlength(Result,DataSize);
  1472. GetData(Pointer(Result));
  1473. end;
  1474. procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean);
  1475. begin
  1476. TheText:=GetAsString;
  1477. end;
  1478. procedure TBinaryField.SetAsString(const AValue: string);
  1479. Var Buf : PChar;
  1480. Allocated : Boolean;
  1481. begin
  1482. Allocated:=False;
  1483. If Length(AVAlue)=DataSize then
  1484. Buf:=PChar(Avalue)
  1485. else
  1486. begin
  1487. GetMem(Buf,DataSize);
  1488. Move(Pchar(Avalue)[0],Buf^,DataSize);
  1489. Allocated:=True;
  1490. end;
  1491. SetData(Buf);
  1492. If Allocated then
  1493. FreeMem(Buf,DataSize);
  1494. end;
  1495. procedure TBinaryField.SetText(const AValue: string);
  1496. begin
  1497. SetAsString(Avalue);
  1498. end;
  1499. procedure TBinaryField.SetVarValue(const AValue: Variant);
  1500. begin
  1501. SetAsString(Avalue);
  1502. end;
  1503. constructor TBinaryField.Create(AOwner: TComponent);
  1504. begin
  1505. Inherited Create(AOwner);
  1506. end;
  1507. { TBytesField }
  1508. function TBytesField.GetDataSize: Word;
  1509. begin
  1510. Result:=Size;
  1511. end;
  1512. constructor TBytesField.Create(AOwner: TComponent);
  1513. begin
  1514. Inherited Create(AOwner);
  1515. SetDataType(ftBytes);
  1516. Size:=16;
  1517. end;
  1518. { TVarBytesField }
  1519. function TVarBytesField.GetDataSize: Word;
  1520. begin
  1521. Result:=Size+2;
  1522. end;
  1523. constructor TVarBytesField.Create(AOwner: TComponent);
  1524. begin
  1525. INherited Create(AOwner);
  1526. SetDataType(ftvarbytes);
  1527. Size:=16;
  1528. end;
  1529. { TBCDField }
  1530. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  1531. begin
  1532. If not (AValue in [1..4]) then
  1533. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1534. end;
  1535. function TBCDField.GetAsCurrency: Currency;
  1536. begin
  1537. if not GetData(@Result) then
  1538. result := 0;
  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(system.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) and FDataset.Active 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;