Fórum ClientDataSet - Gravação em XML na ordem exata. #487495

31/07/2014

0

Olá pessoal!

Estou desenvolvendo um player de áudio usando o Delphi 6. Uso DbGrid, e através do ClientDataSet salvo as informações num arquivo XML.
O Arquivo xml tem em torno de 2.000 registros. O problema é que não estou conseguindo manter a ordem de salvamento das alterações.

No player permito incluir mídias e movê-las no grid.
Qual lógica devo usar para salvar as alterações no arquivo XML e depois importar o mesmo com a mesma sequência que estava no DBGrid?

Agradeço a ajuda e a compreensão dos amigos desenvolvedores.

Adilson
Adilson Pedro

Adilson Pedro

Responder

Post mais votado

01/08/2014

Buenos,

Não conheço algo que o faça automaticamente. Nem o Clonecursor filtrando.
Uma solução é criar um campo numérico e controlar a ordem por ele.

Segue exemplo:

- Utilizo no exemplo um campo "NUMERO" inteiro para isso.

unit uPrincipal;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBClient;

type
  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    ClientDataSet1NUMERO: TIntegerField;
    ClientDataSet1DESCRI: TStringField;
    procedure ClientDataSet1AfterScroll(DataSet: TDataSet);
    procedure ClientDataSet1BeforePost(DataSet: TDataSet);
    procedure ClientDataSet1AfterPost(DataSet: TDataSet);
    procedure ClientDataSet1AfterOpen(DataSet: TDataSet);
  private
    { Private declarations }
  public
    { Public declarations }
    iReg      : integer;
    iRegAtual : integer;
    bAtualiza : boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ClientDataSet1AfterScroll(DataSet: TDataSet);
begin
  if ( DataSet.State in [dsInsert] ) or ( not bAtualiza ) then
    exit;

  // Armazena registro Atual posicionado
  iRegAtual := ClientDataSet1NUMERO.AsInteger;
end;

procedure TForm1.ClientDataSet1BeforePost(DataSet: TDataSet);
begin
  if not bAtualiza then
    exit;

  // Incrementa controle do último número inserido
  Inc(iReg);

  // Grava o registro como último número para identificação
  ClientDataSet1NUMERO.AsInteger := iReg;
end;

procedure TForm1.ClientDataSet1AfterPost(DataSet: TDataSet);
begin
  // Enquanto reordena não entra novamente no evento
  if not bAtualiza then
    exit;

  // Desativa eventos do clientdataset enquanto reordena
  bAtualiza := False;

  // Desativa os controles do clientdataset enquanto reordena para ser mais rápido
  ClientDataSet1.DisableControls;

  ClientDataSet1.Last;

  // Reordena do menor para o maior
  while not ClientDataSet1.bof do
  begin
    // Finaliza o processo quando atingir a numeração do registro atual
    if ClientDataSet1NUMERO.AsInteger < iRegAtual then
      break;

    // Incrementa 1 em cada registro prosterior ao novo incluído   
    ClientDataSet1.Edit;
    ClientDataSet1NUMERO.AsInteger := ClientDataSet1NUMERO.AsInteger + 1;
    ClientDataSet1.Post;

    ClientDataSet1.Prior;
  end;

  // Posiciona no último registro (que foi o incluído por último)
  ClientDataSet1.Last;

  // Grava a posição que estava o registro que estava posicionado
  ClientDataSet1.Edit;
  ClientDataSet1NUMERO.AsInteger := iRegAtual;
  ClientDataSet1.Post;

  // Reativa os controles do clientdataset
  ClientDataSet1.EnableControls;

  // Habilita acesso aos eventos
  bAtualiza := True;
end;

procedure TForm1.ClientDataSet1AfterOpen(DataSet: TDataSet);
begin
  // Habilita acesso aos eventos do clientdataset
  bAtualiza := True;

  // Posiciona no último registro para armazenar as variáveis de controle de ordenação
  ClientDataSet1.Last;

  // Armazena o último registro inserido
  iReg      := ClientDataSet1NUMERO.AsInteger;

  // Armazena registro Atual posicionado
  iRegAtual := ClientDataSet1NUMERO.AsInteger;
end;

end.



ClientDataSet no dfm:

  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    IndexFieldNames = 'NUMERO'
    Params = <>
    AfterOpen = ClientDataSet1AfterOpen
    BeforePost = ClientDataSet1BeforePost
    AfterPost = ClientDataSet1AfterPost
    AfterScroll = ClientDataSet1AfterScroll
    Left = 208
    Top = 40
    object ClientDataSet1NUMERO: TIntegerField
      FieldName = 'NUMERO'
    end
    object ClientDataSet1DESCRI: TStringField
      FieldName = 'DESCRI'
    end
  end

Renato Rubinho

Renato Rubinho
Responder

Gostei + 1

Mais Posts

01/08/2014

Adilson Pedro

Muito obrigado pela ajuda! Agora vou trabalhar com sua sugestão.

Grato mais um vez.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar