DelphiアプリケーションでExcelを操作する便利な方法を
全7回に分けてご紹介してまいります。
今回は前回よりさらに踏み込んだセル・行・列で実行できる操作についてご説明します。
- 第1回:基本編
- 第2回:印刷編
- 第3回:セル操作編(基本)
- 第4回:セル操作編(応用)
- 第5回:セル操作編(発展)
- 第6回:ウインドウ編
- 第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.Insert と Shapes.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月号より(選択範囲から画像取得)