



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; |