Solved

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

Posted on 2009-07-03
5
209 Views
Last Modified: 2012-05-07
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

0
Comment
Question by:peterkiers
  • 3
  • 2
5 Comments
 
LVL 11

Expert Comment

by:dougaug
ID: 24774341
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
 
LVL 1

Author Comment

by:peterkiers
ID: 24774485
I have tested it but when i want to write in the Memo i get an EAccesViolation.

Greetings, Peter Kiers
0
 
LVL 11

Accepted Solution

by:
dougaug earned 500 total points
ID: 24774515
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
 
LVL 1

Author Comment

by:peterkiers
ID: 24774535
Ah, know its perfect. Thank you 500 p's comming your way.

Greetings, Peter Kiers
0
 
LVL 11

Expert Comment

by:dougaug
ID: 24774566
Your Welcome, thankyou.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now