LoginSignup
1
2

More than 5 years have passed since last update.

C++ Builder XE4 > Excel 2016 + OLE > 5行5列代入の高速化 > ScreenUpdatingをfalseにする

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

処理概要

  • ファイルを開く
  • Excel + OLEでの値代入
  • Range選択、コピー・ペースト
  • ファイルを保存

5行5列のセルへの値代入を高速化できないか。

処理速度の検討

C++ Builder XE4 > Excel + OLE > 5x5代入、コピー、ペーストの処理時間
の記事において、5行5列のセルの値代入に4.9秒かかっている。

Excel 2013 vs Excel 2010 Ole or interop performance
を見つけた。

Excel 2013になってからOLE関連で処理が遅くなったようだ。
OLE2.set_property( Application, 'ScreenUpdating', FALSE);で対応するとあり、試してみた。

code

Uni1.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 + "\\base.xlsx";
    WideString dstFile = curDir + "\\out.xlsx";

    //--- Excel処理
    bool closeExcel = false;

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

    DWORD stTim = GetTickCount();

    try
    {
        Variant xls_books;
        Variant xls_abook;
        Variant xls_sheets;
        Variant xls_asheet;

        try {

            Memo1->Lines->Add(L"start: " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));

            ExcelApp.OlePropertySet("Visible", false); // Excel not shown
            ExcelApp.OlePropertySet("DisplayAlerts", false); // No dialog for overwrite
#if 1 // 2018/07/06
            ExcelApp.OlePropertySet("ScreenUpdating", false);
#endif

            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");

            Memo1->Lines->Add(L"start:Fill " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));

            // 1. Fill
            for (int ci = 1; ci <= 5; ci++) { // ci: column index
                for (int ri = 1; ri <= 5; ri++) { // ri: row index
                    xls_asheet.OlePropertyGet("Cells", ri, ci).OlePropertySet("Value", WideString("3.141592"));
                }
            }

            Memo1->Lines->Add(L"fin:Fill " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));

            // 2. Copy and Paste
            Variant wrkRange = xls_asheet.OlePropertyGet("Range", WideString("A1:E5"));
            wrkRange.OleProcedure("Copy");
            xls_asheet.OlePropertyGet("Cells", 7, 7).OleProcedure("Select");
            xls_asheet.OleProcedure("Paste");

            Memo1->Lines->Add(L"fin:Copy " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));

            // 3. Save
#if 1 // 2018/07/06
            ExcelApp.OlePropertySet("ScreenUpdating", true);
#endif

            xls_abook.OleProcedure("SaveAs", dstFile); //開いた*.xlsxを別名保存
            closeExcel = true;
            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();
        }
    }
    __finally
    {
        ExcelApp = Unassigned();
    }
}
//---------------------------------------------------------------------------

結果

下記は対処前の結果。

  • ファイルオープン: 21.9秒
  • 5行5列の代入: 4.9秒
  • コピーとペースト: 1.1秒
  • 保存: 19.7秒

下記は対処後 (ScreenUpdatingをfalse)。

  • ファイルオープン: 22.4秒
  • 5行5列の代入: 1.3秒 (高速化した)
  • コピーとペースト: 0.3秒 (高速化した)
  • 保存: 19.4秒

全体で43.485秒。

1
2
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
1
2