Search Results for

    Show / Hide Table of Contents

    Consolidating files (Delphi)

    Note

    This demo is available in your FlexCel installation at <FlexCel Install Folder>\Demo\Delphi\Modules\10.API\80.Consolidating Files and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​VCL-​demos/​tree/​master/​Delphi/​Modules/​10.​API/​80.​Consolidating Files

    Overview

    The FlexCel API is oriented to modifying files, instead of reading and creating files as different things. So, some most important commands on it are TExcelFile.InsertAndCopyRange and TExcelFile.DeleteRange, that copy and delete ranges on existing sheets.

    This is a real-world example on how you can use TExcelFile.InsertAndCopyRange to copy the first sheet of many different Excel files into one big file.

    Concepts

    • You can use TExcelFile.InsertAndCopyRange and/or TExcelFile.InsertAndCopySheets to copy ranges across different files. Even when it is not as complete as copying from the same file, it does copy most of the things.

    • TExcelFile.InsertAndCopyRange behaves the same way as Excel. That is, if you copy whole rows, the row height and format will be copied, not only the values. The same happens with columns, only when copying full columns the format and width will be copied to the destination. On this demo, we want to copy all Column and Row format, so we have to select the whole sheet. If we selected a smaller range, say (1,1,65535,255) instead of (1,1,65536,256) no full column or full row would be selected and not column or row format would be copied.

    • If the sheets you are copying have formulas or names with references to other files or sheets, you might not get the expected results. You could use TExcelFile.ConvertFormulasToValues and TExcelFile.ConvertFormulasToValues

    Files

    UConsolidatingFiles.pas

    unit UConsolidatingFiles;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, FlexCel.VCLSupport, FlexCel.Core, FlexCel.XlsAdapter,
      {$if CompilerVersion >= 23.0} System.UITypes, {$IFEND}
      ShellAPI;
    
    type
      TFConsolidatingFiles = class(TForm)
        Memo1: TMemo;
        btnGo: TButton;
        SaveDialog: TSaveDialog;
        cbOnlyData: TCheckBox;
        OpenDialog: TOpenDialog;
        procedure btnGoClick(Sender: TObject);
      private
        function Consolidate(const fileNames: TArray<string>;
          const OnlyData: Boolean): TExcelFile;
      end;
    
    var
      FConsolidatingFiles: TFConsolidatingFiles;
    
    implementation
    uses IOUtils;
    {$R *.dfm}
    
    procedure TFConsolidatingFiles.btnGoClick(Sender: TObject);
    var
      FileNames: TArray<String>;
      XlsOut: TExcelFile;
    begin
      if not OpenDialog.Execute then exit;
    
      FileNames := OpenDialog.Files.ToStringArray;
      if Length(FileNames) <= 0 then
      begin
        ShowMessage('You must select at least one file');
        exit;
      end;
    
      XlsOut := Consolidate(FileNames, cbOnlyData.Checked);
      try
        if SaveDialog.Execute then
        begin
          XlsOut.Save(SaveDialog.FileName);
          if MessageDlg('Do you want to open the generated file?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
          begin
            ShellExecute(0, 'open', PCHAR(SaveDialog.FileName), nil, nil, SW_SHOWNORMAL);
          end;
        end;
      finally
        XlsOut.Free;
      end;
    end;
    
    function TFConsolidatingFiles.Consolidate(const fileNames: TArray<string>; const OnlyData: Boolean): TExcelFile;
    var
      XlsIn: TExcelFile;
      XlsOut: TExcelFile;
      i: Int32;
      s: string;
    begin
      XlsIn := TXlsFile.Create;
      try
        XlsOut := TXlsFile.Create(true);
        try
          XlsOut.NewFile(1, TExcelFileFormat.v2019);
          if (Length(fileNames) > 1) and cbOnlyData.Checked then
            XlsOut.InsertAndCopySheets(1, 2, Length(fileNames) - 1);
    
          for i := 0 to Length(fileNames) - 1 do
          begin
            XlsIn.Open(fileNames[i]);
    
            XlsIn.ConvertFormulasToValues(true);  //If there is any formula referring to other sheet, convert it to value.
             //We could also call an overloaded version of InsertAndCopySheets() that
             //copies many sheets at the same time, so references are kept.
            XlsOut.ActiveSheet := i + 1;
            if OnlyData then
              XlsOut.InsertAndCopyRange(TXlsCellRange.FullRange, 1, 1, 1, TFlxInsertMode.ShiftRangeDown, TRangeCopyMode.All, XlsIn, 1) else
            begin
              XlsOut.InsertAndCopySheets(1, XlsOut.ActiveSheet, 1, XlsIn);
            end;
    
            s := TPath.GetFileName(fileNames[i]);  //Change sheet name.
            if Length(s) > 32 then
              XlsOut.SheetName := System.Copy(s, 1, 29) + '...' else
              XlsOut.SheetName := s;
    
          end;
    
          if not cbOnlyData.Checked then
          begin
            XlsOut.ActiveSheet := XlsOut.SheetCount;
            XlsOut.DeleteSheet(1);  //Remove the empty sheet that came with the workbook.
          end;
    
          XlsOut.ActiveSheet := 1;
        except
          XlsOut.Free;
          raise;
        end;
      finally
        XlsIn.Free;
      end;
      Result := XlsOut;
    end;
    
    end.
    
    In This Article
    • Overview
    • Concepts
    • Files
      • UConsolidatingFiles.pas
    Back to top FlexCel Studio for VCL and FireMonkey v7.24
    © 2002 - 2025 tmssoftware.com