Solved

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

Posted on 2009-07-03
5
204 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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Newbie Thread Programming 1 116
code issue 8 84
Convert a string into a TDateTime 5 44
Delphi: Connect to running MS Outlook 4 27
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

708 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

20 Experts available now in Live!

Get 1:1 Help Now