0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++ Builder 10.2 Tokyo > Excel 2016 + OLE > .xlsxファイルを開いてセルから値を読込み、TMemoに表示 (クリップボード経由)

Last updated at Posted at 2020-01-21
動作環境
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を読む。

2020-01-21_15h40_03.png

実行

[Button1]を押下するとExcelが起動してファイルを開き、TMemoに以下のように4を追記する。

2020-01-21_15h38_25.png

備考

クリップボード読取りの前に300msecの待ちを入れた。これがないとエラーになる。
OLEのメソッドで直接読む方法はあるような気はする。

関連

補足 > CR, LF

String astr = Clipboard()->AsText;にて取得した文字列にはCR, LFが後ろに付随する。
その後ろに文字列を結合する場合は、CR, LFを除去した上で結合すること (PasteSpecialにて二行になるため)。

備考 > クリップボードの読込み

クリップボードへのコピーと読込み処理。このあたりを短時間で実行するとエラーになりやすい。
待ち時間が必要。
300msecでもときどきエラーが出るようだ。

処理の問題

クリップボード経由だと、クリップボードの処理が重い。タイミングによってはエラーになる。
下記に実装している、getCellValue()setCellValue()を使った処理に変更するほうが良い。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?