home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / kolekce / d3456 / ALEXSOFT.ZIP / DBTools.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-09-29  |  21.4 KB  |  627 lines

  1. (*////////////////////////////////////////////////////////////////////////////
  2. //   Part of AlexSoft VCL/DLL Library.                                      //
  3. //   All rights reserved. (c) Copyright 1998.                               //
  4. //   Created by: Alex Rabichooc                                             //
  5. //**************************************************************************//
  6. //  Users of this unit must accept this disclaimer of warranty:             //
  7. //    "This unit is supplied as is. The author disclaims all warranties,    //
  8. //    expressed or implied, including, without limitation, the warranties   //
  9. //    of merchantability and of fitness for any purpose.                    //
  10. //    The author assumes no liability for damages, direct or                //
  11. //    consequential, which may result from the use of this unit."           //
  12. //                                                                          //
  13. //  This Unit is donated to the public as public domain.                    //
  14. //                                                                          //
  15. //  This Unit can be freely used and distributed in commercial and          //
  16. //  private environments provided this notice is not modified in any way.   //
  17. //                                                                          //
  18. //  If you do find this Unit handy and you feel guilty for using such a     //
  19. //  great product without paying someone - sorry :-)                        //
  20. //                                                                          //
  21. //  Please forward any comments or suggestions to Alex Rabichooc at:        //
  22. //                                                                          //
  23. //  a_rabichooc@yahoo.com or alex@carmez.mldnet.com                         //
  24. /////////////////////////////////////////////////////////////////////////////*)
  25.  
  26. unit dbtools;
  27.  
  28. interface
  29. uses db, Classes, Controls, dialogs, SysUtils, dbGrids, DBForms, dbTables, DBSearch;
  30.  
  31. procedure DoEditButtonClick(Field: TField; AOwner: TComponent);
  32. function ShowDate(AField: TField; Sender: TWinControl):Integer;
  33. function ShowSpr(AField: TField; AOwner: TComponent): Integer;
  34. function ShowMemo(AField: TField; AOwner: TComponent):Integer;
  35. function ShowImage(AField: TField; AOwner: TComponent):Integer;
  36. function ValidData(AField: TField): Boolean;
  37. procedure GetLookUpText(Sender: TField; var Text: String; DisplayText: Boolean);
  38. procedure SetLookUpText(Sender: TField; const Text: String);
  39. function IsLookUpField(AField: TField): Boolean;
  40. procedure SetFieldAttributes(Field: TField);
  41. function DBSearch(DataSet: TDataSet; AFields: TList; AField: TField;
  42.                                                   AOwner: TComponent; AKind: TSearchKind = skNormal): boolean;
  43. function InitDBForm(DataSet: TDataSet; Field: TField; AOwner: TComponent): Integer;
  44. procedure ReplaceField(AField: TField);
  45. function GetMasterSource(DataSet: TDataSet): TDataSource;
  46. procedure GetReplaceParams(AField: TField;
  47.                            var KeyField, LKeyField: TField;
  48.                            var LDataSet: TDataSet);
  49. procedure BindParams(DataSet: TDataSet; Query: TQuery);
  50.  
  51. type
  52.  
  53. TSender = class
  54. public
  55.     class procedure GetFieldText(Sender: TField; var Text: String; DisplayText: Boolean);
  56.     class procedure SetFieldText(Sender: TField; const Text: String);
  57.     class procedure ValidateData(Sender: TField);
  58. end;
  59.  
  60. TSenderClass = class of TSender;
  61.  
  62. implementation
  63. uses Windows, Graphics, StdUtils, FrmDSrce, dbConsts,
  64.      dbBoxGrd, Mask, Forms, grids, fmClndr, dbClient, dbPanel, fmSearch,
  65.      MemoEdit, {$IFDEF PROFI}ImagEdit{$ELSE}ImgEdt{$ENDIF}
  66.      {$IFNDEF VER120}
  67.      {$IFNDEF VER110},ADOdb
  68.      {$ENDIF}
  69.      {$ENDIF}
  70.      {$IFDEF VER140},Variants, MaskUtils
  71.      {$ENDIF};
  72.  
  73. procedure BindParams(DataSet: TDataSet; Query: TQuery);
  74. var
  75.   I: Integer;
  76.   Old: Boolean;
  77.   Param: TParam;
  78.   PName: string;
  79.   Field: TField;
  80.   Value: Variant;
  81. begin
  82.   if (DataSet = nil) or (Query = nil) then
  83.     Exit;
  84.   with Query do
  85.   begin
  86.     for I := 0 to Params.Count - 1 do
  87.     begin
  88.       Param := Params[I];
  89.       PName := Param.Name;
  90.       Old := CompareText(Copy(PName, 1, 4), 'OLD_') = 0;
  91.       if Old then System.Delete(PName, 1, 4);
  92.       Field := DataSet.FindField(PName);
  93.       if not Assigned(Field) then Continue;
  94.       if Old then Param.AssignFieldValue(Field, Field.OldValue) else
  95.       begin
  96.         Value := Field.NewValue;
  97.         if VarIsEmpty(Value) then Value := Field.OldValue;
  98.         Param.AssignFieldValue(Field, Value);
  99.       end;
  100.     end;
  101.   end;
  102. end;
  103.  
  104. function DBSearch(DataSet: TDataSet; AFields: TList; AField: TField;
  105.                     AOwner: TComponent; AKind: TSearchKind = skNormal): boolean;
  106. var Frm: TForm;
  107. begin
  108.    Result := False;
  109.    if DataSet = nil then
  110.      exit;
  111.    Frm := TSearchForm.CreateWithDataSet(AOwner, DataSet, AFields, AField);
  112.    if Frm.HandleAllocated then
  113.    try
  114.      if AKind <> skNormal then
  115.      with Frm as TSearchForm do
  116.      begin
  117.         ckExtendedSearch.Checked := True;
  118.         if AKind = skContext then
  119.            ckContext.Checked := True;
  120.      end;
  121.      Result := Frm.ShowModal = mrOK;
  122.    finally
  123.      Frm.Free;
  124.    end;
  125. end;
  126.  
  127. function InitDBForm(DataSet: TDataSet; Field: TField; AOwner: TComponent): Integer;
  128. const MinWidth = 340;
  129. var AWidth, AHeight: Integer;
  130.     Form: TDBForm;
  131.     FormClass: TDBFormClass;
  132.     FieldP: ^TField;
  133.  
  134.     procedure ChangePanelBounds;
  135.     var ALeft, ATop: Integer;
  136.     begin
  137.       with Form as TDefaultForm do
  138.       if (AWidth <> ClientWidth) or (AHeight <> ClientHeight) then
  139.       begin
  140.          ALeft := Left - (AWidth-Width) div 2;
  141.          ATop := Top-(AHeight-Height) div 2;
  142.          if ALeft < 0 then ALeft := 0;
  143.          if ATop < 0 then ATop := 0;
  144.          SetBounds(ALeft, ATop, AWidth, AHeight);
  145.       end;
  146.     end;
  147.  
  148. begin
  149.    try
  150.       if Screen.Cursor = crDefault then
  151.           Screen.Cursor := crHourGlass;
  152.  
  153.       FormClass := GetFormClass(DataSet);
  154.       if FormClass = nil then
  155.       begin
  156.          FormClass := TDefaultForm;
  157.       end;
  158.       Form := FindCreateForm(FormClass, GetFormCaption(DataSet), AOwner) as TDBForm;
  159.  
  160.       if Form is TDBForm then
  161.       with Form as TDBForm do
  162.       begin
  163.          FieldP := @ParentField;
  164.          FieldP^ := Field;
  165.       end;
  166.  
  167.       if Form is TDefaultForm then
  168.       with Form as TDefaultForm do
  169.       if DataSource.DataSet = nil then
  170.       begin
  171.          //DbPanel.Box.CreateMode := cmManual;
  172.          DataSource.DataSet := DataSet;
  173.          if GetMasterSource(DataSet) <> nil then
  174.             DBPanel.Orientation := orHorizontal;
  175.          Application.ProcessMessages;
  176.          //SendMessage(DBPanel.Handle, CN_STYLECHANGED, 0, 0);
  177.          AWidth := DbPanel.ActualWidth+Width-ClientWidth;
  178.          if AWidth > Screen.Width then AWidth := Screen.Width;
  179.          if AWidth < MinWidth then AWidth := MinWidth;
  180.          if DbPanel.Box.Visible then
  181.          begin
  182.             Width := AWidth;
  183.             DbPanel.Box.RefreshFields;
  184.             DbPanel.StoreFields := True;
  185.             DbPanel.BoxHeight := DbPanel.Box.ActualHeight + DbPanel.Box.OriginY;
  186.             AWidth := DbPanel.ActualWidth+Width-ClientWidth;
  187.          end;
  188.          AHeight := DbPanel.ActualHeight+paTop.Height+paBottom.Height+
  189.                                                          Height-ClientHeight;
  190.          if AHeight > Screen.Height then
  191.            AHeight := Screen.Height;
  192.          //if DbPanel.Box.Visible and DbPanel.Grid.Visible then
  193.                      Inc(AHeight, 3);
  194.          if not DbPanel.Box.Visible then
  195.             DbPanel.PanelStyle := psGrid;
  196.          ChangePanelBounds;
  197.       end;
  198.       if IsModalForm(DataSet) or (GetFormCaption(DataSet) = '') then
  199.          Result := Form.ShowModal
  200.         else
  201.         begin
  202.            Form.Show;
  203.            Result := 0;
  204.         end;
  205.    finally
  206.       Screen.Cursor := crDefault;
  207.    end;
  208. end;
  209.  
  210. procedure DoEditButtonClick(Field: TField; AOwner: TComponent);
  211. begin
  212.    if Field <> nil then
  213.    with Field do
  214.    begin
  215.       case DataType of
  216.         ftMemo, ftFmtMemo:
  217.            ShowMemo(Field, AOwner);
  218.         ftGraphic, ftTypedBinary, ftBlob:
  219.            ShowImage(Field, AOwner);
  220.         {$IFNDEF VER110}
  221.         ftDataSet:
  222.            InitDBForm((Field as TDataSetField).NestedDataSet, nil, AOwner);
  223.         {$ENDIF}
  224.         ftDate, ftDateTime:
  225.            if AOwner is TWinControl then
  226.                ShowDate(Field, AOwner as TWinControl)
  227.               else
  228.                ShowSpr(Field, AOwner);
  229.         else
  230.          ShowSpr(Field, AOwner);
  231.       end;
  232.    end;
  233. end;
  234.  
  235. function ShowDate(AField: TField; Sender: TWinControl):Integer;
  236. begin
  237.    Result := ord(CreateCalendar(AField, Sender));
  238. end;
  239.  
  240. procedure GetReplaceParams(AField: TField;
  241.                            var KeyField, LKeyField: TField;
  242.                            var LDataSet: TDataSet);
  243. var i: Integer;
  244. begin
  245.    LDataSet := nil;
  246.    LKeyField := nil;
  247.    KeyField := nil;
  248.    if AField <> nil then
  249.    begin
  250.       if IsLookUpField(AField) then
  251.       begin
  252.          KeyField := AField.DataSet.FindField(AField.KeyFields);
  253.          LDataSet := AField.LookupDataSet;
  254.          if LDataSet <> nil then
  255.             LKeyField := LDataSet.FindField(AField.LookUpKeyFields);
  256.       end
  257.        else
  258.        for i := 0 to AField.DataSet.FieldCount-1 do
  259.            with AField.DataSet.Fields[i] do
  260.              if UpperCase(KeyFields) = UpperCase(AField.FieldName) then
  261.              begin
  262.                 KeyField := AField.DataSet.FindField(KeyFields);
  263.                 LDataSet := LookupDataSet;
  264.                 if LDataSet <> nil then
  265.                   LKeyField := LDataSet.FindField(LookUpKeyFields);
  266.                 break;
  267.              end;
  268.    end;
  269. end;
  270.  
  271. procedure ReplaceField(AField: TField);
  272. var KeyField, LKeyField, ResultField: TField;
  273.     LDataSet: TDataSet;
  274.     AValue: Variant;
  275. begin
  276.    GetReplaceParams(AField, KeyField, LKeyField, LDataSet);
  277.    if (LDataSet <> nil) and (LKeyField <> nil) and (KeyField <> nil) and
  278.                        KeyField.CanModify and KeyField.DataSet.Active then
  279.    begin
  280.       with AField.DataSet do
  281.       begin
  282.          AValue := LKeyField.Value;
  283.          if not (AField.DataSet.State in [dsEdit, dsInsert]) then
  284.             if IsEmpty then
  285.                Insert
  286.               else
  287.                Edit;
  288.          KeyField.Value := AValue;
  289.          if AField.FieldKind = fkLookUp then
  290.          begin
  291.             ResultField := LDataSet.FindField(AField.LookupResultField);
  292.             if ResultField <> nil then
  293.               AField.Value := ResultField.Value;
  294.          end;
  295.       end;
  296.    end;
  297. end;
  298.  
  299. function ShowSpr(AField: TField; AOwner: TComponent): Integer;
  300. var KeyField, LKeyField: TField;
  301.     LDataSet: TDataSet;
  302. begin
  303.    try
  304.       Screen.Cursor := crHourGlass;
  305.       Result := -1;
  306.       GetReplaceParams(AField, KeyField, LKeyField, LDataSet);
  307.       if (LDataSet <> nil) and (LKeyField <> nil) and (KeyField <> nil) then
  308.       begin
  309.          if AOwner is TInplaceEdit then
  310.             AOwner := (AOwner as TInplaceEdit).Owner;
  311.          Result := InitDBForm(LDataSet, AField, AOwner);
  312.       end;
  313.    finally
  314.       Screen.Cursor := crDefault;
  315.    end;
  316. end;
  317.  
  318. function ShowMemo(AField: TField; AOwner: TComponent):Integer;
  319. var Form: TForm;
  320. begin
  321.    Result := 0;
  322.    if AField <> nil then
  323.    begin
  324.       Screen.Cursor := crHourGlass;
  325.       try
  326.         Form := TMemoEditor.CreateWithField(AOwner, AField);
  327.       finally
  328.         Screen.Cursor := crDefault;
  329.       end;
  330.       try
  331.         Form.ShowModal;
  332.         Result := 1;
  333.       finally
  334.         Form.Free;
  335.       end;
  336.    end;
  337. end;
  338.  
  339. function ShowImage(AField: TField; AOwner: TComponent):Integer;
  340. var Form: TForm;
  341. begin
  342.    Result := 0;
  343.    if AField <> nil then
  344.    begin
  345.       with AField.DataSet do
  346.         if (State = dsInsert) and not Modified then
  347.             Exit
  348.            else
  349.             CheckBrowseMode;
  350.       Screen.Cursor := crHourGlass;
  351.       try
  352.         Form := TImageEditor.CreateWithField(AOwner, AField);
  353.       finally
  354.         Screen.Cursor := crDefault;
  355.       end;
  356.       try
  357.         Form.ShowModal;
  358.         Result := 1;
  359.       finally
  360.         Form.Free;
  361.       end;
  362.    end;
  363. end;
  364.  
  365. function ValidData(AField: TField): Boolean;
  366. var KeyField, LKeyField: TField;
  367.     LDataSet: TDataSet;
  368.     i: Integer;
  369. begin
  370.    Result := True;
  371.    LDataSet := nil;
  372.    LKeyField := nil;
  373.    KeyField := nil;
  374.    if (AField <> nil) and (AField.DataSet <> nil) and (AField.DataSet.State in [dsEdit, dsInsert]) then
  375.    begin
  376.       if AField.FieldKind = fkLookUp then
  377.       begin
  378.          KeyField := AField.DataSet.FindField(AField.KeyFields);
  379.          LDataSet := AField.LookupDataSet;
  380.          if LDataSet <> nil then
  381.            LKeyField := LDataSet.FindField(AField.LookUpKeyFields);
  382.       end
  383.        else
  384.        for i := 0 to AField.DataSet.FieldCount-1 do
  385.            with AField.DataSet.Fields[i] do
  386.              if UpperCase(KeyFields) = UpperCase(AField.FieldName) then
  387.              begin
  388.                 KeyField := AField.DataSet.FindField(KeyFields);
  389.                 LDataSet := LookupDataSet;
  390.                 if LDataSet <> nil then
  391.                   LKeyField := LDataSet.FindField(LookUpKeyFields);
  392.                 break;
  393.              end;
  394.       if (LDataSet <> nil) and (LKeyField <> nil) and
  395.          (KeyField <> nil) and AField.DataSet.Active then
  396.       begin
  397.          Result := LDataSet.Locate(LKeyField.FieldName, KeyField.Value, []);
  398.          if Result then
  399.             for i := 0 to AField.DataSet.FieldCount-1 do
  400.             with AField.DataSet.Fields[i] do
  401.               if (UpperCase(KeyFields) = UpperCase(AField.FieldName)) and
  402.                  (LookUpDataSet <> nil) and
  403.                  (AField.DataSet.Fields[i]<> AField) then
  404.                  Value :=
  405.                      LookUpDataSet.Lookup(LookUpKeyFields, AField.Value, LookupResultField)
  406.          end
  407.    end;
  408. end;
  409.  
  410. procedure GetLookUpText(Sender: TField; var Text: String; DisplayText: Boolean);
  411. var Result: Variant;
  412.     AField: TField;
  413. begin
  414.    AField := Sender.DataSet.FindField(Sender.KeyFields);
  415.    if AField <> nil then
  416.    begin
  417.       Result := AField.Value;
  418.       With Sender do
  419.       if (LookUpDataSet <> nil) and LookUpDataSet.Active then
  420.          Result := LookUpDataSet.Lookup(LookUpKeyFields, Result, LookUpResultField);
  421.       Text := VarToStr(Result);
  422.    end;
  423. end;
  424.  
  425.  
  426. procedure SetLookUpText(Sender: TField; const Text: String);
  427. var Result: Variant;
  428.     AField: TField;
  429. begin
  430.    AField := Sender.DataSet.FindField(Sender.KeyFields);
  431.    if (AField <> nil) and
  432.       (Sender.DataSet <> nil) and
  433.       Sender.DataSet.Active then
  434.    begin
  435.       Result := Text;
  436.       With Sender do
  437.       if LookUpDataSet <> nil then
  438.          Result := LookUpDataSet.Lookup(LookUpResultField, Result, LookUpKeyFields);
  439.       AField.Value := Result;
  440.    end;
  441. end;
  442.  
  443. function IsLookUpField(AField: TField): Boolean;
  444. begin
  445.    with AField do
  446.    Result :=
  447.        (AField <> nil) and ((FieldKind = fkLookUp) or (LookUpDataSet <> nil));
  448. end;
  449.  
  450. procedure SetFieldAttributes(Field: TField);
  451. var AField, KeyField, LKeyField: TField;
  452.     LDataSet: TDataSet;
  453.     i: Integer;
  454. begin
  455.    if (Field <> nil) then
  456.    begin
  457.       if (Field.FieldKind = fkData) and
  458.          not Assigned(Field.OnValidate) and
  459.          {not (csLoading in Field.ComponentState) and}
  460.          not (csDesigning in Field.ComponentState) then
  461.       begin
  462.          //******************************??????????????????
  463.          LDataSet := nil;
  464.          LKeyField := nil;
  465.          KeyField := nil;
  466.          for i := 0 to Field.DataSet.FieldCount-1 do
  467.             with Field.DataSet.Fields[i] do
  468.             if UpperCase(KeyFields) = UpperCase(Field.FieldName) then
  469.             begin
  470.               KeyField := Field.DataSet.FindField(KeyFields);
  471.               LDataSet := LookupDataSet;
  472.               if LDataSet <> nil then
  473.                 LKeyField := LDataSet.FindField(LookUpKeyFields);
  474.               break;
  475.             end;
  476.          if (LDataSet <> nil) and (LKeyField <> nil) and
  477.             (KeyField <> nil) and Field.DataSet.Active then
  478.            //******************************??????????????????
  479.              Field.OnValidate := TSenderClass.ValidateData;
  480.       end;
  481.       if (Field is TNumericField) then
  482.       begin
  483.          Field.DisplayWidth := Length((Field as TNumericField).DisplayFormat);
  484.          if Field.DisplayWidth < Length((Field as TNumericField).EditFormat) then
  485.             Field.DisplayWidth := Length((Field as TNumericField).EditFormat);
  486.       end
  487.        else
  488.       if Field.EditMaskPtr = '' then
  489.           Field.DisplayWidth := -1
  490.          else
  491.           Field.DisplayWidth := Length(FormatMaskText(Field.EditMaskPtr, ''));
  492.       if (Field.FieldKind = fkData) and (Field.LookUpDataSet <> nil) then
  493.       begin
  494.          if not Assigned(Field.OnGetText) and
  495.             not Assigned(Field.OnSetText) and
  496.             {not (csLoading in Field.ComponentState) and}
  497.             not (csDesigning in Field.ComponentState) then
  498.          begin
  499.             Field.OnGetText := TSenderClass.GetFieldText;
  500.             Field.OnSetText := TSenderClass.SetFieldText;
  501.          end;
  502.          AField := Field.LookUpDataSet.FindField(Field.LookUpResultField);
  503.          if AField <> nil then
  504.          begin
  505.             if Field.EditMaskPtr = '' then
  506.                 Field.EditMask := AField.EditMaskPtr;
  507.             if (Field.DisplayWidth = Field.Size) or (Field.Size = 0) then
  508.             begin
  509.                Field.DisplayWidth := AField.DisplayWidth;
  510.                Field.Alignment := AField.Alignment;
  511.             end;
  512.             if Field.EditMaskPtr <> '' then
  513.                Field.DisplayWidth := Length(FormatMaskText(Field.EditMaskPtr, ''));
  514.             if (AField is TNumericField) then
  515.             begin
  516.                Field.DisplayWidth := Length((AField as TNumericField).DisplayFormat);
  517.                if Field.DisplayWidth < Length((AField as TNumericField).EditFormat) then
  518.                   Field.DisplayWidth := Length((AField as TNumericField).EditFormat);
  519.             end;
  520.          end;
  521.       end
  522.        else
  523.        if (@Field.OnGetText = @TSenderClass.GetFieldText) and
  524.                          (@Field.OnSetText = @TSenderClass.SetFieldText) then
  525.        begin
  526.           Field.OnSetText := nil;
  527.           Field.OnGetText := nil;
  528.        end;
  529.    end;
  530. end;
  531.  
  532. function GetMasterSource(DataSet: TDataSet): TDataSource;
  533. {$IFNDEF VER110}
  534. var i: Integer;
  535. {$ENDIF}
  536. begin
  537.    Result := nil;
  538.    if DataSet <> nil then
  539.    begin
  540.       {$IFNDEF VER120}
  541.       {$IFNDEF VER110}
  542.       if DataSet is TADOTable then
  543.         Result := (DataSet as TADOTable).MasterSource
  544.        else
  545.       if DataSet is TADOQuery then
  546.         Result := (DataSet as TADOQuery).DataSource
  547.        else
  548.       if DataSet is TADODataSet then
  549.         Result := (DataSet as TADODataSet).DataSource
  550.        else
  551.       if DataSet is TADOStoredProc then
  552.         Result := (DataSet as TADOStoredProc).DataSource
  553.        else
  554.       {$ENDIF}
  555.       {$ENDIF}
  556.       if DataSet is TTable then
  557.          Result := (DataSet as TTable).MasterSource
  558.         else
  559.       if DataSet is TQuery then
  560.          Result := (DataSet as TQuery).DataSource
  561.         else
  562.       if DataSet is TClientDataSet then
  563.       begin
  564.          Result := (DataSet as TClientDataSet).MasterSource;
  565.       end;
  566.       {$IFNDEF VER110}
  567.          if not Assigned(Result) then
  568.             if DataSet is TClientDataSet then
  569.             begin
  570.                if ((DataSet as TClientDataSet).DataSetField <> nil) and
  571.                   ((DataSet as TClientDataSet).DataSetField.DataSet <> nil) then
  572.                with (DataSet as TClientDataSet).DataSetField.DataSet.Owner do
  573.                for i := 0 to ComponentCount-1 do
  574.                   if (Components[i] is TDataSource) and
  575.                      ((Components[i] as TDataSource).DataSet =
  576.                           (DataSet as TClientDataSet).DataSetField.DataSet) then
  577.                   begin
  578.                      Result := Components[i] as TDataSource;
  579.                      break;
  580.                   end;
  581.             end
  582.              else
  583.             if DataSet is TNestedTable then
  584.             begin
  585.                if ((DataSet as TNestedTable).DataSetField <> nil) and
  586.                   ((DataSet as TNestedTable).DataSetField.DataSet <> nil) then
  587.                with (DataSet as TNestedTable).DataSetField.DataSet.Owner do
  588.                for i := 0 to ComponentCount-1 do
  589.                   if (Components[i] is TDataSource) and
  590.                      ((Components[i] as TDataSource).DataSet =
  591.                           (DataSet as TNestedTable).DataSetField.DataSet) then
  592.                   begin
  593.                      Result := Components[i] as TDataSource;
  594.                      break;
  595.                   end;
  596.             end;
  597.       {$ENDIF}
  598.    end;
  599. end;
  600.  
  601. {TSender}
  602. class procedure TSender.GetFieldText(Sender: TField; var Text: String;
  603.        DisplayText: Boolean);
  604. begin
  605.    GetLookUpText(Sender, Text, DisplayText);
  606. end;
  607.  
  608. class procedure TSender.SetFieldText(Sender: TField; const Text: String);
  609. begin
  610.    SetLookUpText(Sender, Text);
  611. end;
  612.  
  613. class procedure TSender.ValidateData(Sender: TField);
  614. begin
  615.    if not ValidData(Sender) then
  616.      if Sender.IsNULL and not Sender.Required then
  617.      begin
  618.         MessageBeep(MB_ICONASTERISK);
  619.         MessageDlg(SRecordNotFound, mtInformation, [mbOk], 0);
  620.      end
  621.       else
  622.        Raise EDataBaseError.Create(SRecordNotFound);
  623. end;
  624.  
  625. end.
  626.  
  627.