Ver Mensaje Individual
  #11  
Antiguo 21-12-2021
Avatar de movorack
[movorack] movorack is offline
Miguel A. Valero
 
Registrado: feb 2007
Ubicación: Bogotá - Colombia
Posts: 1.346
Reputación: 20
movorack Va camino a la famamovorack Va camino a la fama
¡Hola, feliz-58!

De pronto algo de este helper, pueda serte útil.

Código Delphi [-]
uses
  System.RegularExpressions;

type
  TMyClientDatasetHelper = class helper for TClientDataset
  Private
  Public
    procedure CopyCurrentRecord(DataSet: TDataset; IgnoreFieldNames: array of string); overload;

    procedure CopyCurrentRecord(DataSet: TDataset); overload;

    procedure CopyData(DataSet: TDataset; IgnoreFieldNames: array of string); overload;

    procedure CopyData(DataSet: TDataset); overload;

     procedure InicLocal(XMLSource: string = ''; LogChanges: Boolean = False);

     procedure FinaLocal(XMLFileName : string = '');
  end; 

{ TMyClientDatasetHelper }

procedure TMyClientDatasetHelper.CopyCurrentRecord(DataSet: TDataset;
  IgnoreFieldNames: array of string);
  function IgnoreField(FieldName: string): Boolean;
    var
      lFieldName : String;
  begin
    Result := False;
    for lFieldName in IgnoreFieldNames do
    begin
      Result := SameText(FieldName.Trim, lFieldName.trim);
      if Result then
        Break;
    end;
  end;
  var
    lField: TField;
begin
  if (not Dataset.Active) or Dataset.IsEmpty then
    Exit;

  if not (Self.State in [dsEdit, dsInsert]) then
    if Self.IsEmpty then
      Self.Append
    else
      Self.Edit;

  for lField in Self.Fields do
  begin
    if IgnoreField(lField.FieldName) then
      Continue;

    if not Assigned(DataSet.FindField(lField.FieldName)) then
      Continue;

    if lField.IsBlob then
    begin
      try
        //Se intenta realizar la copia
        lField.AsBytes := DataSet.FieldByName(lField.FieldName).AsBytes
      except
      end;
    end
    else
    if (lField.Value <> DataSet.FieldByName(lField.FieldName).Value) then
      lField.Value := DataSet.FieldByName(lField.FieldName).Value;
  end;
end;

procedure TMyClientDatasetHelper.CopyCurrentRecord(DataSet: TDataset);
begin
  CopyCurrentRecord(DataSet, []);
end;

procedure TMyClientDatasetHelper.CopyData(DataSet: TDataset);
begin
  CopyData(DataSet, []);
end;

procedure TMyClientDatasetHelper.CopyData(DataSet: TDataset;
  IgnoreFieldNames: array of string);
  var
    BookMark: TBookmark;
begin
  if (not DataSet.Active) or DataSet.IsEmpty then
    Exit;

  if Self.State in [dsEdit, dsInsert] then
    Self.Cancel;

  BookMark := nil;
  try
    DataSet.DisableControls;
    Self.DisableControls;
    BookMark := DataSet.GetBookmark;

    DataSet.First;
    while not DataSet.Eof do
    begin
      Self.Append;
      CopyCurrentRecord(Dataset, IgnoreFieldNames);
      Self.Post;
      Dataset.Next;
    end;

    Self.First;
  finally
    if Assigned(BookMark) and Dataset.BookmarkValid(BookMark) then
      DataSet.GotoBookmark(BookMark);

    DataSet.EnableControls;
    Self.EnableControls;
  end;
end;

procedure TMyClientDatasetHelper.FinaLocal(XMLFileName: string);
begin
  if Self.State in [dsInsert, dsEdit] then
    Self.Post;

  if not XMLFileName.Trim.IsEmpty then
  begin
    if FileExists(XMLFileName) then
      DeleteFile(XMLFileName);

    Self.SaveToFile(XMLFileName, dfXMLUTF8);
  end;
end;

procedure TMyClientDatasetHelper.InicLocal(XMLSource: string;
  LogChanges: Boolean);
  var
    lCds: TClientDataSet;
begin
  if (not (Self is TClientDataSet))
    or Assigned(Self.RemoteServer)
    or (not Self.ProviderName.Trim.IsEmpty)
  then
    Exit;

  //Se inicializa el dataset vacio
  if Self.DataSize > 0 then
    Self.Close;
  Self.FieldDefs.Clear;

  if Self.FieldCount > 0 then
  begin
    Self.CreateDataSet;
    Self.EmptyDataSet;
  end;

  if Self.Active then
    Self.LogChanges := LogChanges;

  if not XMLSource.Trim.IsEmpty then
  begin
    //Para evitar fallas de carga cuando la estructura del dataset no coincide,
    //se crea un dataset temporal para cargar el XML
    lCds := TClientDataSet.Create(Self);
    try
      //Se verifica si es un archivo.
      if FileExists(XMLSource) then
      begin
        try
          lCds.LoadFromFile(XMLSource);
        except
          on E: Exception do
          begin
            if FileExists(XMLSource) then
              DeleteFile(XMLSource);
            raise;
          end;
        end;
      end
      else
      //se verifica que sea una estructura XML
      if TRegEx.IsMatch(XMLSource, '\s*\<\?xml', [roIgnoreCase, roMultiLine]) then
      begin
        lCds.XMLData := XMLSource.Trim;
        lCds.Open;
      end;

      if lCds.Active then
      begin
        lCds.LogChanges := LogChanges;
        Self.CopyData(lCds);
      end;
    finally
      lCds.Free;
    end;
  end;

  if Self.Active and (not Self.IsEmpty) then
    Self.First;
end;
__________________
Buena caza y buen remar... http://mivaler.blogspot.com
Responder Con Cita