前のブログで、ExcelのTypeライブラリーを使ってシート一覧を取得しましたが
ついでといっては、なんですが、dbGo(Ado)を使って、シート一覧を取得してみます。
TAdoQueryを使ってSQL文で、テーブル一覧を取得できないか、ちょっと調べたましたが
無理そうだったので、ここでは、
TADOConnection.OpenSchema (
const Schema: TSchemaInfo;
const Restrictions: OleVariant;
const SchemaID: OleVariant;
DataSet: TADODataSet);
メソッドを使ってテーブルを取得します。
方法は、簡単で、
OpenSchema関数のパラメータ
Schemaに TSchemaInfo.siTables
DataSetに スキーマ取得結果の書き込み先のレコードセットを指定します。
また、今回は、RestrictionsとSchemaIDは使用しませんのでEmptyParamを指定します。
さて、やってみます。
フォームにTADOConnectionを配置し、ConnectionStringの
ProviderにMicrosoft.ACE.OLEDB.12.0
Data SourceにExcelのワークブックのパス
Extended PropertiesにExcel 12.0(Excel2010の場合)
を指定します。
(ConnectionStringについては、http://connectionstrings.com/ が参考になります。)
次に結果格納先としての TADODataSetコンポーネントを配置し、Connectionプロパティに
上記の TADOConnectionコンポーネントを指定します。
あとは、通常の操作で、DataSource,DbGridを配置し、それぞれ接続します。
あとはボタンなどを配置しそのイベントハンドラに
ADOConnection1.Connected := true;
ADOConnection1.OpenSchema(siTables, EmptyParam, EmptyParam,ADODataSet1);
のようなコードを書きます。
で実行すれば、
のように結果が得られます(右側)
なお、torry's Delphiのページにもうちょっと詳しいサンプルがあります。http://www.swissdelphicenter.ch/torry/showcode.php?id=1433
また、AdoでのExcelのSchema,については、MSのHELP
http://support.microsoft.com/kb/257819/ja
が参考になります。
2012年6月7日木曜日
2012年6月3日日曜日
DelphiでExcelブック内のシート一覧を取得し表示する
先日、DelphiでExcelのWorkSheetを列挙しながらSheetを編集する処理を作成したとき、
思いもよらずはまったので、自分メモとして保存。
DelphiからExcelを操作する方法としては、
今回は、1.タイプタイプライブラリーをインポートしてExcelを操作しシート名を一覧表示する
処理をつかった。
以下、ソース
E2431 for-in ステートメントはコレクション型 'Sheets' で動作できません('Sheets' に 'GetEnumerator' のメンバが含まれていないかアクセスできないため)
のメッセージが、出てEXEが作れないため、従来のfor文で列挙している。
Excelのコレクションが1基数なので、for 文は、1からシート数まででにしていのが
ポイントです。(ポイントというもののものではありませんが・・・)
まあ、Excelに限らず、Win32版のVisual Basic(VB6,VB5)とか、VBAのコレクションInterface
は基本1基数なのですが・・・
下図のようなブックに対して
上のような処理を実行すると
のような結果がえられます。
以下は、余談ですが、
自分 、Excelのコレクションが1基数だということをすっかり忘れていて、結果、午前中つぶしちゃいました。
思いもよらずはまったので、自分メモとして保存。
DelphiからExcelを操作する方法としては、
- Excelのタイプライブラリーをインポート
- dbGoを使用する
- サードパーティのコンポーネントを使用する
- ・・・
今回は、1.タイプタイプライブラリーをインポートしてExcelを操作しシート名を一覧表示する
処理をつかった。
以下、ソース
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} uses Excel_TLB,System.Win.ComObj; const LCID = LOCALE_SYSTEM_DEFAULT; procedure TForm1.Button1Click(Sender: TObject); Var ExcelApp : Excel_TLB.ExcelApplication; ExcelBook : Excel_TLB.ExcelWorkbook; ExcelSheet : Excel_TLB.ExcelWorksheet; BookPath : String; i : integer; begin ListBox1.Clear; ExcelApp := CreateComObject(CLASS_ExcelApplication) as ExcelApplication; ExcelApp.DisplayAlerts[LCID] := false; BookPath := IncludeTrailingPathDelimiter(ExtractFileDir(Application.ExeName)) + 'Test.xlsx'; ExcelBook := ExcelApp.Workbooks.Add(BookPath, LCID); (* このように書きたいが 'GetEnumerator' のメンバが含まれていないかアクセスできないため) 通常では使用不可 for ExcelSheet in ExcelBook.Worksheets do begin ListBox1.Items.Add(ExcelSheet.Name); end; *) // Excelのコレクションは1基数なので1からカウントを始める。 for i := 1 to ExcelBook.Worksheets.Count do begin ExcelSheet := ExcelBook.Worksheets.Item[i] As Excel_TLB.ExcelWorksheet; ListBox1.Items.Add(ExcelSheet.Name); end; ExcelSheet := nil; ExcelBook.Close(false,BookPath,false,LCID); ExcelBook := nil; if Assigned(ExcelApp) then begin ExcelApp.Quit; ExcelApp := nil; end; end; end.for ~ in doの構文が使えると、基数のこと意識しなくても良いが、コンパイルすると
E2431 for-in ステートメントはコレクション型 'Sheets' で動作できません('Sheets' に 'GetEnumerator' のメンバが含まれていないかアクセスできないため)
のメッセージが、出てEXEが作れないため、従来のfor文で列挙している。
Excelのコレクションが1基数なので、for 文は、1からシート数まででにしていのが
ポイントです。(ポイントというもののものではありませんが・・・)
まあ、Excelに限らず、Win32版のVisual Basic(VB6,VB5)とか、VBAのコレクションInterface
は基本1基数なのですが・・・
下図のようなブックに対して
上のような処理を実行すると
のような結果がえられます。
以下は、余談ですが、
自分 、Excelのコレクションが1基数だということをすっかり忘れていて、結果、午前中つぶしちゃいました。
登録:
投稿 (Atom)