C++ Builder XE4 > Excel + OLE > 5x5代入、コピー、ペーストの処理時間

```txt:動作環境
- 実装
    - C++ Builder XE4
- 確認
    - Windows 8.1 Pro
    - Office 2016
```

### 処理概要

- 下記のエクセルファイルがあるとする
    - 26シート(重い): データやグラフが大量に掲載
    - 1シート(軽い): テキストのみ
- 下記の処理をする
    - 1. 5行x5列の代入
    - 2. 1の範囲をコピー
    - 3. 26シートの一つにペースト

### 疑問点

代入とコピーまでの処理を「軽いシート」で作業した場合と、「重いシート」で作業した場合に処理時間の違いはあるのか?

### code

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <System.Win.ComObj.hpp>  // EXCEL処理用

#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------


#define WORK_ON_OTHER_SHEET // 軽いシートでの作業


__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnConvertClick(TObject *Sender)
{
	String curDir = ExtractFileDir(Application->ExeName);

	WideString srcFile = curDir + "\\base.xlsx";
	WideString dstFile = curDir + "\\out.xlsx";

	//--- Excel処理
	bool closeExcel = false;

	Variant ExcelApp = CreateOleObject("Excel.Application");

	DWORD stTim = GetTickCount();

	try
    {
		Variant xls_books;
		Variant xls_abook;
		Variant xls_sheets;
		Variant xls_asheet;

		try {
			ExcelApp.OlePropertySet("Visible", false); // Excel not shown
			ExcelApp.OlePropertySet("DisplayAlerts", false); // No dialog for overwrite

			xls_books = ExcelApp.OlePropertyGet("Workbooks");
			xls_abook = xls_books.OleFunction("Open", srcFile);
			// 最初のシート選択
#ifdef WORK_ON_OTHER_SHEET
			xls_abook.OlePropertyGet("Sheets", 27).OleProcedure("Select");
#else
			xls_abook.OlePropertyGet("Sheets", 1).OleProcedure("Select");
#endif
			xls_asheet = xls_abook.OlePropertyGet("ActiveSheet");
			// 1. Fill
			for (int ci = 1; ci <= 5; ci++) { // ci: column index
				for (int ri = 1; ri <= 5; ri++) { // ri: row index
					xls_asheet.OlePropertyGet("Cells", ri, ci).OlePropertySet("Value", WideString("3.141592"));
				}
			}
			// 2. Copy and Paste
			Variant wrkRange = xls_asheet.OlePropertyGet("Range", WideString("A1:E5"));
			wrkRange.OleProcedure("Copy");
#ifdef WORK_ON_OTHER_SHEET
			xls_abook.OlePropertyGet("Sheets", 1).OleProcedure("Select");
			xls_asheet = xls_abook.OlePropertyGet("ActiveSheet");
#endif
			xls_asheet.OlePropertyGet("Cells", 7, 7).OleProcedure("Select");
			xls_asheet.OleProcedure("Paste");

			// 3. Save
			xls_abook.OleProcedure("SaveAs", dstFile); //開いた*.xlsxを別名保存
			closeExcel = true;
			ExcelApp.Exec(Procedure("Quit"));

			DWORD edTim = GetTickCount();
			String msg = IntToStr((int)(edTim - stTim)) + L"(msec) has passed";

			msg = msg + L"\r\n" + L"Save to [" + dstFile + L"]";
			ShowMessage(msg);
		}
		__finally
        {
            xls_asheet = Unassigned(); // 変数を初期状態に
            xls_sheets = Unassigned();
            xls_abook = Unassigned();
            xls_books = Unassigned();
        }
    }
    __finally
	{
        ExcelApp = Unassigned();
	}
}
//---------------------------------------------------------------------------
```

### 結果

下記、「重い」は重いシートでの処理を意味する。

| 代入とコピー | ペースト | 処理時間(秒) | 備考 |
|:-:|:-:|:-:|:-:|
| 重い | 重い | 45 | WORK_ON_OTHER_SHEET 未定義 | 
| 軽い | 重い | 44 | WORK_ON_OTHER_SHEET 定義 |
| 軽い | 軽い | 39 | シート1のみで作業(未掲載コード) |

代入とコピーを行うシートの違いによる処理時間の違いは見られなかった。
(何回かためした時に64秒という処理になっていたときがあったが、再現しなくなった。)

44秒の処理はまだまだ遅い。
対象としているExcelファイルが重過ぎる。

### 処理時間のプロファイリング

処理の内訳を確認した

- ファイルオープン: 23秒
- 5行5列の代入: 1秒未満
- コピーとペースト: 1秒未満
- 保存: 18秒

ファイルオープンと保存が主な処理になっているとすれば、代入やコピーペーストの処理が増えても処理時間の増加は少ないかもしれない。

### 処理時間のプロファイリング (2018/07/06)

重いシートでの処理時間を再測定。

- ファイルオープン: 21.9秒
- 5行5列の代入: 4.9秒
- コピーとペースト: 1.1秒
- 保存: 19.7秒

全体で47.656秒。

「5行5列の代入」に5秒かかっている。