LoginSignup
0
1

More than 5 years have passed since last update.

C++ Builder XE4 > Excel 2016 + OLE > csvファイルを読込んで、コピーし、xlsxファイルにペーストして、別名保存

Last updated at Posted at 2018-07-06
動作環境
- 実装
    - C++ Builder XE4
- 確認
    - Windows 8.1 Pro
    - Excel 2016

処理概要

  1. xlsxファイルを開く
  2. csvファイルを開き、Range指定してコピーする
    • B1:B500の範囲
  3. 1で開いたファイルにペースト
  4. 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); // 書式なしペースト
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