The text of the Memo will not be saved to the database.

Dear experts,

I have made a little example that loads and saves the Treeview-nodes to a database.
Only the saving part doesn't work 100%. Because when I put text in the memo. And then
press the Save-button, the text have to be saved to the column of the database.
and that doesn't work. When i put text in the data-column of the database and then run
my example and the press the Load-button the text appears in the memo. So the loading-part
works but not the saving-part. Who can help me?

I have put the example on my site: http://members.home.nl/peterkiers/
You see a floppy-disk, doubleclick on it. To download the example.


Greetings, peter kiers


unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, ComCtrls, StdCtrls, ImgList, ExtCtrls;
 
type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Splitter1: TSplitter;
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    ImageList1: TImageList;
    ADOQuery1: TADOQuery;
    ADOConnection1: TADOConnection;
    Memo1: TMemo;
    FolderBtn: TButton;
    FileBtn: TButton;
    procedure FolderBtnClick(Sender: TObject);
    procedure FileBtnClick(Sender: TObject);
    procedure TreeView1Changing(Sender: TObject; Node: TTreeNode;
      var AllowChange: Boolean);
    procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure savetree(t: ttreeview);
    procedure loadtree(t: TTreeView);
    procedure saveNode(n: TTreeNode);
    function findNode(t:TTreeView; id: integer): TTreeNode;
    procedure AddItem(aText: string; aIndex: Integer; aParent: TTreeNode);
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
type
  TItem = class(TObject)
  private
    fStatus: byte;
    fParentID: integer;
    fNodeText: string;
    fID: integer;
    fData: string;
    fSaver: TAdoQuery;
    fChanged: Boolean;        
    fSaveImmediate: boolean;
    fIsNew: Boolean;
    fImageIndex: integer;
    procedure SetData(const Value: string);
    procedure SetNodeText(const Value: string);
    procedure SetParentID(const Value: integer);
    procedure SetStatus(const Value: byte);
    procedure SetImageIndex(const Value: integer);
  protected
    procedure Changed; dynamic;
  public
    constructor Create(aSaver: TAdoQuery; AId, AParentID: integer; AStatus: byte);
    constructor LoadFromDataset(aSaver: TAdoQuery);
    procedure BeginUpdate;
    procedure EndUpdate;
    procedure Delete;
    procedure Save;
  published
    property ID: integer read fID write fID;
    property ParentID: integer read fParentID write SetParentID;
    property ImageIndex: integer read fImageIndex write SetImageIndex;
    property Status: byte read FStatus write SetStatus;
    property Data: string read fData write SetData;
    property NodeText: string read fNodeText write SetNodeText;
  end;
 
{ TItem }
 
procedure TItem.BeginUpdate;
begin
  fSaveImmediate := false;                 
end;
(*---------------------------------------------------*)
procedure TItem.Changed;
begin
  fChanged := True;
  if fSaveImmediate then Save;
end;
(*---------------------------------------------------*)
constructor TItem.Create(aSaver: TAdoQuery; AId, AParentID: integer;
  AStatus: byte);
begin
  inherited Create;
  fChanged := False;
  fSaveImmediate := True;
  fIsNew := True;
  fSaver := aSaver;
  fID := AID;
  fParentID := AParentID;
  fStatus := AStatus;
  fNodeText := '';
  fData := '';
end;
(*---------------------------------------------------*)
procedure TItem.Delete;
begin
//
end;
(*---------------------------------------------------*)
procedure TItem.EndUpdate;
begin
  fSaveImmediate := True;
  if fChanged then Save;
end;
(*---------------------------------------------------*)
constructor TItem.LoadFromDataset(aSaver: TAdoQuery);
begin
  Create(aSaver, 0, 0, 0);
  if not aSaver.IsEmpty then
  begin
    fId := aSaver.FieldByName('ID').AsInteger;
    fParentID := aSaver.FieldByName('PARENT').AsInteger;
    fStatus := aSaver.FieldByName('STATUS').AsInteger;
    fNodeText := aSaver.FieldByName('NAME').AsString;
    if aSaver.FindField('DATA') <> nil then
      fData := aSaver.FieldByName('DATA').AsString;
    fImageIndex := aSaver.FieldByName('IMAGE_INDEX').AsInteger;
    fIsNew := False;
  end;
end;
(*---------------------------------------------------*)
procedure TItem.Save;
begin
  if fIsNew then
    fSaver.SQL.Text :=
      'insert into tree (parent, name, status, image_index, data) values (:v1, :v2, :v3, :v4, :v5)'
  else
    fSaver.SQL.Text :=
      'update tree set parent = :v1, name = :v2, status = :v3, image_index = :v4, data = :v5 where id = :v6';
  fSaver.Parameters.ParamByName('v1').Value := fparentID;
  fSaver.Parameters.ParamByName('v2').Value := fNodeText;
  fSaver.Parameters.ParamByName('v3').Value := fStatus;
  fSaver.Parameters.ParamByName('v4').Value := fImageIndex;
  fSaver.Parameters.ParamByName('v5').Value := fData;
  if not fIsNew then
    fSaver.Parameters.ParamByName('v6').Value := fId;
  fSaver.ExecSQL;
  if fIsNew then
  begin
    fSaver.SQL.Text :=
      'SELECT id from tree order by id desc';
    fSaver.Open;
    fId := fSaver.FieldByName('ID').asInteger;
    fSaver.Close;
    fIsNew := False;
  end;
  fChanged := False;
end;
(*---------------------------------------------------*)
procedure TItem.SetData(const Value: string);
begin
  if fData <> Value then
  begin
    fData := Value;
    Changed;
  end;
end;
(*---------------------------------------------------*)
procedure TItem.SetImageIndex(const Value: integer);
begin
  if fImageIndex <> Value then
  begin
    fImageIndex := Value;
    Changed;
  end;
end;
(*---------------------------------------------------*)
procedure TItem.SetNodeText(const Value: string);
begin
  if fNodeText <> Value then
  begin
    fNodeText := Value;
    Changed;
  end;
end;
(*---------------------------------------------------*)
procedure TItem.SetParentID(const Value: integer);
begin
  if fParentId <> Value then
  begin
    fParentID := Value;
    Changed;
  end;
end;
(*---------------------------------------------------*)
procedure TItem.SetStatus(const Value: byte);
begin
  if fStatus <> Value then
  begin
    FStatus := Value;
    Changed;
  end;
end;
(*---------------------------------------------------*)
procedure TForm1.AddItem(aText: string; aIndex: Integer; aParent: TTreeNode);
var n: TTreeNode;
  data: TItem;
  parentId: integer;
begin
  parentId := 0;
  if (aParent <> nil) and (TItem(aParent.Data) <> nil) then
    parentId := TItem(aParent.Data).ID;
  data := TItem.Create(AdoQuery1, -1, parentId, 0);
  data.NodeText := aText;
  data.ImageIndex := aIndex;
  n := TTreeNode.Create(TreeView1.Items);
  n.Text := data.NodeText;
  n.ImageIndex := data.ImageIndex;
  n.SelectedIndex := data.ImageIndex;
  TreeView1.Items.AddNode(n, aParent, aText, data, naAddChild);
end;
(*---------------------------------------------------*)
procedure TForm1.Button1Click(Sender: TObject);
begin
  loadTree(treeview1);
end;
(*---------------------------------------------------*)
procedure TForm1.Button2Click(Sender: TObject);
begin
  savetree(treeview1);
end;
(*---------------------------------------------------*)
procedure TForm1.FileBtnClick(Sender: TObject);
var aText: string;
begin
  if (TreeView1.Selected <> nil) and (TreeView1.Selected.ImageIndex = 0) then
  begin
     if InputQuery('File', 'Enter a file name', aText) then
      AddItem(aText, 1, TreeView1.Selected);
  end else
    ShowMessage('Select a folder in the treeview first.');
end;
(*---------------------------------------------------*)
function TForm1.findNode(t: TTreeView; id: integer): TTreeNode;
var i:integer;
begin
  i:=0;
  while (i<t.items.count) and (TItem(t.items[i].data).ID<>id) do
    inc(i);
  if i<t.items.count then result:=t.items[i]
                     else result:=nil;
end;
(*---------------------------------------------------*)
procedure TForm1.FolderBtnClick(Sender: TObject);
var aText: string;
begin
  if InputQuery('Folder', 'Enter a folder name', aText) then
    AddItem(aText, 0, nil);
end;
(*---------------------------------------------------*)
procedure TForm1.FormCreate(Sender: TObject);
begin
  ADOConnection1.Open;
end;
(*---------------------------------------------------*)
procedure TForm1.loadtree(t: TTreeView);
var
  p, n: TTreeNode;
  data: TItem;
begin
  t.Items.Clear;
  ADOQuery1.SQL.Text := 'select * from tree order by parent asc';
  ADoQuery1.Open;
  while not ADoQuery1.Eof do
  begin
    data := TItem.LoadFromDataset(AdoQuery1);
    p := FindNode(t, data.ParentID);
    n := t.items.AddChildObject(p, data.NodeText, data);
    n.ImageIndex := data.ImageIndex;
    n.SelectedIndex := data.ImageIndex;
    AdoQuery1.Next;
  end;
  AdoQuery1.Close;
end;
(*---------------------------------------------------*)
procedure TForm1.saveNode(n: TTreeNode);
var i, aParent: integer;
  item: TItem;
begin
  item := TItem(n.Data);
  if item <> nil then
  begin
    item.BeginUpdate;
    try
      Item.NodeText := n.Text;
      aParent := 0;
      if (n.Parent <> nil) and (TItem(n.Parent.Data) <> nil) then
        aParent := TItem(n.Parent.Data).ID;
      Item.ParentID := aParent;
      Item.ImageIndex := n.ImageIndex;
    finally
      Item.EndUpdate;
    end;
  end;
  for i := 0 to n.Count-1 do SaveNode(n.Item[i]);
end;
(*---------------------------------------------------*)
procedure TForm1.savetree(t: ttreeview);
var n: TTreeNode;
begin
  n := t.items.getFirstNode;
  while n <> nil do
  begin
    SaveNode(n);
    n := n.getNextSibling;
  end;
end;
(*---------------------------------------------------*)
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
  Memo1.Text := '';
  if (Node <> nil) and (Node.ImageIndex = 1) then
    Memo1.Text := TItem(Node.Data).Data;
end;
(*---------------------------------------------------*)
procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
  var AllowChange: Boolean);
  var n: TTreeNode;
begin
  n := TTreeView(Sender).Selected;
  if (n <> nil) and (n.ImageIndex = 1) then    
    TItem(N.Data).Data := Memo1.Text;
end;
(*---------------------------------------------------*)
end.

Open in new window

LVL 1
peterkiersAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

dougaugCommented:
Hi,

the memo text has not been saved in database because the assignment of memo text was in TreeViewChanging event. In previous code, you should click in another item before saving it to database to your program work correctly.

I've deleted the TreeViewChanging event and added the code below:

procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
var n: TTreeNode;
begin
  n := TreeView1.Selected;
  TItem(n.Data).fSaveImmediate := False;

  if (n <> nil) and (n.ImageIndex = 1) then
    TItem(N.Data).Data := Memo1.Text;
end;

Test this and see if now it's working OK.

Regards
0
peterkiersAuthor Commented:
I have tested it but when i want to write in the Memo i get an EAccesViolation.

Greetings, Peter Kiers
0
dougaugCommented:
Replace my last code with this (i've changed the event to Memo1KeyUp):

procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var n: TTreeNode;
begin
  n := TreeView1.Selected;

  if (n <> nil) and (n.ImageIndex = 1) then
  begin
    TItem(n.Data).fSaveImmediate := False;
    TItem(N.Data).Data := Memo1.Text;
  end;
end;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
peterkiersAuthor Commented:
Ah, know its perfect. Thank you 500 p's comming your way.

Greetings, Peter Kiers
0
dougaugCommented:
Your Welcome, thankyou.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.