C++ Builder XE4 > Excel > 1行挿入して、別ファイル保存 | DisplayAlertsのオフ

```txt:動作環境
C++ Builder XE4
```

### 概要

- 最初のシートの１行目に１行挿入する
- 別ファイル名で保存
    - `*_1.xls`

### 参考

[在C++Builder中利用OLE存取Excel文件](https://blog.csdn.net/ljianhui/article/details/8689804)

谢谢你

### code v0.1

```Main.h
//---------------------------------------------------------------------------

#ifndef MainH
#define MainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.Dialogs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TOpenDialog *OpenDialog1;
	TEdit *E_srcFilepath;
	TButton *B_selectFile;
	TButton *B_addRow;
	TLabel *Label1;
	void __fastcall B_selectFileClick(TObject *Sender);
	void __fastcall B_addRowClick(TObject *Sender);
private:	// ユーザー宣言
	String m_srcFilename; // 読込みファイル
	String m_dstFilename; // 出力ファイル
	void __fastcall Excel_addRow(WideString srcFile, WideString dstFile);
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

```Main.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <Vcl.FileCtrl.hpp>  // For MinimizeName()
#include <System.Win.ComObj.hpp>  // EXCEL処理用
#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

/*
v0.1 2018/04/13 EXCELファイルに１行挿入し、別ファイル保存
	- add B_selectFileClick()
	- add B_addRowClick()
	- add Excel_addRow()
*/


__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	// プログラム概要の表示
	Label1->Caption = L"選択したファイルの最初のシートの１行目に１行挿入します。\r\n"
		L"結果を別ファイル(_1.xlsx)に保存します。";

	OpenDialog1->Filter = L"EXCEL files (*.xlsx)|*.XLSX";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_selectFileClick(TObject *Sender)
{
	if (OpenDialog1->Execute() == false) {
		return;
	}

	m_srcFilename = OpenDialog1->FileName; // 読込み用の変数にセット
	m_dstFilename = StringReplace(m_srcFilename, L".xlsx", L"_1.xlsx", TReplaceFlags()<<rfReplaceAll);

	// 縮小表示
	E_srcFilepath->Text = MinimizeName(m_srcFilename, this->Canvas, E_srcFilepath->Width);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_addRowClick(TObject *Sender)
{
	if (m_srcFilename.Length() == 0) {
		String wrnmsg = L"ファイルが選択されていません。";
		ShowMessage(wrnmsg);
		return;
	}

	B_addRow->Enabled = false;

	Excel_addRow((WideString)m_srcFilename, (WideString)m_dstFilename);

	B_addRow->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Excel_addRow(WideString srcFile, WideString dstFile)
{
	Variant ExcelApp = CreateOleObject("Excel.Application");
	try
	{
		Variant xls_books;
		Variant xls_abook;
		Variant xls_sheets;
		Variant xls_asheet;

		try {
			ExcelApp.OlePropertySet("Visible", false); // Excel not shown

			xls_books = ExcelApp.OlePropertyGet("Workbooks");
			xls_abook = xls_books.OleFunction("Open", srcFile);
			// 最初のシート選択
			xls_abook.OlePropertyGet("Sheets", 1).OleProcedure("Select");
			xls_asheet = xls_abook.OlePropertyGet("ActiveSheet");
			//
			xls_asheet.OlePropertyGet("Rows", 1).OleProcedure("Insert");

			xls_abook.OleProcedure("SaveAs", dstFile); //開いた*.xlsxを別名保存
			ExcelApp.Exec(Procedure("Quit"));
			
            String msg = L"Save to [" + dstFile + L"]";
			ShowMessage(msg);
		}
		__finally
		{
            xls_asheet = Unassigned(); // 変数を初期状態に
            xls_sheets = Unassigned();
            xls_abook = Unassigned();
            xls_books = Unassigned();
		}
	}
	__finally
	{
		ExcelApp = Unassigned();
	}
}
```

### 実行例

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/50c98f80-4f35-c7b6-c71b-1c92ed9828c8.png)

保存先ファイルが既存の場合、以下のダイアログが表示される。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/7fee3ee1-f609-8cd6-3004-89830f12bef3.png)

**不具合: 上記のダイアログで[いいえ(N)]を選択すると、ExcelAppが残ったままになる。読込んだエクセルファイルが「使用中のファイル」になってしまう。**

### code v0.2

code v0.1の不具合対応。
下記を追加することで、保存ファイル既存の時のダイアログを非表示にする。

```cpp
ExcelApp.OlePropertySet("DisplayAlerts", false); // No dialog for overwrite
```

参考: http://www.acot.net/excelread/src1.html @ ACoTさん

情報感謝です。

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

#include <vcl.h>
#pragma hdrstop

#include <Vcl.FileCtrl.hpp>  // For MinimizeName()
#include <System.Win.ComObj.hpp>  // EXCEL処理用
#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

/*
v0.2 2018/04/13
	- fix bug > 既存ファイル上書きで「いいえ(N)」選択時、Excelが起動したままになる
		+ [DisplayAlerts]をfalseにした
v0.1 2018/04/13 EXCELファイルに１行挿入し、別ファイル保存
	- add B_selectFileClick()
	- add B_addRowClick()
	- add Excel_addRow()
*/


__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	// プログラム概要の表示
	Label1->Caption = L"選択したファイルの最初のシートの１行目に１行挿入します。\r\n"
		L"結果を別ファイル(_1.xlsx)に保存します。";

	OpenDialog1->Filter = L"EXCEL files (*.xlsx)|*.XLSX";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_selectFileClick(TObject *Sender)
{
	if (OpenDialog1->Execute() == false) {
		return;
	}

	m_srcFilename = OpenDialog1->FileName; // 読込み用の変数にセット
	m_dstFilename = StringReplace(m_srcFilename, L".xlsx", L"_1.xlsx", TReplaceFlags()<<rfReplaceAll);

	// 縮小表示
	E_srcFilepath->Text = MinimizeName(m_srcFilename, this->Canvas, E_srcFilepath->Width);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_addRowClick(TObject *Sender)
{
	if (m_srcFilename.Length() == 0) {
		String wrnmsg = L"ファイルが選択されていません。";
		ShowMessage(wrnmsg);
		return;
	}

	B_addRow->Enabled = false;

	Excel_addRow((WideString)m_srcFilename, (WideString)m_dstFilename);

	B_addRow->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Excel_addRow(WideString srcFile, WideString dstFile)
{
	bool closeExcel = false;

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

	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);
			// 最初のシート選択
			xls_abook.OlePropertyGet("Sheets", 1).OleProcedure("Select");
			xls_asheet = xls_abook.OlePropertyGet("ActiveSheet");
			//
			xls_asheet.OlePropertyGet("Rows", 1).OleProcedure("Insert");

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

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

### link

- [C++ Builder XE4 > Excel > Link > Access to Excel cells in "C++ Builder XE4" | +入力ファイル情報](https://qiita.com/7of9/items/6ec8b19c8d3b787e2699)
- [C++ Builder XE4 > Excel > link: 在C++Builder中利用OLE存取Excel文件 > Excel処理実装例 (中国語)](https://qiita.com/7of9/items/4ff4163e1a6dd650a4b0)
- [C++ Builder XE4 > Excel処理 > 1つめのシートを選択する (シート名は任意)](https://qiita.com/7of9/items/ff3a43911d3797da3dd2)