動作環境
- 実装
- C++ Builder XE4
- 確認
- Windows 8.1 Pro
- Excel 2016
処理概要
- xlsxファイルを開く
- csvファイルを開き、Range指定してコピーする
-
B1:B500
の範囲
-
- 1で開いたファイルにペースト
- 1で開いたファイルを別名保存
code
- srcFile: 読込みcsvファイル名
- baseFile: 読込みxlsxファイル名
- dstFile: 保存ファイル名
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <System.Win.ComObj.hpp> // EXCEL処理用
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnConvertClick(TObject *Sender)
{
String curDir = ExtractFileDir(Application->ExeName);
WideString srcFile = curDir + "\\0624\\240000_1.csv";
WideString baseFile = curDir + "\\base.xlsx";
WideString dstFile = curDir + "\\out.xlsx";
Variant ExcelApp = CreateOleObject("Excel.Application");
DWORD stTim = GetTickCount();
try
{
Variant xls_books;
Variant xls_abook;
Variant book_csv; // データ読込み用csv
Variant sheet_csv; // データ読込み用csv
Variant xls_sheets;
Variant xls_asheet;
try {
Memo1->Lines->Add(L"start: " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
// Excel初期処理
ExcelApp.OlePropertySet("Visible", false); // Excel not shown
ExcelApp.OlePropertySet("DisplayAlerts", false); // No dialog for overwrite
ExcelApp.OlePropertySet("ScreenUpdating", false); // 処理の高速化のため
xls_books = ExcelApp.OlePropertyGet("Workbooks");
// 1. 保存対象ファイル
xls_abook = xls_books.OleFunction("Open", baseFile);
xls_abook.OlePropertyGet("Sheets", 1).OleProcedure("Select");
xls_asheet = xls_abook.OlePropertyGet("ActiveSheet");
Memo1->Lines->Add(L"fin:Open " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
// 2. 行列のコピー
book_csv = xls_books.OleFunction("Open", srcFile);
book_csv.OlePropertyGet("Sheets", 1).OleProcedure("Select");
sheet_csv = book_csv.OlePropertyGet("ActiveSheet");
Variant wrkRange = sheet_csv.OlePropertyGet("Range", WideString("B1:B500"));
wrkRange.OleProcedure("Copy");
book_csv.OleProcedure("Close");
Memo1->Lines->Add(L"fin:Copy " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
// 3. ペースト
xls_asheet.OlePropertyGet("Cells", /*row=*/1, /*column=*/3).OleProcedure("Select");
xls_asheet.OleProcedure("PasteSpecial"); // 書式なしペースト
Memo1->Lines->Add(L"fin:Paste " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
// 4. 別名保存
ExcelApp.OlePropertySet("ScreenUpdating", true); // 高速化のための設定を戻す
xls_abook.OleProcedure("SaveAs", dstFile); //開いた*.xlsxを別名保存
ExcelApp.Exec(Procedure("Quit"));
Memo1->Lines->Add(L"fin:Save " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
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();
book_csv = Unassigned();
sheet_csv = Unassigned();
}
}
__finally
{
ExcelApp = Unassigned();
}
}
//---------------------------------------------------------------------------
備考
csvファイルから読込む部分を別関数化しようとしたが、Variant型の扱いが問題なのか、エラーが出た。
備考2
(追記 2018/07/11)
xls_asheet.OleProcedure("PasteSpecial"); // 書式なしペースト
上記の実行では「書式なし」にはなっていないだろう。
形式を選択して貼り付ける(PasteSpecialメソッド)を参考に下記のようにしてみたが、「WorksheetクラスのPasteSpecialメソッドが失敗しました。」というエラーになる。
xls_asheet.OleProcedure("PasteSpecial", -4163); // 書式なしペースト