Page 1 of 1

Display of string corrupted in DBGrid

Posted: Tue 23 Dec 2014 10:46
by Louarn
Hello all,

I encounter an issue with the display of string value in DB grid.
Here is a screenshot of the pb:

Image


You can reproduce it following this way:
- Feed the grid with data, having Field.DataType like dtExtString, dtExtWideString
- Modify the value of a field (here LIBQTER).
- Stay on the line, quit the field, and come back in it
- Press escape key
- The display of string field suech as ENS1E is corrupted

Here is a video of the issue:
http://v8.tinypic.com/player.swf?file=14ne1hg&s=8

http://fr.tinypic.com/player.php?v=14ne1hg&s=8

The app is connected to an oracle database.

Here is the source code of the application:

Code: Select all

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, OraCall, Data.DB,
  DBAccess, Ora, Vcl.ExtCtrls, Vcl.Grids, Vcl.DBGrids, Bde.DBTables, MemDS;

type
  TForm2 = class(TForm)
    OraSession1: TOraSession;
    Panel1: TPanel;
    Label1: TLabel;
    Button1: TButton;
    EdtServer: TEdit;
    Label3: TLabel;
    EdtLogin: TEdit;
    Label4: TLabel;
    EdtPwd: TEdit;
    Panel2: TPanel;
    DBGrid1: TDBGrid;
    OraQuery1: TOraQuery;
    OraDataSource1: TOraDataSource;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure OraDataSource1StateChange(Sender: TObject);
    procedure OraDataSource1DataChange(Sender: TObject; Field: TField);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form2       : TForm2;
  FPost       : boolean;
implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  FPost := false;
  if not OraSession1.Connected then
  begin
     OraSession1.Server    := EdtServer.Text ;
     OraSession1.UserName  := EdtLogin.Text;
     OraSession1.PassWord  := EdtPwd.Text;
     OraSession1.Open ;
  end;
  if OraSession1.Connected then
     showmessage('Connection is Ok.')
  else
     showmessage('Connection KO !!!');

end;

procedure TForm2.Button2Click(Sender: TObject);
begin
   OraQuery1.Open;
end;

procedure TForm2.OraDataSource1DataChange(Sender: TObject; Field: TField);
begin
    if field <> nil then
       Fpost := true;
end;

procedure TForm2.OraDataSource1StateChange(Sender: TObject);
begin
   if (OraDataSource1.DataSet.State = dsBrowse) and (Fpost) then
   begin
      Fpost := false;
      OraDataSource1.DataSet.Edit;
      OraDataSource1.DataSet.Post;
   end;
end;

end.

Code: Select all

object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'Dispose buffer issue'
  ClientHeight = 390
  ClientWidth = 1064
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 1064
    Height = 105
    Align = alTop
    TabOrder = 0
    ExplicitWidth = 517
    object Label1: TLabel
      Left = 25
      Top = 11
      Width = 32
      Height = 13
      Caption = 'Server'
    end
    object Label3: TLabel
      Left = 25
      Top = 38
      Width = 25
      Height = 13
      Caption = 'Login'
    end
    object Label4: TLabel
      Left = 25
      Top = 65
      Width = 20
      Height = 13
      Caption = 'Pwd'
    end
    object Button1: TButton
      Left = 217
      Top = 8
      Width = 104
      Height = 33
      Caption = 'Connect DB'
      TabOrder = 0
      OnClick = Button1Click
    end
    object EdtServer: TEdit
      Left = 73
      Top = 8
      Width = 125
      Height = 21
      TabOrder = 1
      Text = ''
    end
    object EdtLogin: TEdit
      Left = 73
      Top = 35
      Width = 125
      Height = 21
      TabOrder = 2
      Text = ''
    end
    object EdtPwd: TEdit
      Left = 73
      Top = 62
      Width = 125
      Height = 21
      PasswordChar = '*'
      TabOrder = 3
      Text = ''
    end
    object Button2: TButton
      Left = 217
      Top = 47
      Width = 104
      Height = 33
      Caption = 'Feed grid'
      TabOrder = 4
      OnClick = Button2Click
    end
  end
  object Panel2: TPanel
    Left = 0
    Top = 105
    Width = 1064
    Height = 285
    Align = alClient
    TabOrder = 1
    ExplicitLeft = 392
    ExplicitTop = 176
    ExplicitWidth = 185
    ExplicitHeight = 41
    object DBGrid1: TDBGrid
      Left = 1
      Top = 1
      Width = 1062
      Height = 283
      Align = alClient
      DataSource = OraDataSource1
      TabOrder = 0
      TitleFont.Charset = DEFAULT_CHARSET
      TitleFont.Color = clWindowText
      TitleFont.Height = -11
      TitleFont.Name = 'Tahoma'
      TitleFont.Style = []
    end
  end
  object OraSession1: TOraSession
    Left = 584
    Top = 16
  end
  object OraQuery1: TOraQuery
    Session = OraSession1
    SQL.Strings = (   
        'select ... from ... where ...' +
        )
    Left = 480
    Top = 16
  end
  object OraDataSource1: TOraDataSource
    DataSet = OraQuery1
    OnStateChange = OraDataSource1StateChange
    OnDataChange = OraDataSource1DataChange
    Left = 392
    Top = 16
  end
end

I know that the OraDataSource1StateChange is strangely coded, but this should not generate such behaviour.
It is not easy to modify the source code of this method.

Please help !

Re: Display of string corrupted in DBGrid

Posted: Tue 23 Dec 2014 11:25
by AlexP
Hello,

Please provide the script of creating the table used in your sample.

Re: Display of string corrupted in DBGrid

Posted: Tue 23 Dec 2014 11:58
by Louarn
Hello AlexP,

Here it is:

Code: Select all

CREATE TABLE "TestApp"
  (
    "ORTR"      NUMBER(9,0) NOT NULL ENABLE,
    "OT"        NUMBER(9,0),
    "LIBQTE"    VARCHAR2(20 BYTE),
    "LIBQTER"   VARCHAR2(20 BYTE),
    "ENS1E"     VARCHAR2(40 BYTE),
    "ENS1D"     VARCHAR2(40 BYTE),
    "REFCDE"    VARCHAR2(32 BYTE),
    "CDECLT"    VARCHAR2(32 BYTE),
    "REFOT"     VARCHAR2(32 BYTE),
    "RECEP"     VARCHAR2(32 BYTE),
    "NOM_PORD"  VARCHAR2(35 BYTE),
    "TOTALQTE"  VARCHAR2(255 BYTE),
    "TOTALQTER" VARCHAR2(255 BYTE)
  )
  
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72186,71624,'7 T','15 T','ACHILLE TRANSPORTS','AEF FRET',' ',' ',' ',' ','OMP','7 T','15 T');
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72288,71726,'1 T',' ','ACHILLE TRANSPORTS','AEF FRET',' ',' ',' ',' ','OMP','1 T',' ');
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72292,71730,'10 M3',' ','SL - CLIENT TEST 1','CASO',' ',' ',' ',' ','OMP','10 M3',' ');
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72291,71729,'2 T','2 T','ACHILLE TRANSPORTS','AEF FRET',' ',' ',' ',' ','OMP','2 T','2 T');
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72287,71725,'1 T','1 T','ACHILLE TRANSPORTS','AEF FRET',' ',' ',' ',' ','OMP','1 T','1 T');
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72289,71727,'1 T',' ','ACHILLE TRANSPORTS','AEF FRET',' ',' ',' ',' ','OMP','1 T',' ');
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72282,71720,' ',' ','GHJHTRJ','SEZFGEH',' ',' ',' ',' ','OMP',' ',' ');
Insert into "TestApp" (ORTR,OT,LIBQTE,LIBQTER,ENS1E,ENS1D,REFCDE,CDECLT,REFOT,RECEP,NOM_PORD,TOTALQTE,TOTALQTER) values (72293,71731,' ',' ',' ','CASO',' ',' ',' ',' ','OMP',' ',' ');
 
Just add a "select * from TestApp" in the query to retrieve the data.

Re: Display of string corrupted in DBGrid

Posted: Tue 23 Dec 2014 13:18
by AlexP
Thank you for the information, we have reproduced the problem and will investigate the reasons for such behavior.

Re: Display of string corrupted in DBGrid

Posted: Sun 04 Jan 2015 14:24
by AlexP
We haven't yet found a reason for such behavior. We are still investigating the problem. Please specify the need to use such an approach for data posting on calling the Cancel method. For the time being, as a workaround, you can use the BeforeCancel event for saving data to the database.

Re: Display of string corrupted in DBGrid

Posted: Fri 16 Jan 2015 09:06
by Louarn
Hello AlexP,

Sorry for my late answering.

Currently, there are many interaction in the form, between grid and frame.
We are looking to move some code from the StateChange to the BeforeScroll event.
But it is hard job, we have the behaviour in many screen and the application is old and complex.

That is why we need to have an improve behaviour of the datasource component.

Re: Display of string corrupted in DBGrid

Posted: Mon 19 Jan 2015 11:13
by AlexP
Unfortunately, we haven't yet found the reason for such behavior. As soon as we obtain any information, we will inform you.