アプリでDelphi(その1−1)

戻る

ここでは、VBC++BuilderDelphi で OLEオートメーションによる Excel97 コントロールの違いを見てみます。

OLEオートメーション

  • Sheet1 の "KAKAKU" セルにテキストボックス(VB)/エディットボックス(C++Builder/Delphi)から取り出した値をセットします。
  • 消費税5%の計算を行い、Sheet1 の "GOUKEI" セルにセットされた値を取り出し、テキストボックス(VB)/エディットボックス(C++Builder/Delphi)にセットします。
  • ここでは、単純な計算しか行っていませんが、アイデアしだいで使えるアプリケーションが作成できそうです。
  • Excel97 のOLEオートメーションを理解するためには、Excel97 VBA の理解が大切な要素となります。
  • 動作条件は Excel97 がインストールされていることです(^^;

 


VBの場合

  • フォームにテキストボックス(Text1、Text2)、コマンドボタン(Command1、Command2、Command3、Command4)、コモンダイアログ(CommonDialog1)を置いてください。
  • Text2 BackColor プロパティを適当な色にして、Locked プロパティTrue にしておきます。
  • ツールボックスにコモンダイアログがない場合は、マウスカーソルをツールボックス上に移動し、右クリックで [コンポーネント(O)...]を選び、[コンポーネント|コントロール]で ”Microsoft Common Dialog Control 5.0 (SP2)” をチェックしてください。
  • コマンドボタン1は、Excel97 の起動とブックのオープンを行います。
  • コマンドボタン2は、Text1 に入力した値を Excel97 で計算し、その結果を Text2 に代入します。
  • コマンドボタン3は、Excel97 を終了します。
  • コマンドボタン4は、プログラムを終了します。

先頭へダウンロード vb5ex97ole1.LZH (12KB)

Module1.bas

Option Explicit

'* WIN32API
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Form1.frm

Option Explicit

Private exApp As Object
Private wBooks As Object
Private wBook As Object
Private wSheets As Object
Private wSheet As Object
Private eRange As Object

Private Sub Command1_Click()
    Dim fname As String
    Dim msg As String
    
    '* Ex97起動 *
    ' ファイル選択(アプリ起動ディレクトリを初期ディレクトリにする)
    CommonDialog1.Flags = CommonDialog1.Flags Or cdlOFNHideReadOnly
    CommonDialog1.Filter = "Excel97ファイル (*.xls)|*.xls|すべてのファイル (*.*)|*.*"
    CommonDialog1.InitDir = App.EXEName
    CommonDialog1.CancelError = True
    On Error GoTo LCancel
    CommonDialog1.ShowOpen
    On Error GoTo 0
    fname = CommonDialog1.filename
    
    '* OLE オートメーション部
    ' Excel97 起動
    On Error GoTo LErrMsg
    msg = "Excel97が起動できません"
    Set exApp = CreateObject("Excel.Application.8")
    On Error GoTo 0
    ' Excel97 表示
    exApp.Visible = True
    
    ' このフォームをフォアグランドにする
    Call SetForegroundWindow(Form1.hwnd)
    
    ' Workbook オブジェクトのコレクションを得る
    Set wBooks = exApp.WorkBooks
    
    ' Workbook をオープンする
    On Error GoTo LErrMsg
    msg = fname & "が Excel97 で開けません"
    Set wBook = wBooks.Open(fname)
    On Error GoTo 0
    
    ' Worksheet オブジェクトのコレクションを得る
    Set wSheets = wBook.WorkSheets
    
    ' Worksheet オブジェクトを”Sheet1”に指定する
    On Error GoTo LErrMsg
    msg = "Sheet1 が見つかりません"
    Set wSheet = wSheets.Item("Sheet1")
    On Error GoTo 0
    
    Exit Sub

LErrMsg:
    ' エラー発生時
    msg = "エラー番号:" & Str(Err.Number) & " " & Err.Description & Chr(13) & msg
    Call MsgBox(msg, vbCritical, "実行時エラー")
LCancel:
    ' キャンセル時
End Sub

Private Sub Command2_Click()
    Dim msg As String
    
    '* 計算
    ' 値をセルにセット
    On Error GoTo LErrMsg
    msg = "Excel97は既に終了しているか、""KAKAKU""のセルが見つからない"
    Set eRange = wSheet.Range("KAKAKU")
    On Error GoTo 0
    eRange.Value = Text1.Text
    
    ' ワークシート再計算
    wSheet.Calculate
    
    ' 結果取り出し
    Set eRange = wSheet.Range("GOUKEI")
    Text2.Text = eRange.Value
    
    Exit Sub

LErrMsg:
    ' エラー発生時
    msg = "エラー番号:" & Str(Err.Number) & " " & Err.Description & Chr(13) & msg
    Call MsgBox(msg, vbCritical, "実行時エラー")
End Sub

Private Sub Command3_Click()
    Dim msg As String
    
    '* Ex97終了
    ' 保存確認ダイアログを非表示
    On Error GoTo LErrMsg
    msg = "Excel97 は既に終了しています"
    exApp.DisplayAlerts = False
    On Error GoTo 0
    
    ' Excel97 を終了する
    exApp.Quit
    
    Exit Sub

LErrMsg:
    ' エラー発生時
    msg = "エラー番号:" & Str(Err.Number) & " " & Err.Description & Chr(13) & msg
    Call MsgBox(msg, vbCritical, "実行時エラー")
End Sub

Private Sub Command4_Click()
    '* 閉じる(C)
    Unload Form1
End Sub


C++Builderの場合

  • フォームにエディット(Edit1、Edit2)、ボタン(Button1、Button2、Button3、Button4)、ファイル選択ダイアログ(OpenDialog1)を置いてください。
  • Edit2 Color プロパティを適当な色にして、ReadOlny プロパティtrue にしておきます。
  • ボタン1は、Excel97 の起動とブックのオープンを行います。
  • ボタン2は、Edit1 に入力した値を Excel97 で計算し、その結果を Edit2 に代入します。
  • ボタン3は、Excel97 を終了します。
  • ボタン4は、プログラムを終了します。

先頭へダウンロード bcb1ex97ole1.LZH (180KB)

Unit1.h

//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <vcl\Classes.hpp>
#include <vcl\Controls.hpp>
#include <vcl\StdCtrls.hpp>
#include <vcl\Forms.hpp>
#include <vcl\Dialogs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE 管理のコンポーネント
    TEdit *Edit1;
    TEdit *Edit2;
    TOpenDialog *OpenDialog1;
    TButton *Button1;
    TButton *Button2;
    TButton *Button3;
    TButton *Button4;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall Button2Click(TObject *Sender);
    void __fastcall Button3Click(TObject *Sender);
    void __fastcall Button4Click(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
private:    // ユーザー宣言
    Variant  exApp;
    Variant  wBooks;
    Variant  wBook;
    Variant  wSheets;
    Variant  wSheet;
    Variant  sRange;
public:     // ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit1.cpp


//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#include <vcl\oleauto.hpp>    // 追加
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // Ex97起動
    AnsiString  fname;

    // ファイル選択(アプリ起動ディレクトリを初期ディレクトリにする)
    OpenDialog1->Options << ofHideReadOnly;
    OpenDialog1->Filter = "Excel97ファイル (*.xls)|*.xls|すべてのファイル (*.*)|*.*";
    OpenDialog1->InitialDir = ExtractFileDir( Application->ExeName );
    if( OpenDialog1->Execute() == false )
        // キャンセル選択時
        return;
    fname = OpenDialog1->FileName;

    // OLE オートメーション部
    try {
        // Excel97 起動
        exApp = CreateOleObject( "Excel.Application.8" );
    }
    catch( EOleError& ){
        // 起動失敗
        ShowMessage( "Excel97 を起動することができません" );
        exApp = NULL;
        return;
    }
    catch(...){
        throw;
    }
    // Excel97 表示
    exApp.OlePropertySet( "Visible", "True" );

    // このフォームをフォアグランドにする
    SetForegroundWindow( Application->Handle );
    //This->Update;

    // Workbook オブジェクトのコレクションを得る
    wBooks = exApp.OlePropertyGet( "Workbooks" );

    // Workbook をオープンする
    try {
        wBook = wBooks.OleFunction( "Open", fname );
    }
    catch(EOleError&){
        // オープン失敗
        ShowMessage( fname + "が Excel97 で開けません" );
        exApp = NULL;
        return;
    }
    catch(...){
        throw;
    }

    // Worksheet オブジェクトのコレクションを得る
    wSheets = wBook.OlePropertyGet( "WorkSheets" );

    // Worksheet オブジェクトを”Sheet1”に指定する
    try {
        wSheet = wSheets.OlePropertyGet( "Item", "Sheet1" );
    }
    catch(EOleError&){
        // ワークシートの指定に失敗
        ShowMessage( "Sheet1 が見つかりません" );
        exApp = NULL;
        return;
    }
    catch(...){
        throw;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    // 計算
    Variant  work;

    // Range プロパティで”KAKAKU”を指定する
    try {
        sRange = wSheet.OlePropertyGet( "Range", "KAKAKU" );
    }
    catch(EOleError&){
        // セルの指定に失敗
        ShowMessage( "Excel97は既に終了しているか、\"KAKAKU\"のセルが見つからない" );
        exApp = NULL;
        return;
    }
    catch(...){
        throw;
    }

    // ”KAKAKU”に値をセットする
    work = Edit1->Text;
    sRange.OlePropertySet( "Value", work );

    // Worksheet オブジェクトで再計算
    wSheet.OleProcedure( "Calculate" );

    // Range プロパティで”GOUKEI”を指定する
    sRange = wSheet.OlePropertyGet( "Range", "GOUKEI" );

    // ”GOUKEI”の値をゲットする
    work = sRange.OlePropertyGet( "Value" );
    Edit2->Text = work;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
    // Ex97終了

    // 保存確認ダイアログを非表示
    try {
        exApp.OlePropertySet( "DisplayAlerts", "False" );
    }
    catch(EOleError&){
        // プロパティの指定に失敗
        ShowMessage( "Excel97 は既に終了しています" );
        exApp = NULL;
        return;
    }
    catch(...){
        throw;
    }

    // Excel97 を終了する
    exApp.OleProcedure( "Quit" );
    exApp = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
    // 閉じる(C)
    Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    exApp = NULL;
}
//---------------------------------------------------------------------------

Delphiの場合

  • フォームにエディット(Edit1、Edit2)、ボタン(Button1、Button2、Button3、Button4)、ファイル選択ダイアログ(OpenDialog1)を置いてください。
  • Edit2 Color プロパティを適当な色にして、ReadOlny プロパティtrue にしておきます。
  • ボタン1は、Excel97 の起動とブックのオープンを行います。
  • ボタン2は、Edit1 に入力した値を Excel97 で計算し、その結果を Edit2 に代入します。
  • ボタン3は、Excel97 を終了します。
  • ボタン4は、プログラムを終了します。

先頭へダウンロード d31ex97ole1.LZH (132KB)


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComObj;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;
  exApp: Variant;
  wBooks: Variant;
  wBook: Variant;
  wSheets: Variant;
  wSheet: Variant;
  eRange: Variant;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
   fname: AnsiString;
begin
    { Ex97起動 }
    // ファイル選択(アプリ起動ディレクトリを初期ディレクトリにする)
    OpenDialog1.Options := [ ofHideReadOnly ];
    OpenDialog1.Filter := 'Excel97ファイル (*.xls)|*.xls|すべてのファイル (*.*)|*.*';
    OpenDialog1.InitialDir := ExtractFileDir( Application.ExeName );
    if OpenDialog1.Execute = False Then
        // キャンセル選択時
        Exit;
    fname := OpenDialog1.FileName;

    // OLE オートメーション部
    try
        // Excel97 起動
        exApp := CreateOleObject('Excel.Application.8');
    except
        on EOleSysError do
        begin
            // 起動失敗
            ShowMessage('Excel97が起動できません');
            exApp := Null;
            Exit;
        end;
    end;
    // Excel97 表示
    exApp.Visible := True;

    // このフォームをフォアグランドにする
    SetForegroundWindow( Application.Handle );
    Update;

    // Workbook オブジェクトのコレクションを得る
    wBooks := exApp.WorkBooks;

    // Workbook をオープンする
    try
        wBook := wBooks.Open( fname );
    except
        on EOleSysError do
        begin
            // オープン失敗
            ShowMessage( fname + 'が Excel97 で開けません' );
            exApp := Null;
            Exit;
        end;
    end;

    // Worksheet オブジェクトのコレクションを得る
    wSheets := wBook.WorkSheets;

    // Worksheet オブジェクトを”Sheet1”に指定する
    try
        wSheet := wSheets.Item[ 'Sheet1' ];
    except
        on EOleSysError do
        begin
            // ワークシートの指定に失敗
            ShowMessage( 'Sheet1 が見つかりません' );
            exApp := Null;
            Exit;
        end;
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    { 計算 }
    // 値をセルにセット
    try
        eRange := wSheet.Range[ 'KAKAKU' ];
    except
        on EOleSysError do
        begin
            // セルの指定に失敗
            ShowMessage( 'Excel97は既に終了しているか、''KAKAKU''のセルが見つからない' );
            exApp := Null;
            Exit;
        end;
    end;
    eRange.Value := Edit1.Text;

    // ワークシート再計算
    wSheet.Calculate;

    // 結果取り出し
    eRange := wSheet.Range[ 'GOUKEI' ];
    Edit2.Text := eRange.Value;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
    { Ex97終了 }
    // 保存確認ダイアログを非表示
    try
        exApp.DisplayAlerts := False;
    except
        on EOleSysError do
        begin
            // プロパティの指定に失敗
            ShowMessage( 'Excel97 は既に終了しています' );
            exApp := Null;
            Exit;
        end;
    end;

    // Excel97 を終了する
    exApp.Quit;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
    { 閉じる(C) }
    Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    exApp := Null;
end;

end.

 

先頭へ/戻る