Delphi と Excel の緊密な連携 [Wang Anpeng ([email protected]) 2002/4/14] 優れた RAD として、Delphi の強力なデータベース機能は最も重要な機能の 1 つですが、操作が難しい QuickReport コントロールは多くの場合、操作が困難です。データベースレポートのニーズを満たします。レポートが非常に複雑である場合、または形式の変更に柔軟性が必要な場合は、レポート サーバーとして Excel を使用するのが良い選択です。 Delphi バージョン 5 以降で提供される Excel コンポーネントは、OLE オートメーション テクノロジのアプリケーションを大幅に簡素化します。ただし、欠落しているヘルプ ファイルは常に Delphi で最も批判されている点であり、これらの新しいコンポーネントも例外ではありません。この記事ではこれについて詳しく紹介します。 Excel のオブジェクト モデルはツリー状の階層構造です。WorkBook はルート オブジェクトの属性オブジェクトです。この記事で主に説明するワークシートは、ワークブックの属性オブジェクトです。詳細については、MSOffice の VBA ヘルプ ファイルを参照してください。 Delphi で Excel を制御するには、まずサーバー プログラムとの接続を確立し、ワークブックを開いて、次にターゲット ワークシートとデータを交換し、最後に切断する必要があります。 Excel ワークブックを開く この例は、TStringGrid (もちろん一部のデータを入力する必要があります) と 2 つのボタンを備えたメイン フォームから始まり、コントロール パネルの [サーバー] タブから TExcelapplication コントロールをドラッグし、フォーム上に配置します。まず、ConnectKind を ckRunningOrNew に設定します。これは、実行中の Excel インスタンスが検出できれば接続を確立し、そうでなければ Excel を開始することを意味します。さらに、プログラムを実行するとすぐにサーバー プログラムとの接続を確立したい場合は、AutoConnect プロパティを True に設定できます。 Excel との接続を確立するために必要なのは、Excel . Connect; という 1 つのステートメントだけです。[サーバー] タブに他のいくつかの Excel コントロールがあることに気づいたかもしれません。これらのコントロールは、ConnectTo メソッドを通じて前の Excel にリンクできます。 Excel . ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel . ActiveSheet as _Worksheet); _Worksheet); さらに、ConnectTo メソッドを使用する前に、対応するブックまたはワークシートを開く必要があることに注意してください。したがって、これらのコントロールは、ほとんどの場合、追加の利便性をもたらさないため、TExcelApplication を 1 つだけ使用することをお勧めします。 Excel サーバーとの接続が確立されると、新しいワークブックを作成できます。 var wkBook : _WorkBook; LCID : Integer; ... LCID := GetUserDefaultLCID(); function 最初のパラメータは、新しいワークブックに使用されるテンプレートを定義するために使用されます。xlWBATChart、xlWBATExcel4IntlMacroSheet、を使用できます。 xlWBATExcel4MacroSheet または xlWBATWorksheet 定数、または既存の xls ファイルの名前にすることもできます。ここでの EmptyParam は Variant ユニットと定義された変数であり、デフォルトのユニバーサル テンプレートを使用して新しいワークブックを作成することを意味します。既存の xls ドキュメントを開く場合は、開くファイル名を最初のパラメーターとして Open 関数に渡す必要があります: wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam 、EmptyParam、EmptyParam、EmptyParam、EmptyParam、 EmptyParam,EmptyParam,LCID); 次のステートメントでは、_WorkSheet 変数を使用して現在のアクティブ セルを表すことを知っておく必要があります。ワークシートの名前がわかっている場合は、インデックス番号をワークシート名に置き換えることができます: wkSheet:=wkBook.Sheets[1] as _WorkSheet; データ交換が完了したら、ワークブックを保存する必要があります: Excel.ActiveWorkBook.SaveAs ('MyOutput', EmptyParam ,EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, LCID); または: Excel.ActiveWorkBook.Save(LCID); 最後に、ブックを閉じて Excel から切断します: wkBook.Close(True, SaveAsName, EmptyParam, LCID); ;ここの Close メソッドには、save 関数が含まれています。最初のパラメーターは、ワークブックを閉じる前に変更を保存するかどうかを示します。3 番目のパラメーターは、複数の作成者がドキュメントを処理するために使用されます。 2 行目では Excel を終了するように求められます。 ワークシートとのデータの交換 入力データは、アクティブなワークシートの特定のセルまたは範囲に対して実行されます。範囲とセルは両方ともワークシートのオブジェクト プロパティです。 Cells はセルのコレクションです。特定の場所が指定されていない場合は、ワークシート全体のすべてのセルを表すことができます。たとえば、WS.Cells.Item[1,1] などです。は、左上隅のセル A1 を表します。Item は VBA の Cells のデフォルトのプロパティなので省略できますが、Delphi にはそのような便利な機能はありません。セルに値を割り当てるには、その Value プロパティを参照する必要があります。言うまでもなく、このプロパティは次のようにバリアント変数です。もちろん、セルに値を割り当てることもできます。 var AFormula:String …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; 上記の方法は非常に直接的で簡単ですが、非常に時間がかかるため、大規模なレポートには適していません。では、すべてのデータを順番に Excel に転送できますか? Range を使用できます。このオブジェクトはワークシート内の領域を表します。通常は、Range[ 'C3 のように、その左上隅と右下隅のセルの位置を指定します。 '、'J42']。ここには小さな問題があります。データが 26 列を超える場合 (たとえば、100 列がある場合)、またはターゲット領域の範囲をその場で決定する必要がある場合、文字名を使用してセルをマークするのはさらに面倒です。 「C3」はセルのラベルであるため、もちろん Range[Cells.Item[1,1]、Cells.Item[100,100]] などの Cells も使用できることを思い出してください。 Range の値を配列にすることは考えられますが、Delphi で値を割り当てるために Array を使用してはなりません。 Delphi では、Excel オブジェクトの値は常に Variant 型であることに注意してください。 var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //ここに 100*100 の動的配列を作成します。ここで、wkSheet を使用した配列要素は Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas; を実行します。わかりやすくするために、ここではワークシートと Range の両方に Cells プロパティがあることに注意してください。さらに、VarArrayCreate で作成された 1 次元配列は、単一行の Range にのみ割り当てることができます。単一列の Range の値を定義する場合は、2 次元配列を使用する必要があります。例: Datas:=VarArrayCreate([1,100,1 ,1], varVariant); // 100*1 の動的配列を作成します。ちなみに、Cells.Item[] は実際には Range オブジェクトを返します。ワークシートからのデータの取得は、基本的にデータの書き込みの逆のプロセスです。注意が必要なのは、ワークシートのデータ範囲を決定する方法です。 var ir, ic : Integer …… wkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam;) ).Activate ; ir := Excel.ActiveCell.Row ic := Excel.ActiveCell.Column;ここでは、特殊セル関数 SpecialCells を巧みに使用して、データを含む最後のセルを取得しています。 データ編集 以下に、データ編集の 2 つの例を示します。 var DestRange: OleVariant; begin DestRange := Excel.Range['A1', 'B4']; 上記の例では、8 つのセルの内容がコピーされます。 Copy 関数に空のパラメーターを渡すと、この領域のデータがクリップボードにコピーされ、後で Paste メソッドを使用して他の場所に貼り付けることができます。 var WS: _Worksheet; …… Excel.Range['A1', 'B4'].Copy(EmptyParam); // ワークシートのデータをクリップボードにコピー WS := Excel.Activesheet as _Worksheet; // アクティビティ Worksheet を変更します。 .Range['C1', 'D4'].WS.Paste(EmptyParam, EmptyParam, lcid); //クリップボードの内容を新しいワークシートに貼り付けます。 書式設定 Excel をレポート サーバーとして選択するのは、主にその強力な書式設定機能のためです。まず、「アドレス帳」というタイトルのセルを結合して中央に表示し、フォントを太字の18ポイントの「公用書体」に変更します。 with wkSheet.Range['A1','D1'],Font do begin Merge(True ); // セルを結合します。セルの内容が長い場合は、内容の一部が表示されません。通常は、選択した領域の右端をダブルクリックして、各列の幅を内容の長さに合わせて自動的に調整します。 Delphi では、AutoFit メソッドを使用して列の幅と行の高さを適応させることもできます。このメソッドは行全体と列全体に対してのみ使用できます。それ以外の場合は、OLE メソッドの実行拒否のエラーが表示されます。 wkSheet.Columns.EntireColumn.AutoFit; 中国語スタイルのレポートには通常、上部と下部のキャップ付きの表の行が必要で、Borders コレクション プロパティを使用できます。 VBA のコレクション オブジェクトには通常、デフォルトの Item プロパティがあり、Delphi では省略できないことに注意してください。 Weight プロパティは、テーブルの線の太さを定義するために使用されます。Aname.RefersToRange では、Borders do begin horizontalAlignment:= xlRight; .Weight: =xlThin; item[xlInsideVertical].Weight:=xlThin; ページ設定と印刷ページ設定は、ワークシートの PageSetUp オブジェクト プロパティを通じて設定されます。 Excel VBA には 40 を超える用紙定数があらかじめ設定されています。一部のプリンタでは一部の用紙タイプしかサポートされていないことに注意してください。 Orientation 属性は印刷の方向を制御するために使用され、定数の landscape = 2 は水平印刷を示します。ブール値プロパティ Centerhorizontally および CenterVertical は、印刷されたコンテンツが水平方向と垂直方向の中央に配置されるかどうかを決定するために使用されます。 with wkSheet.PageSetUp do begin PaperSize:=xlPaperA4; // 用紙タイプ A4 PRintTitleRows := 'A1:D1' // この行/ページを繰り返します LeftMargin:=18; // 左マージン RightMargin:=18; // 0.25 インチはプリンタによって異なります。 TopMargin:=36; //0.5 インチ BottomMargin:=36; //0.5" Centerhorizontally:=True; Orientation:=1; //水平印刷 (ランドスケープ)=2、ポートレート=1 end; レポートを印刷するには、ワークシートの PrintOut メソッドを呼び出すことができます。VBA で定義されたこのメソッドは、合計 8 つのオプションのパラメータで、最初の 2 つは開始ページと終了ページ、および 3 番目の形式で印刷する部数を指定するために使用されます。ただし、Delphi では、最後に LCID パラメータが追加され、EmptyParam になります。このパラメータには使用できません。同様に、印刷プレビュー メソッド PrintPreview には VBA ではパラメーターがありませんが、Delphi で呼び出す場合は 2 つのパラメーターが必要です。 // wkBook.PrintPreview(True,LCID); // レポートの形式が次の場合、wkSheet.PrintOut(EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,LCID);より複雑な場合、より良い方法は、特定のテーブル範囲に名前を付けて、それらを名前で参照することです。 Names は WorkBook のコレクション オブジェクト プロパティであり、このジョブを実行できる Add メソッドがあります。 Var Aname : Excel2000.Name …… Aname := wkBook.Names.Add('アドレス帳','=Sheet1!$A$3:$D$7', EmptyParam, EmptyParam, EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam); Add 関数の最初のパラメータは定義された名前で、2 番目のパラメータは名前で表されるセル範囲です。範囲名の型には修飾子を使用する必要があることに注意してください。タイプ ライブラリ (D4) を使用する場合、修飾子は Excel_TLB です。さらに、名前付き範囲では絶対参照を使用する必要があります。つまり、「$」記号を追加する必要があります。範囲に名前を付けると、その名前でその範囲を参照できるようになります。次のコード行により、アドレス帳の内容が太字で表示されます。 Delphi で Excel マクロ プログラムを変更してください。次のコードは、ワークブックを閉じるときに最終アクセス時刻を記録するマクロを作成します。 var LineNo: integer; CM: CodeModule; begin CM := WkBook.VBProject.VBComponents.Item( 'ThisWorkbook')コードモジュール; LineNo := CM.CreateEventProc('BeforeClose', 'Workbook'); SDate:='最終アクセス日:'+DateToStr(Date()); CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+''"');マクロ 前の uses セクションにユニットを追加します: VBIDE2000。タイプ ライブラリが使用されている場合、対応するユニットは VBIDE_TLB です。このコードのキーは CodeModule オブジェクトです。残念ながら、Excel VBA ヘルプ ドキュメントにはこのオブジェクトの痕跡がないため、MSDN で検索するしかありません。 Delphi4 とそれ以前のバージョン Delphi4 では TExcelApplication オブジェクトが提供されていないため、OLE オートメーション テクノロジを使用するにはタイプ ライブラリを導入する必要があります。Excel97 のタイプ ライブラリは Excel8.olb です。これら 2 つの方法の主な違いは、サーバー プログラムとの接続を確立する方法です。タイプ ライブラリを使用して Excel を制御するためのプログラム フレームワークは、Windows、ComObj、ActiveX、Excel_TLB を使用します。 ; 不明:IUnknown 結果 : HResult; 開始 LCID := LOCALE_USER_DEFAULT := GetActiveObject(CLASS_Application, nil, Unknown); //実行中のプログラム インスタンスのキャプチャを試みます if (Result = MK_E_UNAVAILABLE) then Excel := CoApplication.Create //新しいプログラム インスタンスを開始します else begin {GetActiveObject メソッド呼び出し中のエラーを確認します} OleCheck(Result); (Unknown.QueryInterface(_Application, Excel)); end …… //データ処理を実行 Excel.Visible[LCID] := True; // Excel.DisplayAlerts[LCID] := False; // プロンプト ダイアログ ボックスを表示します。 Excel.Quit End;コスト 例外部分の実行速度。付随する関数 CoApplication および異なる Delphi バージョンによって生成される一部の定数名は異なる場合があるため、対応するタイプ ライブラリを確認する必要があることに注意してください。 Quit メソッドを呼び出す前に、プログラム内で作成されたすべてのワークブック変数とワークシート変数を必ず解放してください。解放しないと、Excel がメモリ内に常駐して実行される可能性があります (Ctrl+Alt+Del キーを押して表示できます)。 GetActiveObject を呼び出してプログラム インスタンスをキャプチャする場合、小さな問題が発生します。Excel が最小化された実行状態にある場合、プログラムのメイン フレームのみが表示され、ユーザー領域が表示されないことがあります。さらに、タイプ ライブラリを導入したくない場合は、遅延バインディングを使用することもできますが、かなり遅くなります。次の例では、Excel アプリケーションを表す Variant 変数を宣言します。 var Excel: Variant; ... try Excel := CreateOleObject('Excel.Application'); .Visible := True;遅延バインディングを使用する場合、コンパイラは呼び出される Excel オブジェクト メソッドをチェックしませんが、これらのタスクは実行中に完了するようにサーバー プログラムに任せます。このように、VBA によって設定される多数のデフォルト パラメータ (多くの場合、12 個以上) が設定されます。したがって、このメソッドには予期せぬ利点があります。コードは次のように簡潔です。 var WBk, WS, SheetName: OleVariant ..... WBk := Excel.WorkBooks.Open('C:/Test.xls; ');WS := WBk.Worksheets.Item['SheetName']; WS.Activate; …… WBk.Close(SaveChanges := True); タイプ ライブラリで定義された定数を使用する場合、自分でのみ行うことができます: const xlWBATWorksheet = -4167 …… XLApp.Workbooks.Add(xlWBatWorkSheet);最後に、Excel を閉じた後に変数を解放することを忘れないでください。 Excel := Unassigned; 以下は、この記事の例で使用されている、Delphi6+MSOffice2000 で渡されたソース コードです。ユニット Unit1; インターフェイスは Windows、メッセージ、SysUtils、バリアント、クラス、グラフィックス、コントロール、フォーム、ダイアログ、OleServer、Excel2000、グリッド、StdCtrls を使用します。プロシージャ FormActivate(Sender: TObject); Button1Click(Sender: TObject); プロシージャ Write2Xls; プロシージャ AddMacro; プロシージャ Public 宣言; ; 実装 {$R *.dfm} は VBIDE2000 を使用します。 wkSheet:_WorkSheet; Rows[1].CommaText:='張三、男性、25,010-33775566'; Rows[2].CommaText:='李思、男性、47,012-6574906'; Rows[3].CommaText:='金曜日、女性、18,061-7557381'; Rows[4].CommaText:='Sun Tao、女性、31,3324559'; end; Excel で開始する; wkBook:=WorkBooks.Add(EmptyParam) , LCID); wkSheet:=wkBook.Sheets[1] として _WorkSheet 終了; TForm1.Write2Xls; var Datas:Variant; 開始 ir:=StringGrid1.ColCount; :=1 から ir do for j:=1 から ic do Datas[i,j]:=StringGrid1.Cells[j-1,i-1]; wkSheet do begin Activate(LCID); Value:='Address Book'; .Item[3,1],cells.Item[ir+2,ic]].Value:=データ; // Excel.Visible[LCID]:=True; Datas:=Unassigned; プロシージャ TForm1.Retrieve; i,j:Integer; wkSheet で始まります。 =Excel.ActiveCell.Column; Datas:=Range[Cells.Item[1,1],Cells.Item[ir,ic]].Value; with StringGrid1 do begin ColCount:=ic; for i:=0; to ir-1 do for j:=0 to ic-1 do Cells[j,i]:=Datas[i+1,j+1]; Datas:=UnAssigned; 終了; プロシージャ TForm1.CloseExl; 開始 wkBook.Close(True,SaveAsName,EmptyParam,LCID);ネームシートの開始AName:=wkBook.Names.Add('アドレス帳','=Sheet1!$A$3:$D$7',EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam); プロシージャ TForm1 .AddFormula; var AFormula:String; AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; プロシージャ TForm1.Formats で始まります。 Font do begin Merge(True); // セルを結合します。 FontStyle:=Bold; wkSheet.Columns.EntireColumn.AutoFit; Aname.RefersToRange を使用して、Item[xlEdgeBottom].Weight:=xlMedium;項目[xlInside水平].Weight:=xlThin;プロシージャTFOrm1.AddMacro:整数; CM:= WkBook.VBProject。 VBComponents.Item('ThisWorkbook').Codemodule 行番号; := CM.CreateEventProc('BeforeClose', 'Workbook'); SDate:='最終アクセス日:'+DateToStr(Date()); CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+'"'); プロシージャ TForm1.Printit から始まります。 PaperSize:=xlPaperA4; //用紙タイプ A4 PrintTitleRows := 'A1:D1' //この行/ページを繰り返します LeftMargin:=18; //0.25 インチの左マージン RightMargin:=18; //0.25 インチはプリンタによって異なりますTopMargin:=36; //0.5 インチ BottomMargin:=36; //0.5 インチ Centerhorizontally:=True; Orientation:=1; //Landscape=2、portrait=1 end; wkSheet.PrintOut(EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,LCID); ; OpenExl を試し始めます。 NameSheet; PrintIt; ReTrieve; 最後に、Delphi の強力な RAD 関数が終了しました。これは最も重要な機能の 1 つですが、操作が難しい QuickReport コントロールではデータベース レポートのニーズを満たせないことがよくあります。レポートが非常に複雑である場合、または形式の変更に柔軟性が必要な場合は、レポート サーバーとして Excel を使用するのが良い選択です。 Delphi バージョン 5 以降で提供される Excel コンポーネントは、OLE オートメーション テクノロジのアプリケーションを大幅に簡素化します。ただし、欠落しているヘルプ ファイルは常に Delphi で最も批判されている点であり、これらの新しいコンポーネントも例外ではありません。この記事ではこれについて詳しく紹介します。 Excel のオブジェクト モデルはツリー状の階層構造です。WorkBook はルート オブジェクトの属性オブジェクトです。この記事で主に説明するワークシートは、ワークブックの属性オブジェクトです。詳細については、MSOffice の VBA ヘルプ ファイルを参照してください。 Delphi で Excel を制御するには、まずサーバー プログラムとの接続を確立し、ワークブックを開いて、次にターゲット ワークシートとデータを交換し、最後に切断する必要があります。 Excel ワークブックを開く この例は、TStringGrid (もちろん一部のデータを入力する必要があります) と 2 つのボタンを備えたメイン フォームから始まり、コントロール パネルの [サーバー] タブから TExcelApplication コントロールをドラッグし、フォーム上に配置します。まず、ConnectKind を ckRunningOrNew に設定します。これは、実行中の Excel インスタンスが検出できれば接続を確立し、そうでなければ Excel を開始することを意味します。さらに、プログラムを実行するとすぐにサーバー プログラムとの接続を確立したい場合は、AutoConnect プロパティを True に設定できます。 Excel との接続を確立するために必要なのは、Excel . Connect; という 1 つのステートメントだけです。[サーバー] タブに他のいくつかの Excel コントロールがあることに気づいたかもしれません。これらのコントロールは、ConnectTo メソッドを通じて前の Excel にリンクできます。 Excel . ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel . ActiveSheet as _Worksheet); _Worksheet); さらに、ConnectTo メソッドを使用する前に、対応するブックまたはワークシートを開く必要があることに注意してください。したがって、これらのコントロールは、ほとんどの場合、追加の利便性をもたらさないため、TExcelApplication を 1 つだけ使用することをお勧めします。 Excel サーバーとの接続が確立されると、新しいワークブックを作成できます。 var wkBook : _WorkBook; LCID : Integer; ... LCID := GetUserDefaultLCID(); function 最初のパラメータは、新しいワークブックに使用されるテンプレートを定義するために使用されます。xlWBATChart、xlWBATExcel4IntlMacroSheet、を使用できます。 xlWBATExcel4MacroSheet または xlWBATWorksheet 定数、または既存の xls ファイルの名前にすることもできます。ここでの EmptyParam は Variant ユニットと定義された変数であり、デフォルトのユニバーサル テンプレートを使用して新しいワークブックを作成することを意味します。既存の xls ドキュメントを開く場合は、開くファイル名を最初のパラメーターとして Open 関数に渡す必要があります: wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam 、EmptyParam、EmptyParam、EmptyParam、EmptyParam、 EmptyParam,EmptyParam,LCID); 次のステートメントでは、_WorkSheet 変数を使用して現在のアクティブ セルを表すことを知っておく必要があります。ワークシートの名前がわかっている場合は、インデックス番号をワークシート名に置き換えることができます: wkSheet:=wkBook.Sheets[1] as _WorkSheet; データ交換が完了したら、ワークブックを保存する必要があります: Excel.ActiveWorkBook.SaveAs ('MyOutput', EmptyParam ,EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, LCID); または: Excel.ActiveWorkBook.Save(LCID); 最後に、ブックを閉じて Excel から切断します: wkBook.Close(True, SaveAsName, EmptyParam, LCID); ;ここの Close メソッドには、save 関数が含まれています。最初のパラメーターは、ワークブックを閉じる前に変更を保存するかどうかを示します。3 番目のパラメーターは、複数の作成者がドキュメントを処理するために使用されます。 2 行目では Excel を終了するように求められます。 ワークシートとのデータの交換 入力データは、アクティブなワークシートの特定のセルまたは範囲に対して実行されます。範囲とセルは両方ともワークシートのオブジェクト プロパティです。 Cells はセルのコレクションです。特定の場所が指定されていない場合は、ワークシート全体のすべてのセルを表すことができます。たとえば、WS.Cells.Item[1,1] などです。は、左上隅のセル A1 を表します。Item は VBA の Cells のデフォルトのプロパティなので省略できますが、Delphi にはそのような便利な機能はありません。セルに値を割り当てるには、その Value プロパティを参照する必要があります。言うまでもなく、このプロパティは次のようにバリアント変数です。もちろん、セルに値を割り当てることもできます。 var AFormula:String …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; 上記の方法は非常に直接的で簡単ですが、非常に時間がかかるため、大規模なレポートには適していません。では、すべてのデータを順番に Excel に転送できますか? Range を使用できます。このオブジェクトはワークシート内の領域を表します。通常は、Range[ 'C3 のように、その左上隅と右下隅のセルの位置を指定します。 '、'J42']。ここには小さな問題があります。データが 26 列を超える場合 (たとえば、100 列がある場合)、またはターゲット領域の範囲をその場で決定する必要がある場合、文字名を使用してセルをマークするのはさらに面倒です。 「C3」はセルのラベルであるため、もちろん、Range[Cells.Item[1,1]、Cells.Item[100,100]] などのセルも使用できることを思い出してください。 Range の値を配列にすることは考えられますが、Delphi で値を割り当てるために Array を使用してはなりません。 Delphi では、Excel オブジェクトの値は常に Variant 型であることに注意してください。 var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //ここに 100*100 の動的配列を作成します。ここで、wkSheet を使用した配列要素は Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas; を実行します。わかりやすくするために、ここではワークシートと Range の両方に Cells プロパティがあることに注意してください。さらに、VarArrayCreate で作成された 1 次元配列は、単一行の Range にのみ割り当てることができます。単一列の Range の値を定義する場合は、2 次元配列を使用する必要があります。例: Datas:=VarArrayCreate([1,100,1 ,1], varVariant); // 100*1 の動的配列を作成します。ちなみに、Cells.Item[] は実際には Range オブジェクトを返します。ワークシートからのデータの取得は、基本的にデータの書き込みの逆のプロセスです。注意が必要なのは、ワークシートのデータ範囲を決定する方法です。 var ir, ic : Integer …… wkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam;) ).Activate ; ir := Excel.ActiveCell.Row ic := Excel.ActiveCell.Column;ここでは、特殊セル関数 SpecialCells を巧みに使用して、データを含む最後のセルを取得しています。 データ編集 以下に、データ編集の 2 つの例を示します。 var DestRange: OleVariant; begin DestRange := Excel.Range['A1', 'B4']; 上記の例では、8 つのセルの内容がコピーされます。 Copy 関数に空のパラメーターを渡すと、この領域のデータがクリップボードにコピーされ、後で Paste メソッドを使用して他の場所に貼り付けることができます。 var WS: _Worksheet; …… Excel.Range['A1', 'B4'].Copy(EmptyParam); // ワークシートのデータをクリップボードにコピー WS := Excel.Activesheet as _Worksheet; // アクティビティ Worksheet を変更します。 .Range['C1', 'D4'].WS.Paste(EmptyParam, EmptyParam, lcid); //クリップボードの内容を新しいワークシートに貼り付けます。 書式設定 Excel をレポート サーバーとして選択するのは、主にその強力な書式設定機能のためです。まず、タイトル「アドレス帳」のセルを結合して中央に表示し、フォントを太字の18ポイントの「公用書体」に変更します。 with wkSheet.Range['A1','D1'],Font do begin Merge(True ); // セルを結合します。セルのコンテンツが長い場合、コンテンツの一部は表示されません。通常は、選択した領域の右端をダブルクリックして、各列の幅をコンテンツの長さに合わせて自動的に調整します。 Delphi では、AutoFit メソッドを使用して列の幅と行の高さを適応させることもできます。このメソッドは行全体と列全体に対してのみ使用できます。それ以外の場合は、OLE メソッドの実行拒否のエラーが表示されます。 wkSheet.Columns.EntireColumn.AutoFit; 中国語スタイルのレポートには通常、上部と下部のキャップ付きの表の行が必要で、Borders コレクション プロパティを使用できます。 VBA のコレクション オブジェクトには通常、デフォルトの Item プロパティがあり、Delphi では省略できないことに注意してください。 Weight プロパティは、テーブルの線の太さを定義するために使用されます。Aname.RefersToRange では、Borders は、Item[xlEdgeBottom].Weight:=xlMedium; .Weight: =xlThin; item[xlInsideVertical].Weight:=xlThin; ページ設定と印刷ページ設定は、ワークシートの PageSetUp オブジェクト プロパティを通じて設定されます。 Excel VBA には 40 を超える用紙定数があらかじめ設定されています。一部のプリンタでは一部の用紙タイプしかサポートされていないことに注意してください。 Orientation 属性は印刷の方向を制御するために使用され、定数の landscape = 2 は水平印刷を示します。ブール値プロパティ Centerhorizontally および CenterVertical は、印刷されたコンテンツが水平方向と垂直方向の中央に配置されるかどうかを決定するために使用されます。 with wkSheet.PageSetUp do begin PaperSize:=xlPaperA4; // 用紙タイプ A4 PrintTitleRows := 'A1:D1' // この行/ページを繰り返します LeftMargin:=18; // 左マージン RightMargin:=18; // 0.25 インチはプリンタによって異なります。 TopMargin:=36; //0.5" BottomMargin:=36; Centerhorizontally:=True; Orientation:=1; //水平印刷 (横向き)=2、縦向き=1 end; レポートを印刷するには、VBA で定義されたこのメソッドを呼び出します。オプションのパラメータ、最初の 2 つは開始ページと終了ページ、および 3 番目の形式で印刷する部数を指定するために使用されます。ただし、Delphi では最後に LCID パラメータが追加され、このパラメータには EmptyParam は使用できません。 。同様に、Print Preview Method PrintPreviewにはVBAにはパラメーターがありませんが、Delphiで呼び出されると2つのパラメーターが必要です。 // wkbook.printpreview(lcid);より複雑で、より良いアプローチは、特定のテーブル範囲に名前を付けて、名前でそれらを参照することです。名前はワークブックのコレクションオブジェクトプロパティであり、このジョブを実行できる追加方法があります。 var aname:excel2000.name; emptyparam、emptyparam); ADD関数の最初のパラメーターは定義された名前で、2番目のパラメーターは名前で表されるセル範囲です。範囲名のタイプは、タイプライブラリ(D4)を使用する場合、予選はexcel_tlbであることに注意してください。さらに、名前付き範囲は絶対的な参照を使用する必要があります。つまり、「$」シンボルを追加します。レンジに名前を付けると、次のコードを参照できます。 DelphiでExcelマクロプログラムを変更してください!次のコードは、ワークブックを閉じるときの最後のアクセス時間を記録します。 codemodule; lineno:= cm.createeventproc( 'beforeclose'、 'workbook'); SDATE: '最終アクセス日:'+dateToStr(date());マクロは、以前の使用セクションにユニットを追加します:vbide2000が使用されている場合、対応するユニットはvbide_tlbです。このコードの鍵は、残念ながら、Excel VBAヘルプドキュメントにこのオブジェクトのトレースがないため、MSDNのみを検索できます。 Delphi4および以前のバージョンDelphi4は、TexcelApplicationオブジェクトを提供しておらず、Excel97のタイプライブラリはExcel8.olbです。これらの2つの方法の主な違いは、サーバープログラムとの接続を確立する方法です;未知); //実行中のプログラムインスタンスをキャプチャしようとします(mk_e_unavailable) (不明true; excel.displayalerts:= false;パーツの実行速度のコスト。添付の関数の併用と、異なるDelphiバージョンによって生成されたいくつかの定数名は異なる場合があるため、対応するタイプライブラリを確認する必要があることに注意する必要があります。 QUITメソッドを呼び出す前に、プログラムで作成されたすべてのワークブックとワークシートの変数を必ずリリースしてください。そうしないと、Excelはメモリに存在して実行できます(Ctrl+Alt+Delを押すと表示できます)。 Excelが最小化された状態にある場合、GetActiveObjectを呼び出すことには小さな問題があります。さらに、タイプライブラリを導入したくない場合は、遅延バインディングを使用することもできますが、はるかに遅くなります。次の例は、excel:excel:excel:createoleObject(excel.application ')を表すバリアント変数を宣言します.visible:= true;ラギングバインディングを使用する場合、コンパイラは呼び出されたExcelオブジェクトメソッドをチェックしませんが、これらのタスクをこの方法で完了するために、VBAによって設定された多数のデフォルトパラメーター(多くの場合1ダース)です。必要に応じて使用されるため、この方法には予期しない利点があります'); ws := wbk.worksheetsem ['Sheetname']……wbk.close:= sexl.quit; 、自分だけができます:const xlwbatworksheet = -4167;最後に、excel:= close excel:=以下は、delphi6+msoffice2000で渡されたソースコードです。ユニットユニット1;手順formactivate(送信者:tobject); button 1は、プライベート宣言}手順closexl; ; wksheet:_worksheet; rows [1] .commatext:= 'Zhang San、25,010-33775566' [2] = 'li si、男性、47,012-6574906'; 、18,061-7557381 ';行[4] = 'Sun Tao、31,3324559' 、lcid)= wkbooks [1] tform1.write2 := 1はjの場合はir:= 1からic doデータ[i、j]:= stringgrid1.cells [i-1]; .item [3,1]、cells.item [ir+2、ic]]。データ:= variant:integer。 = excel.activecell.column;データ:range [1,1]、cellsem [ir、ic] IR-1はJ:= 0からIC-1 doセル[j、i]:= datas [i+1、j+1];データは、end saveas.close.close. namesheet; aname:= wkbook.names.add( 'アドレス帳'、 '= sheet1!$ 3:$ d $ 7'、emattyparam、emptyparam、emattyparam、emathyparam、embyparam、emstyparam); .addformula:string; Aformula: '= rand()';フォントはマージ(true); fontstyle:= column.entirecolumn.autorange。項目[Xlinsideの項目]。 vbcomponents.item( 'thisworkbook') := cm.createeventproc( 'beforeclose'、 'workbook'); "+sdate+'"');論文:= xlpapera4; topmargin:= 36; //0.5 "bottommargin:= 36; //0.5"オリエンテーション:= 1; ; write2xlを試してください。 namesheet