Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2013年12月28日] [更新 2013年12月28日] エクセル操作フォームEx
エクセル操作フォームEx   参考コード類
複数のブックの表示とブック間の操作
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro + Excel 2010







別のエクセル操作フォームEx を実行時に生成して表示


エクセル操作フォームEx を使用したアプリケーションを複数起動して、各々に別のブックを表示すれば当然、複数のブックを開くことになります。

ここでは、エクセル操作フォームEx を起動して、そこからボタンクリック等で別のエクセル操作フォームEx を生成して起動します。新たに生成したエクセル操作フォームEx で別のブックを表示すれば複数のブックを開くことになります。ただし、エクセルのインスタンスを生成すると、それは別のプロセスとして生成されます。
また、エクセル操作フォームEx の仕様上、後で起動したエクセル操作フォームEx が、前面に表示されてしまい、起動元のエクセル操作フォームEx をクリックしても前面に移動できません。現在のところ回避策はありません。


[備考]
たとえ同じエクセルでも、別のプロセスで起動しているアプリケーションは、プロセスを越えての操作はできません。特殊な手順、方法が必要です。文字列 (テキスト) だけは特別で、専用のメッセージ類があります。


図1
別のエクセル操作フォームEx 起動

リスト1
別のエクセル操作フォームEx を実行時に生成して表示
procedure TplExcelFormEx1.Button1Click(Sender: TObject);
var
  objExcelSheet : OleVariant;
  ExcelForm     : TplExcelFormEx;
begin
  //現在のブックの1番目のシートのオブジェクト
  objExcelSheet := xlfExcelBook.Worksheets[1];

  //エクセル操作フォームExを生成
  ExcelForm := TplExcelFormEx.Create(Self);
  ExcelForm.xlfBookFullPath := ExpandFileName('../Book2.xls');
  //グリッドライン等を表示
  ExcelForm.xlfDisplayGridLines    := True;
  ExcelForm.xlfDisplayWorkBookTabs := True;
  ExcelForm.xlfDisplayHeadings     := True;
  ExcelForm.PanelRight.Visible     := False;

  //表示してセルに値を代入
  ExcelForm.Show;
  ExcelForm.xlfCellValue['A3'] := 'ABC';
  ExcelForm.xlfBookSaved       := True;

  //次のような、プロセスを超えた操作はできない
  try
    objExcelSheet.Copy(Before := ExcelForm.xlfExcelBook.Worksheets[1]);
  except
  end;
end;




現在のエクセル操作フォームEx に別のブックを表示


エクセル操作フォームEx で指定のブックを表示して、そこに別のブックを表示します。
複数のブックを開くことになります。このサンプルでは、最初に開いたブックのシートを、後から開いたブックのシートに挿入します。このように複数のブックを開いておくと、シートの挿入だけではなく、ブック間の操作が可能となります。
エクセル操作フォームEx は後から開いたブックを閉じる操作は行いません。プログラマの責任で実装することになります。


図2
最初のブックを表示
図3
2 番目のブックを表示
図4
2 番目のブックにシートを挿入
  • 挿入したシートは、最初に表示したブックのシート

リスト2
現在のエクセル操作フォームEx に別のブックを表示
procedure TplExcelFormEx1.Button2Click(Sender: TObject);
var
  objExcelSheet : OleVariant;
  objExcelApp   : OleVariant;
  objExcelBook  : OleVariant;
begin
  //現在のブックの1番目のシートのオブジェクト
  objExcelSheet := xlfExcelBook.Worksheets[1];

  //新しく別のブックを開く
  //このブックがアクティブになる
  objExcelApp  := xlfExcelApp.Application;
  objExcelBook := objExcelApp.Workbooks.Open(ExpandFileName('../Book2'));
  objExcelBook.WorkSheets[1].Cells[3, 2].Value := 320;

  //指定時間後に、最初のブックの1番目のシートを新しいブックの1番目のシートの前に挿入
  Sleep(3000);
  objExcelSheet.copy(Before := objExcelBook.WorkSheets[1]);

  //指定時間後に保存しないで閉じる
  Sleep(3000);
  objExcelBook.Close(SaveChanges := False);
end;




エクセル操作フォームEx を使用しないで複数のブックを開いて操作


次のコードは、エクセル操作フォームEx を使用しないで複数のブックを開いて操作する例です。ここでは、CreateOleObject でエクセルのオブジェクトを生成しています。
上のサンプルと同じく、最初に開いたブックのシートを、後で開いたブックのシートに挿入します。このようにシートの挿入だけではなく、ブック間の操作が可能となります。

エクセル操作フォームEx は、エクセルを表示して操作を実行することを目的としていますが、エクセル操作フォームEx を使用しない方法では、ブックを表示しなくても操作が可能です。


[備考]
昔のエクセルでは、ブックを別のウィンドウで開いたり、同じウィンドウに重ねて表示するかを設定可能なバージョンもありました。現在は、少なくとも Excel 2007, Excel 2010 では、同じウィンドウに重ねて表示する仕様となっています。別のウィンドウでブックを開くようにするには、レジストリの操作が必要です。


図5
最初のブックを表示
図6
2 番目のブックを表示
図7
2 番目のブックにシートを挿入
  • 挿入したシートは、最初に表示したブックのシート

リスト3
エクセル操作フォームEx を使用しないで複数のブックを開いて操作
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }

  end;

var
  Form1: TForm1;

implementation

uses ComObj;

{$R *.dfm}

//=============================================================================
//  複数のブックを表示
//  エクセル操作フォームを使用しない場合
//  TExcelApplicationを使用してもよいが、メソッド類の引数を省略したいので、最初
//  からCreateOleObjectを使用して、OleVariant型で扱うことにする
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  objExcelApp   : OleVariant;
  objExcelBook1 : OleVariant;
  objExcelBook2 : OleVariant;
  objExcelSheet : OleVariant;
begin
  objExcelApp   := CreateOleObject('Excel.Application');
  objExcelBook1 := objExcelApp.WorkBooks.Open(ExpandFileName('../Book1.xls'));
  objExcelSheet := objExcelBook1.WorkSheets[1];

  //生成したエクセルを表示
  //表示しなくても操作は可能
  objExcelApp.Visible := True;

  //指定時間後に別のブックを開く
  Sleep(3000);
  objExcelBook2 := objExcelApp.WorkBooks.Open(ExpandFileName('../Book2.xls'));

  //指定時間後に、最初のブックの1番目のシートを新しいブックの2番目のシートの前に挿入
  Sleep(3000);
  objExcelSheet.copy(Before := objExcelBook2.WorkSheets[2]);

  //指定時間後に保存しないで終了
  Sleep(3000);
  objExcelBook1.Saved := True;
  objExcelBook2.Saved := True;

  objExcelSheet := Unassigned;
  objExcelBook1.Close;
  objExcelBook2.Close;
  objExcelBook1 := unAssigned;
  objExcelBook2 := unAssigned;

  objExcelApp.Quit;
  objExcelApp := unAssigned;
end;

end.