Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


Delphi OLEのExcel操作術 第5回:セル操作編(発展)

DelphiアプリケーションでExcelを操作する便利な方法を
全7回に分けてご紹介してまいります。

今回は前回よりさらに踏み込んだセル・行・列で実行できる操作についてご説明します。

 

※第1~4回でも使用した以下の変数は、今回も引き続き使用します。

uses節には「System.Win.ComObj」を追加しておいて下さい。
(Delphi XE以前では「ComObj」)

var // 「OLEのExcel操作術」各Tips共通で使用する変数宣言
  MsExcel: OleVariant;       // ExcelのOLE変数
  MsApplication: OleVariant; // アプリケーションのOLE変数
  WBook: OleVariant;         // ブックのOLE変数
  WSheet: OleVariant;        // シートのOLE変数

また、記事中の各コードは対象となるExcelアプリケーションなどの各変数が
設定されていることが前提です。
(プログラムではExcelファイルが開かれるコードを実行した状態になります)
手っ取り早く検証のみ行いたい場合は、上記変数定義ののち以下を記述します。

  // Excel起動
  MsExcel := CreateOleObject('Excel.Application');
  MsApplication := MsExcel.Application;
  MsApplication.Visible := True;

  // 新規ファイルを作成
  WBook  := MsApplication.WorkBooks.Add ;
  WSheet := WBook.ActiveSheet;

 

また、本文中で登場するExcel側で決められた定数は
constで宣言しておくとわかりやすくなります。

(※uses節に「Excel2000」を追加しておくと本記事で使用する名前の定数の大半が
  含まれているため、const宣言不要になります。
  またExcel2000ではなく「Office2000」または「OfficeXP」に含まれる定数もあります。)

 


画像の挿入

本項では画像を挿入する方法についてご説明します。
画像挿入の方法は Pictures.InsertShapes.AddPicture の2通りあります。

 

【Pictures.Insertメソッド】
挿入する位置(画像の左上が来るセル)をSelectした後、画像ファイル名を指定します。
Excel上でのサイズは画像ファイルそのままの大きさになります。

なお、Excel 2010以降でPictures.Insertメソッドを使用すると、
画像が埋め込みではなくリンクオブジェクトとして挿入されます。

埋め込まないためブックのファイルサイズは軽くなりますが、
リンク元となる画像ファイルが移動・削除または名前の変更で参照できなくなると、
図が表示されなくなります
のでご注意ください。

<参考情報>
Excel 2010 で Pictures.Insert メソッドを使用して図をワークシートに挿入すると図がリンク オブジェクトとして挿入される(Microsoft サポート)

const
  // この定数を省略する場合、usesにExcel2000だけでなくOffice2000またはOfficeXPも必要
  msoTrue  = $FFFFFFFF;
  msoFalse = $00000000;
var
  wPic : Variant;
begin

  // 単純な図の挿入
  WSheet.Cells[5, 5].Select;  // 挿入位置
  WSheet.Pictures.Insert('C:\AppTest\Blue hills.jpg'); 

  // 画像サイズ変更(倍率指定)
  WSheet.Cells[15, 5].Select; // 挿入位置
  wPic := WSheet.Pictures.Insert('C:\AppTest\Blue hills.jpg');
  wPic.ShapeRange.ScaleWidth(0.5, False);   // 横方向倍率 50%
  wPic.ShapeRange.ScaleHeight(0.5, False);  // 縦方向倍率 50%

  // 画像サイズ変更(縦横比固定)①②のいずれかのみ実施でよい
  WSheet.Cells[25, 5].Select;     // 挿入位置
  wPic := WSheet.Pictures.Insert('C:\AppTest\Blue hills.jpg');
  wPic.ShapeRange.Width  := 100;  // ①
  wPic.ShapeRange.Height := 100;  // ② 

  // 画像サイズ変更(縦横比固定しない場合)
  WSheet.Cells[35, 5].Select; // 挿入位置
  wPic := WSheet.Pictures.Insert('C:\AppTest\Blue hills.jpg');
  wPic.ShapeRange.LockAspectRatio := msoFalse;  // 縦横比固定しない
  wPic.ShapeRange.Width  := 100;  // 横方向倍率 100%
  wPic.ShapeRange.Height := 100;  // 縦方向倍率 100%

 

【Shapes.AddPictureメソッド】
Shapes.AddPicture では既存のファイルから図オブジェクトを作成します。

ここではWidth・Heightの指定を省略できません。
このため画像サイズのままで挿入するには、一旦ダミー値を設定し、
その後元のサイズに戻す処理を行います。

このコード内の「msoTrue」「msoFalse」は、
上記Pictures.Insertメソッドで説明したconst値と同じものです。
「msoTrue」は元の画像サイズに対して行うことを表し、1はそれに対する倍率です。

また、上記Pictures.Insertメソッドでは画像がリンクオブジェクトとして挿入されますが、
Shapes.AddPictureを使えば引数の設定でリンクさせないことも可能です。
(画像そのものを埋め込むためファイルサイズは増大するものの、元の画像が参照できなくなっても影響を受けません)

const
  // この定数を省略する場合、usesにExcel2000だけでなくOffice2000またはOfficeXPも必要
  msoTrue  = $FFFFFFFF;
  msoFalse = $00000000;

var
  wPic : Variant;
begin
  // Width・Heightはダミーの値
  wPic := WSheet.Shapes.AddPicture('C:\AppTest\Blue hills.jpg',   // 画像ファイルパス
                                    LinkToFile:=False,            // リンクさせない
                                    SaveWithDocument:=True,       // 文書と図を一緒に保存
                                    Left:=MsExcel.Selection.Left, // 左端に貼り付け
                                    Top:=MsExcel.Selection.Top,   // 上端に貼り付け
                                    Width:=100,                   // 図の幅(ダミー)
                                    Height:=100);                 // 図の高さ(ダミー)

  // 元のサイズに戻す
  wPic.ScaleHeight(1, msoTrue);
  wPic.ScaleWidth (1, msoTrue);

  // 画像サイズ変更(倍率指定)※倍率0.5で縮小する場合
  wPic.ScaleHeight(0.5, msoTrue);
  wPic.ScaleWidth (0.5, msoTrue);

  // 画像サイズ変更(サイズ指定…縦横比固定)※①②のいずれかのみ実施でよい
  wPic.Height := 100; // ①
  wPic.Width  := 100; // ②

  // 画像サイズ変更(サイズ指定…縦横比固定なし)
  // Pictures.Insertメソッドと同様、LockAspectRatioの値で設定
  wPic.LockAspectRatio := msoFalse;
  wPic.Height := 100;
  wPic.Width  := 100;

 


セルの結合と解除

本項ではセルを結合する方法をご紹介します。

セルの結合は次のようにRangeで設定したセル領域の
MergeCellsプロパティに対して、Trueを設定します。

  WSheet.Range['A1:A3'].MergeCells := True;

 

解除するときには逆にFalseを設定します。
このときのセル指定は上記のように範囲指定でも、
その中に含まれるセルをひとつだけ指定しても行えます。

  WSheet.Range['A2'].MergeCells := False;

 

また結合した結果に対して、以前の第3回でご紹介した
寄せる方向を指定することで、レイアウトを整えることができます。

// 縦・横方向とも中央に寄せる場合)
const
  xlHAlignCenter = 4294963188;
  xlVAlignCenter = 4294963188;
begin
  WSheet.Range['A1:A3'].MergeCells := True;
  WSheet.Range['A1'].VerticalAlignment   := xlVAlignCenter;
  WSheet.Range['A1'].HorizontalAlignment := xlHAlignCenter;

 

左上端以外のセルに値が入っている場合、警告メッセージがExcelから表示されます。

  • (Excel 365の場合)セルを結合すると、左上の値のみが保持され、他のセルの値は破棄されます。
  • (Excel 2010の場合)選択範囲には複数のデータ値があります。1 つのセルとして結合すると、選択したセル範囲にある最も左上端にあるデータのみが保持されます (空白セルは無視されます)。

これを表示しないようにするには、セルの結合の前に次のコードを追加します。

  MsApplication.DisplayAlerts := False;

ただしセル結合以外のExcelからのメッセージ(閉じる前の保存確認など)も
表示されなくなりますので、MergeCellsをTrueにする処理が終わったら、
必要に応じてDisplayAlertsをTrueに戻して下さい。

 


並び替え(ソート)

ここからは、「並び替え(ソート)」を行う方法をご紹介します。

基本的なソート手順

並び替えを行うには、Rangeを使ってソートするデータ範囲を指定し、
その範囲に対してSortメソッドを実行します。
その時にソート項目とソート順(照準/降順)を指定します。

const
  xlAscending  = $00000001;
  xlDescending = $00000002;
・・・
  WSheet.Range['A1:C5'].Sort(Key1 := WSheet.Range['B1:B5'],
                             order1:= xlAscending);

ソート対象とソート項目は、上記の『Range[‘A1:C5’]』のように、
開始と終了のセルを指定していますが、それ以外に開始セルのみ指定することも可能です。
開始セルから連続した領域が範囲と見なされますので、最終セルが不定の場合などに便利です。

  WSheet.Range['A1'].Sort(Key1 := WSheet.Range['B1'],
                          order1:= xlAscending);

 

また、次の指定を含めることができます。

  • Header
    • xlYes(先頭行をタイトル行とし、2行目以降がソート対象)
    • xlNo (範囲全体がソート対象)
    • xlGuess(Excelが先頭行がタイトルかを自動判断)
  • MatchCase
    • True (大文字と小文字を区別)
    • False(大文字と小文字を区別しない)
  • Orientation
    • xlTopToBottom(列はそのままで行が入れ替わる)
    • xlLeftToRight(行はそのままで列が入れ替わる)

なお複数項目の指定も可能です。(3つまで)
前述のソート項目以外の指定も含めた形では次のようになります。

const
  xlAscending  = $00000001;
  xlDescending = $00000002;

  xlGuess = $00000000;
  xlYes   = $00000001;
  xlNo    = $00000002;

  xlTopToBottom = $00000001;
  xlLeftToRight = $00000002;
begin
  ・・・
  WSheet.Range['A1'].Sort(Key1 := WSheet.Range['B1'],
                          order1:= xlAscending,
                          Key2 := WSheet.Range['A1'],
                          order2:= xlDescending,
                          Key3 := WSheet.Range['C1'],
                          order3:= xlAscending,
                          Header:=xlGuess,
                          MatchCase:=False,
                          Orientation:=xlTopToBottom);

 

より高度なソート手順(Excel 2007~)

旧バージョンのExcelでは仕様としてソート項目は3つまででしたが、
Excel 2007以降では変更になり、また方法も異なっています。
(※Excel 2007以降でも前項のソート手順は行えます。)

SheetのSort.SortFieldsに並び替え項目を追加していきます。
必要な指定は、列と昇順(xlAscending)/降順(xlDescending)です。
またソートを行うデータ範囲はSort.SetRangeで指定し、ソートはSort.Applyを実行します。

次の例では、B(降順)・A(昇順)・C(昇順)・D(昇順)の順に並び替えています。

const
  xlAscending  = $00000001;
  xlDescending = $00000002;
begin
  ・・・
  WSheet.Sort.SortFields.Clear;
  WSheet.Sort.SortFields.Add(Key:=WSheet.Range['B1'],Order:=xlDescending);
  WSheet.Sort.SortFields.Add(Key:=WSheet.Range['A1'],Order:=xlAscending);
  WSheet.Sort.SortFields.Add(Key:=WSheet.Range['C1'],Order:=xlAscending);
  WSheet.Sort.SortFields.Add(Key:=WSheet.Range['D1'],Order:=xlAscending);
  WSheet.Sort.SetRange(WSheet.Range['A1:H1048576']);
  WSheet.Sort.Apply;

 

また、前項で紹介した「Header」「MatchCase」「Orientation」の指定を行う場合、
次のようなコードをApplyの実行前に入れる形になります。

const
  xlAscending  = $00000001;
  xlDescending = $00000002;

  xlGuess = $00000000;
  xlYes   = $00000001;
  xlNo    = $00000002;

  xlTopToBottom = $00000001;
  xlLeftToRight = $00000002;
begin
  ・・・
  WSheet.Sort.Header:=xlYes;
  WSheet.Sort.MatchCase:=False;
  WSheet.Sort.Orientation:=xlTopToBottom;
  WSheet.Sort.Apply;

 


Excelの選択範囲から画像取得

ここからは、Delphi/400でExcelから選択範囲の画像取得のテクニックをご紹介いたします。

OLEのExcel操作では、マクロのように細かい操作もプログラムで実現可能です。
例えば開いたExcelのSheet(WSheet)に対して、
A1セルからD6セルの位置範囲を画像としてコピーする場合、下記のように記述できます。

// 例)A1からD6セルを画像としてクリップボードにコピー
WSheet.Range['A1:D6'].CopyPicture;

これでクリップボードに画像情報が保存されますので、
実行後にペイントツールなどに「貼り付け」すると
セル情報が画像としてコピー/貼り付けするできることができます。

 


(本記事は、以下の資料をもとに最新情報を含めた再構成をしております。)

  • ミガロ.情報マガジン「MIGARO News!!」
    • Vol.129 2011年8月号より(画像の挿入)
    • Vol.132 2011年11月号より(セルの結合と解除)
    • Vol.136 2012年3月号より(並び替え)
    • Vol.137 2012年4月号より(高度な並び替え)
    • Vol.179 2015年10月号より(選択範囲から画像取得)