動作環境
RAD Studio 10.2 Tokyo Update 3
Excel 2016
処理概要
- Excelファイル(.xlsx)を開く
- セルD2の文字(
4
)をString型として取得する - TMemoに表示する
実装
Unit1.h
//---------------------------------------------------------------------------
# ifndef Unit1H
# define Unit1H
//---------------------------------------------------------------------------
# include <System.Classes.hpp>
# include <Vcl.Controls.hpp>
# include <Vcl.StdCtrls.hpp>
# include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE で管理されるコンポーネント
TButton *Button1;
TMemo *Memo1;
void __fastcall Button1Click(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
# endif
Unit1.cpp
//---------------------------------------------------------------------------
# include <vcl.h>
# pragma hdrstop
# include <System.Win.ComObj.hpp> // EXCEL処理用
# include <ClipBrd.hpp>
# include "Unit1.h"
//---------------------------------------------------------------------------
# pragma package(smart_init)
# pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
static const String kFile_import = L"Book_200121_1317.xlsx";
//static const String kFile_export = L"Modified_200121_1331.xlsx";
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Excel使用
Variant ExcelApp = CreateOleObject("Excel.Application");
// .exeフォルダにあるEXCELファイルのパス
String curDir = ExtractFileDir(Application->ExeName);
WideString srcfile = curDir + L"\\" + kFile_import; // WideStringでないとOleFunctions("Open")はエラーになる
try {
Variant xls_books;
Variant xls_abook;
Variant book_csv; // データ読込み用csv
Variant sheet_csv; // データ読込み用csv
Variant xls_sheets;
Variant xls_asheet;
try {
// 0. Excel初期処理
ExcelApp.OlePropertySet("Visible", true); // Excel表示
ExcelApp.OlePropertySet("DisplayAlerts", false); // No dialog for overwrite
ExcelApp.OlePropertySet("ScreenUpdating", true); // 更新あり
xls_books = ExcelApp.OlePropertyGet("Workbooks");
// 1. ファイルオープンとシート選択
xls_abook = xls_books.OleFunction("Open", srcfile);
xls_abook.OlePropertyGet("Sheets", 1).OleProcedure("Select");
xls_asheet = xls_abook.OlePropertyGet("ActiveSheet");
// 2. D2セル選択してクリップボードへ
Variant wrkRange = xls_asheet.OlePropertyGet("Range", WideString("D2"));
wrkRange.OleProcedure("Copy");
// 処理待ち
Application->ProcessMessages();
Sleep(300); // msec
// 3. クリップボードからの取得
String astr = Clipboard()->AsText;
Memo1->Lines->Add(astr); // 確認用出力
// 4. Excel終了
ExcelApp.Exec(Procedure("Quit"));
} __finally {
xls_asheet = Unassigned();
xls_abook = Unassigned();
xls_books = Unassigned();
}
}
__finally
{
ExcelApp = Unassigned();
}
}
//---------------------------------------------------------------------------
使用EXCELファイル例
下記はBook_200121_1317.xlsx
ファイルの中身。
セルD2を読む。
実行
[Button1]を押下するとExcelが起動してファイルを開き、TMemoに以下のように4を追記する。
備考
クリップボード読取りの前に300msecの待ちを入れた。これがないとエラーになる。
OLEのメソッドで直接読む方法はあるような気はする。
関連
補足 > CR, LF
String astr = Clipboard()->AsText;
にて取得した文字列にはCR, LFが後ろに付随する。
その後ろに文字列を結合する場合は、CR, LFを除去した上で結合すること (PasteSpecialにて二行になるため)。
備考 > クリップボードの読込み
クリップボードへのコピーと読込み処理。このあたりを短時間で実行するとエラーになりやすい。
待ち時間が必要。
300msecでもときどきエラーが出るようだ。
処理の問題
クリップボード経由だと、クリップボードの処理が重い。タイミングによってはエラーになる。
下記に実装している、getCellValue()
とsetCellValue()
を使った処理に変更するほうが良い。