dicas show delphi

DICAS

Visite a biblioteca de dicas da comunidade.

Saiba mais
sombra
Artigos Show Delphi

ARTIGOS

Abordagens detalhadas sobre assuntos diversos.

Saiba mais
sombra
iniciantes show delphi

INICIANTES

Aprenda a programar de um modo simples e fácil.

Saiba mais
sombra
downloads show delphi

DOWNLOADS

Acesse os materiais exclusivos aos membros.

Saiba mais
sombra
voltar

PARA QUEM GOSTA DE DELPHI

Classe que auxilia a persistência de dados com ClientDataSet

Autor: Caique Rodrigues

Muitas vezes ao utilizar ClientDataSets, esquecemos que é necessário
implementar algum código para exibir alguma mensagem quando ocorre
algum erro.

Esta classe já nos fornece alguns métodos que facilitam o nosso trabalho
com a manipulação de dados com ClientDataSets.

Confira o código abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
unit CDSSuppl;
 
interface
 
uses
SysUtils, DB, DBClient;
 
type
TCDSSuppl = class
private
class procedure DefaultReconcileError(DataSet: TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind;
var Action: TReconcileAction);
public
class procedure PostIfNeed(ClientDataSet: TClientDataSet);
class procedure ApplyUpdates(ClientDataSet: TClientDataSet;
MaxErrors: integer = 0);
class procedure CopyDataSet(Source: TClientDataSet;
var Target: TClientDataSet; AllRecords: boolean = True);
class procedure CopyDataSetStruct(Source: TClientDataSet;
var Target: TClientDataSet);
class procedure CopyDataSetRecord(Source, Target: TClientDataSet);
class procedure InsertRecordFromDataSet(Source, Target: TClientDataSet);
class procedure InsertAllRecordsFromDataSet(Source, Target: TClientDataSet);
class function SaveRunTimeIndexes(ClientDataSet: TClientDataSet)
: TIndexDefs;
class procedure RestoreRunTimeIndexes(ClientDataSet: TClientDataSet;
AIndexDefs: TIndexDefs; AFreeIndexDefs: boolean = True);
end;
 
implementation
 
{ TCDSSuppl }
 
var
FErrorMsg: string;
 
const
StrUpdtKind: array [TUpdateKind] of string = ('Modificação', 'Inserção',
'Exclusão');
 
class procedure TCDSSuppl.ApplyUpdates(ClientDataSet: TClientDataSet;
MaxErrors: integer = 0);
begin
if not assigned(ClientDataSet.OnReconcileError) then
ClientDataSet.OnReconcileError := TCDSSuppl.DefaultReconcileError;
if ClientDataSet.ApplyUpdates(MaxErrors) <> 0 then
Raise Exception.Create(FErrorMsg);
end;
 
class procedure TCDSSuppl.CopyDataSet(Source: TClientDataSet;
var Target: TClientDataSet; AllRecords: boolean = True);
var
{$IFDEF _2010}
bm: TBookmark;
{$ELSE}
bm: TBookmarkStr;
{$ENDIF}
begin
CopyDataSetStruct(Source, Target);
 
if not AllRecords then
begin
CopyDataSetRecord(Source, Target);
exit;
end;
 
Target.DisableControls;
 
Source.DisableControls;
 
bm := Source.Bookmark;
Source.First;
while not Source.Eof do
begin
CopyDataSetRecord(Source, Target);
Source.Next;
end;
Source.Bookmark := bm;
Source.EnableControls;
 
Target.EnableControls;
end;
 
class procedure TCDSSuppl.CopyDataSetStruct(Source: TClientDataSet;
var Target: TClientDataSet);
var
indxField: integer;
begin
if not assigned(Target) then
Target := TClientDataSet.Create(nil);
 
if Target.Active then
Target.Close;
 
Target.FieldDefs.BeginUpdate;
Target.FieldDefs.Clear;
 
with Source do
for indxField := 0 to FieldCount - 1 do
with Fields[indxField] do
if (DataType = ftString) then
Target.FieldDefs.Add(FieldName, DataType, DataSize, False)
else if (DataType = ftFMTBcd) then
Target.FieldDefs.Add(FieldName, DataType,
TFMTBCDField(Fields[indxField]).Size, False)
else
Target.FieldDefs.Add(FieldName, DataType, 0, False);
 
Target.FieldDefs.EndUpdate;
 
Target.CreateDataSet;
end;
 
class procedure TCDSSuppl.CopyDataSetRecord(Source, Target: TClientDataSet);
var
I: integer;
Field: TField;
InEditMode: boolean;
begin
InEditMode := Target.State in [dsInsert, dsEdit];
 
if not InEditMode then
Target.Append;
 
with Target do
begin
for I := 0 to FieldCount - 1 do
begin
Field := Source.FindField(Fields[I].FieldName);
if assigned(Field) then
Fields[I].Assign(Field);
end;
end;
 
if not InEditMode then
Target.Post;
end;
 
class procedure TCDSSuppl.DefaultReconcileError(DataSet: TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction);
begin
FErrorMsg := StrUpdtKind[UpdateKind];
FErrorMsg := FErrorMsg + #13#10 + E.Message;
FErrorMsg := FErrorMsg + #13#10 + intToStr(E.ErrorCode);
 
if E.Context <> '' then
FErrorMsg := FErrorMsg + #13#10 + 'Contexto: ' + E.Context;
 
FErrorMsg := FErrorMsg + #13#10 + DataSet.Name;
 
if UpdateKind = ukDelete then
Action := raCancel
else
Action := raAbort;
end;
 
class procedure TCDSSuppl.InsertAllRecordsFromDataSet(Source,
Target: TClientDataSet);
begin
with Source do
begin
DisableControls;
First;
while not Eof do
begin
InsertRecordFromDataSet(Source, Target);
Next;
end;
First;
EnableControls;
end;
end;
 
class procedure TCDSSuppl.InsertRecordFromDataSet(Source,
Target: TClientDataSet);
begin
Target.Insert;
CopyDataSetRecord(Source, Target);
Target.Post;
end;
 
class procedure TCDSSuppl.PostIfNeed(ClientDataSet: TClientDataSet);
begin
if ClientDataSet.State in [dsInsert, dsEdit] then
ClientDataSet.Post;
end;
 
class function TCDSSuppl.SaveRunTimeIndexes(ClientDataSet: TClientDataSet)
: TIndexDefs;
var
x: integer;
begin
Result := TIndexDefs.Create(nil);
 
if ClientDataSet.Active then
begin
ClientDataSet.IndexDefs.Update;
for x := 0 to ClientDataSet.IndexDefs.Count - 1 do
if (ixNonMaintained in ClientDataSet.IndexDefs[x].Options) then
Result.AddIndexDef.Assign(ClientDataSet.IndexDefs[x]);
end;
end;
 
class procedure TCDSSuppl.RestoreRunTimeIndexes(ClientDataSet: TClientDataSet;
AIndexDefs: TIndexDefs; AFreeIndexDefs: boolean);
var
x: integer;
begin
if assigned(AIndexDefs) then
begin
for x := 0 to AIndexDefs.Count - 1 do
with ClientDataSet.IndexDefs.AddIndexDef do
Assign(AIndexDefs[x]);
AIndexDefs.Update;
if AFreeIndexDefs then
AIndexDefs.Free;
end;
end;
 
end.

Exemplo de uso para salvar dados:

1
2
3
4
5
procedure TForm1.BtnSalvarClick(Sender: TObject);
begin
TCDSSuppl.PostIfNeed(ClientDataSet1);
TCDSSuppl.ApplyUpdates(ClientDataSet1, 0);
end;
  • InfusTec
  • 0 comentários
  • 2 de setembro de 2016

Deixe um comentário

Ir ao topo

© 2024 Infus Soluções em Tecnologia - Todos os Direitos Reservados