ExcelのデータをDelphiで読み込むには?

解決


かわにー  2003-09-04 22:06:30  No: 4605

お世話になっております。
さっそくですが過去ログの
「ExcelのデータをDelphiで読み込むには」にて、
ウォレスさんの以下のサンプルで
保存したファイルからは読み込めましたが
現在表示されている、シートの内容を
読み込むには、どのようにすればよいのでしょうか?

それともシートの内容が更新される度に、
上書き保存してやる必要がありますか?

よろしくお願いします。

---------------------------------------------------
var
  ExcelApp: Olevariant;
  ExcelBook: Olevariant;
  ExcelSheet: Olevariant;
  iRow: Integer;
  iCol: Integer;
  Ctmp: Variant;
begin
  ExcelApp := CreateOleObject('Excel.Application');
  ExcelBook := ExcelApp.WorkBooks.Open('c:\tmp\test.xls', False);
  ExcelSheet := ExcelBook.WorkSheets['テスト用'];
  Memo1.Clear;
  for iRow := 1 to 5 do
  begin
    Ctmp := '';
    for iCol := 1 to 5 do
    begin
      Ctmp := ExcelSheet.Cells[iRow, iCol].value;
      Memo1.Lines.Add(InttoStr(Ctmp));
    end;
  end;
end;
---------------------------------------------------


さだ  2003-09-04 22:56:43  No: 4606

ここにExcelを操作するクラスがありますよ。
これではできないだろうか?
http://www.geocities.jp/lupin_home/


かわにー  2003-09-07 08:20:38  No: 4607

さださん、ありがとうございます。
やってみましたが、やはり保存されたデータ
でないとダメみたいなので、それで
やります。
イマイチ納得はできませんが・・・・


Mr.XRAY  URL  2003-09-07 22:45:04  No: 4608

解決済みということですが,ちょっとのぞいたものでから...

「現在表示されている」の意味が不明なのですが.
1. 表示されているブックのあるシートのセル値を取得したが
    既に保存済みのデータが表示されてしまう.
2. ブックを表示してからその値をMemo1に表示したい.

もし,2.であれば,
ExcelSheet := ExcelBook.WorkSheets['テスト用'];
のあとに,
ExcelApp.Visible:=True;
を追加すれば表示は可能です.

意味を取り違えていたらごめんなさい.


かわにー  2003-09-08 10:38:15  No: 4609

Mr.XRAY様、ありがとうございます。
実は、私がやりたい事は、

ファイルに保存されていない、Excelのデータを
Delphiで読み込む(操作する)事なんです。

現状はDelphiで出来そうにないので、データを
入力した後に必要に応じてファイルに出力してもらい
それをインターバルタイマーなどで読み込む仕様で
納得してもらおうかと思った次第です。

あれからも調べていたら、VBの掲示板でこの表現で
の質問を見つけまして、うまい表現だなと思いました。
VBでは出来るようなんですけど・・・・


ウォレス&グルミット  2003-09-09 06:38:25  No: 4610

ええと、既に解決済みとなっていますが・・・
私もこの件に関しては知りたいです。

ビギナーなりの想像です。
ハンドルからOLEヴァリアントへのオブジェクト代入(言葉遣いは正しい?)ができればいいのですよね?

CreateOleObject  のかわりに  GetActiveOleObject  を使うにしてもファイル名が必要ですので、1度も保存されてないEXCELには無理そうですし。

ハンドルの取得はEnumWindowsProcで出来そうです(あたりまえ?)


Mr.XRAY  2003-09-09 09:49:19  No: 4611

[Servers]タブのTExcelApplicationなら,既に起動中のExcelに
接続できるんだけどな...
このコンポのConnectメソッドです.

同じようなものが,OleObjectというんですか,あるのではないかと
思うのですが.調べる気力なし.ゴメン!!


ウォレス&グルミット  2003-09-09 18:17:58  No: 4612

>Servers]タブ・・・・

それって多分professional版ですよね?
私みたいなサンデープログラマはDelphi6Personalです。トホホ

やはり、起動中のExcelに接続するのは(出来るのでしょうが)面倒そうですね。


Mr.XRAY  2003-09-09 21:53:56  No: 4613

できますよ.できるはずですよ.
今最初のコードを見直したら,保存済みのブックを読出していますよね.
目的は,
新規にブックを作成して表示する.
このブックのあるシートのあるセルに値を入力する.
この値を取得する.

でしたよね.
だったら既存のブックを,わざわざ開く必要はありません.

{ブック追加}
WorkBook := Excel.Workbooks.Add;
{WorkSheet1をアクティブにする。}
  WorkSheet := WorkBook.WorkSheets[1];
{WorkSheet1をアクティブにする。}
  WorkSheet := WorkBook.WorkSheets[1];

として,このシートを対象にすればいいだけのはずです.


ウォレス  2003-09-09 23:02:27  No: 4614

かわにーさんの目的は、
>新規にブックを作成して表示する.
の部分が、「Delphiではなく、ユーザの場合」に、ということですよね?
一度も保存されていない場合、ブックをうまくOLEヴァリアントに代入する(用語使いが変かも)ことができません。

Mr.XRAYさんのおっしゃるように、Addメソッドを実行しましたが、接続しないようです・・・

頓珍漢でしたらすいません。


Mr.XRAY  2003-09-10 04:19:01  No: 4615

>頓珍漢でしたらすいません。

これは違いますね.多分,頭の中で考えている動作がお互いに異なって
いるためだと思います.以下にテストしてコードをリストします.
多分,ウォレスさんのは2.じゃないかと思います.私が想像したのは
1.の方です.新規だからどちらでも同じだと思ったんです.

それと,D6 Personal版でも,ちょっと面倒ですけど,ActiveXの取込み
をすると,TExcelApplicationが使えるようになります.

では,コード流します(Private以降).

  private
    { Private 宣言 }
     Excel: Variant;
     WorkBook: Variant;
     WorkSheet: Variant;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// 感想
// OleObjectはコード補完機能が使えないのが不便
// 逆にExce VABのコードがそのまま利用可能なのは便利
// でもやっぱりTExctApplictionの方が私はいい
// 以下のコードはusesにComobjが必要

//====================================================================
//   1.
//   新規にブックを作成し表示する
//   表示したExelのセルに値をセット
//====================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
     {Excelのオブジェクトを作成}
     Excel := CreateOleObject('Excel.Application');
     {ブックを作成}
     WorkBook := Excel.Workbooks.Add;
     {シートオブジェクトを定義}
     WorkSheet := WorkBook.WorkSheets[1];
     {表示}
     Excel.Visible:=True;

     {セルA1に文字ABCをセット}
     WorkSheet.Cells[1,1].Value:='ABC';
end;
//====================================================================
//   2.
//   既に誰かが表示したエクセルを操作する
//   でも誰だ.このプログラムを起動する人とは別?
//====================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
     {表示中のExcelのオブジェクトを取得}
     Excel:=GetActiveOleObject('Excel.Application');

     {シートオブジェクトを定義(ここではSheet3)}
     WorkSheet := Excel.WorkSheets[3];
     {そのシートをアクティブにする}
     WorkSheet.Activate;
     {表示}
     Excel.Visible:=True;

     {セルA1に文字ABCをセット}
     WorkSheet.Cells[1,1].Value:='ABC';
end;
//====================================================================
//   終了処理
//   これでいいのかは不明(取敢えずメモリリークはない)
//====================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
     try
       WorkBook.close;
       WorkBook:=unAssigned;
       WorkSheet:=unAssigned;
       Excel.Quit;
       Excel:=unAssigned;
     except
     end;
end;

end.


Mr.XRAY  2003-09-10 07:56:44  No: 4616

スンマセン.Button2のクリックイベント修正します.
前のだと,エクセルが起動していない場合にOLEエラーが発生します.

procedure TForm1.Button2Click(Sender: TObject);
begin
     try
       {表示中のExcelのオブジェクトを取得}
       Excel:=GetActiveOleObject('Excel.Application');
     except
       ShowMessage('エクセルが起動していません');
       exit;
     end;

     {シートオブジェクトを定義(ここではSheet3)}
     WorkSheet := Excel.WorkSheets[3];
     {そのシートをアクティブにする}
     WorkSheet.Activate;
     {表示}
     Excel.Visible:=True;

     {セルA1に文字ABCをセット}
     WorkSheet.Cells[1,1].Value:='ABC';
end;


Mr.XRAY  2003-09-10 09:19:49  No: 4617

再びごめんなさい.WorkBookへの接続を忘れていました.
というわけで,以下にコードをUPしました.変更があれば
ここで修正します.

http://homepage2.nifty.com/Mr_XRAY/Others/OleObject_for_Excel1.htm


ウォレス  2003-09-10 20:39:41  No: 4618

HP拝見しました。

同じようにしたつもりですが、やはり、表示中のEXCELには接続できませんでした。
(新規作成はうまく行きました)

Win2K+SP4+Delphi6Personalです。
環境の差でしょうか・・・?

どなたか近い環境の方で試していただける方いませんでしょうか・・?


Mr.XRAY  2003-09-10 22:32:48  No: 4619

Win2K+D6 Personal+Excel2000
Win2k+D6 Peraonal+Excel97

で実行しました.表示中のExcelにも接続しました.
ただし,「同じように」ではなく,HPにUPしたコードのままです.

同じようにではなく,同じコードだとどうなるか確認してみて下さい.
つま,Sheet3のA1セルにABCが入力されるかどうかですね.
(そうしないと会話が成り立ちません)

それでダメなら他の方法を考える必要があります.


Jボス  2003-09-10 22:53:28  No: 4620

Win2K+SP4+Delphi6 Enterprise
では、うまくいきましたよ!
Button2Clickの中だけでもコピー∩ペーストしてみるといいかも
しれませんよ。


LupinⅢ  URL  2003-09-10 23:37:25  No: 4621

ウォレスさんのExcelはExcel95っていうことはないですか?

そうするとCells[1,1]という風な使い方はできません。
ここの部分は忘れてしまいましたがCells????のように指定するはずです。


ウォレス  2003-09-11 02:24:32  No: 4622

※EXCELのバージョンは2000です。

目を皿のようにして間違いを探しましたが、判りません。
(そもそもHPからコピペしているので、ボタンの番号が入れ替わってない限り、差はないのです。)
ぐお〜なんで私だけ?と思いつつ、ただ何度も実行しつづけていると、(その間コードは触らず)突然、出来るように!
そして、また何度か実行していると、また全く接続しないように・・・

IDEと実行ファイルと両方試してみましたが、両者に特別差があるようにも思えません。

とにかく再現性が極めて低いようです。やはり環境なのかな・・・
今からPC立ち上げなおしてやってみます。


LupinⅢ  URL  2003-09-11 02:39:05  No: 4623

うーん、そうしたら出来ない状態の時にタスクマネージャーを確認してみてください。
表示上はExcelが起動していないのにタスクマネージャーの中でExcelのExeが起動していたりしていませんか?
実際には表示上見えていないExcelに接続しているのかもしれません。


ウォレス  2003-09-11 02:40:21  No: 4624

お騒がせしています。

PC立ち上げ直後に試してみましたが接続できません。
EXCELの新規作成は必ず成功します。
しかし、接続の方はうまくいきません(><)

結局、先ほど3度ほど成功しただけで後は全く思うように行きません。
皆さんは成功されているようなので、PCの環境の差じゃないかな、と思います。


ウォレス  2003-09-11 02:53:37  No: 4625

LupinⅢさん、ありがとうございます。
タスクマネージャで確認しましたが、プロセスにもEXCELらしきものは見当たりませんでした。
しかし、変なことに気づきました。
タスクマネージャでEXCELがいないことを確認  →  Button2をクリック
で、本来ならShowMessageを行うはずですが、ここに飛びません。

・・・というかButton2のイベントが関連付けられていないではないですか・・
あれえ?Button1と4は関連付けられているのに??
そもそも、先ほど成功したのに・・・と言い訳してみます(汗

あまりに初歩的なミスで恥ずかしい限りです。みなさん、おさわがせしました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加