.NET 開発者の観点から捉えた Excel オブジェクト モデル

  http://msdn.microsoft.com/ja-jp/library/cc326832.aspx

因为range object太重要了所以就只介绍这个,和word一样

Range オブジェクト


Range オブジェクトは、Excel アプリケーションで最も使用頻度の高いオブジェクトです。Excel 内のある範囲を操作できるようにするには、その範囲を Range オブジェクトとして表現し、その Range メソッドやプロパティを操作することが必要です。Range クラスは非常に重要です。この文書のすべてのサンプルで、何らかの方法で Range オブジェクトが使用されています。基本的に、Range オブジェクトはセル、行、列、1 つ以上のセル ブロックを含む一群のセル (連続もしくは非連続)、複数のシート上のセルのグループを表します。

数多くある Range クラスのすべてのメンバを説明することは不可能なので、このセクションでは 3 つの重要な問題に焦点を当てます。 

  • コード内で範囲を参照する。
  • コード内で範囲を操作する。
  • Range オブジェクトを使用して特定の目的を達成する。
つまり、Range オブジェクトの使用方法は状況によって何通りもあるため、このセクションでは全体的なメンバのリストを提供するのではなく、「~するには ?」という質問に答えていきます。

選択の管理

現在の選択を使用して範囲のプロパティや動作を変更しがちですが、これはできるだけ避け てください。ほかの共有リソースと同様、Excel 内の選択はユーザーの選択を表します。もしこれをコード内で変換してしまうとユーザーは現在の選択を制御できなくなります。大切なことは、ユーザーの選択 を変更したい場合にのみオブジェクトの Select メソッドを呼びだすということです。開発者として都合がいいからという理由だけで Select メソッドを変更するのは好ましくありません。範囲のプロパティを設定する方法は他にもあります。Select メソッドの使用を回避すれば、コードの実行速度が上がるだけでなく、ユーザーの満足度を上げることもできます。

以下のようなコードを記述して、ユーザーが現在操作しているセルに隣接する範囲を簡単にクリアすることができます。

' Visual Basic
ThisApplication.ActiveCell.CurrentRegion.Select
DirectCast(ThisApplication.Selection, Excel.Range).ClearContents
// C#
ThisApplication.ActiveCell.CurrentRegion.Select();
((Excel.Range)ThisApplication.Selection).ClearContents();

この方法を実行するとユーザーの選択は失われます。最初に選択されたセルが 1 つだけであっても、上記のコードを実行すると隣接するセル ブロック全体が選択されます。全部のセルを選択することが目的でない限りは、以下のコードを使用してください。

' Visual Basic
ThisApplication.ActiveCell.CurrentRegion.ClearContents
// C#
ThisApplication.ActiveCell.CurrentRegion.ClearContents();

最初に紹介したフラグメントを使用する場合もあります。Excel 開発の初心者は、Excel 内でさまざまなオブジェクトやメソッドの使用方法を試行錯誤しているうちにマクロ レコーダを使用するようになる傾向があるので、このようなコードが時々記述されます。これは良いアイデアですが、マクロ レコーダが書くコードは実にひどいものです。一般的に、マクロ レコーダは選択を使用し、タスクを記録するときにその選択を変更します。

ヒント    1 つのセルもしくはセルのグループを操作するには、可能であれば、選択を変更するのではなく目的のセルを表す範囲を使用します。ユーザーの選択を変更することが目的であれば、Range.Select メソッドを使用します。

コード内の範囲の参照

Range クラスは非常に柔軟性があるので、プログラムで範囲を操作する際には多すぎるほどの選択肢があります。Range オブジェクトは単一オブジェクトの場合もあれば、一連のオブジェクトを表す場合もあります。ItemCount メンバがあるので、Range オブジェクトはたいていの場合、単一オブジェクトを指しますが、Range オブジェクトの使い方を判断するのが困難な場合もあります。

ヒント    以下のいくつかの例を使用して範囲の Address プロパティを検索することができます。このプロパティは、"$A$1" (A1 に位置するセル)、"$1" (ワークシートの最初の行)、そして "$A$1:$C$5" (A1 と C5 で囲まれる四角内のすべてのセルからなる範囲) などを含むいくつかのフォーマットのうちの 1 つの範囲の座標の表示を含む文字列を返します。"$" は相対座標と対照的な絶対座標を表しています。Address プロパティを使用すれば、検索した範囲の正確な位置が簡単に分かります。範囲の参照方法についての詳細は Excel オンライン ヘルプを参照してください。

簡単に言えば、以下のリストに記載されたコードを記述して Range オブジェクトが単一セルとグループのセル、どちらを参照するのかを指定することができます[range对象引用的是哪个对象]それぞれの例には以下のセット アップ コードがあります。

' Visual Basic
Dim ws As Excel.Worksheet = _
DirectCast(ThisWorkbook.Worksheets(1), Excel.Worksheet)
Dim rng, rng1, rng2 As Excel.Range
// C#
Excel.Worksheet ws = (Excel.Worksheet)ThisWorkbook.Worksheets[1];
Excel.Range rng, rng1, rng2;

以下のいずれかのテクニックを使用して、特定の範囲を参照できます (Range オブジェクトの参照を取得する方法は他にもいくつかあります)。

  • Application オブジェクトの ActiveCell プロパティを参照します。
    ' Visual Basic
    rng = ThisApplication.ActiveCell
    // C#
    rng = ThisApplication.ActiveCell;
  • オブジェクトの Range プロパティを使用して範囲を指定します。C# はパラメータ表現された非インデックス型プロパティをサポートしていないので、代わりパラメータを 2 つ必要とする get_Range メソッドを呼び出す必要があります。
    ' Visual Basic
    rng = ws.Range("A1")
    rng = ws.Range("A1:B12")
    // C#
    rng = ws.get_Range("A1", Type.Missing);
    rng = ws.get_Range("A1:B12", Type.Missing);
  • ワークシートの Cells プロパティを使用して単一の行と列の値を指定します。
    ' Visual Basic
    ' セルのコレクションは Object を返します。
    ' これを明示的な Range オブジェクトに変換します:
    rng = DirectCast(ws.Cells(1, 1), Excel.Range)
    // C#
    rng = (Excel.Range)ws.Cells[1, 1];
  • 範囲の "コーナー" を指定します。範囲内の Cells プロパティ、Rows プロパティ、および Columns プロパティを直接参照することもできます。それぞれの場合、プロパティは範囲を返します。
    ' Visual Basic
    rng = ws.Range("A1", "C5")
    rng = ws.Range("A1", "C5").Cells
    rng = ws.Range("A1", "C5").Rows
    rng = ws.Range("A1", "C5").Columns
    // C#
    rng = ws.get_Range("A1", "C5");
    rng = ws.get_Range("A1", "C5").Cells;
    rng = ws.get_Range("A1", "C5").Rows;
    rng = ws.get_Range("A1", "C5").Columns;
  • セル参照を参照します。このテクニックはこの文書の随所で使用されています。C# の get_Range メソッドはパラメータを 2 つ必要とし、範囲名はパラメータを 1 つしか必要としないので、2 番目のパラメータに Type.Missing を指定する必要があります。
    ' Visual Basic
    rng = ThisApplication.Range("SomeRangeName")
    // C#
    rng = ThisApplication.Range("SomeRangeName", Type.Missing);
  • 特定の行、列もしくは行の範囲と列の範囲を参照します。RowsColumns のプロパティはそれぞれ Object を返すので Option StrictOn に設定されている場合は変換が必要です。
    ' Visual Basic
    rng = DirectCast(ws.Rows(1), Excel.Range)
    rng = DirectCast(ws.Rows("1:3"), Excel.Range)
    rng = DirectCast(ws.Columns(3), Excel.Range)
    // C#
    rng = (Excel.Range)ws.Rows[1, Type.Missing];
    rng = (Excel.Range)ws.Rows["1:3", Type.Missing];
    rng = (Excel.Range)ws.Columns[3, Type.Missing];
Application オブジェクトの Selection プロパティを使用して、選択されたセルと一致する範囲を返すことができます。図 20 のような状況では以下のコードで文字列 "$C$3" を返すことができます (絶対座標を示すために "$" を使用します)。

' Visual Basic
Debug.WriteLine( _
DirectCast(ThisApplication.Selection, Excel.Range).Address)
// C#
System.Diagnostics.Debug.WriteLine(
((Excel.Range)ThisApplication.Selection).
get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing));

    ヒント    Address プロパティも、パラメータ化されたプロパティのうちの 1 つで、C# では直接操作できません。get_Address メソッドを呼び出し、Range オブジェクトに対応するアドレスを検索します。Address プロパティのパラメータはすべて任意ですが、get_Address メソッドではパラメータは 5 つ検索されます。しかし、アドレスの形式を指定する 3 番目のパラメータ以外はおそらく必要ありません。

他の 2 つの範囲の結合を含む範囲を作成します (カッコ内に 2 つの範囲をカンマで区切って指定します)。

' Visual Basic
rng = ThisApplication.Range("A1:D4, F2:G5")
' Application オブジェクトの Union メソッドを使用して
' 2 つの範囲の共通部分を検索することもできます:
rng1 = ThisApplication.Range("A1:D4")
rng2 = ThisApplication.Range("F2:G5")
rng = ThisApplication.Union(rng1, rng2)
// C#
rng = ThisApplication.get_Range("A1:D4, F2:G5", Type.Missing);
// Application オブジェクトの Union メソッドを使用して
// 2 つの範囲の共通部分を検索することもできます。
// ただし、C# ではさらに多くの追加の作業が必要です:
rng1 = ThisApplication.get_Range("A1", "D4");
rng2 = ThisApplication.get_Range("F2", "G5");
// Union メソッドには 30 のパラメータの供給が
// 要求されることに注意してください: rng = ThisApplication.Union(rng1, rng2, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
他の 2 つの範囲の共通部分を参照する範囲を作成します (カッコ内に 2 つの範囲を区切り文字なしで指定します)。

' Visual Basic
rng = ThisApplication.Range("A1:D16 B2:F14")
' Application オブジェクトの Intersect メソッドを使用して
' 2 つの範囲の共通部分を検索することもできます:
rng1 = ThisApplication.Range("A1:D16")
rng2 = ThisApplication.Range("B2:F14")
rng = ThisApplication.Intersect(rng1, rng2)
// C#
rng = ThisApplication.get_Range("A1:D16 B2:F14", Type.Missing);
// Application オブジェクトの Intersect メソッドを使用して
// 2 つの範囲の共通部分を検索することもできます。 Note
// 30 のパラメータを渡す必要があることに注意してください:
rng1 = ThisApplication.get_Range("A1", "D16");
rng2 = ThisApplication.get_Range("B2", "F14");
rng = ThisApplication.Intersect(rng1, rng2, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
範囲の Offset プロパティを使用してオリジナルの範囲に対応する範囲を検索します。以下の例では、行 1、列 1 に位置するセルの下の領域にコンテンツを加えます。

' Visual Basic
rng = DirectCast(ws.Cells(1, 1), Excel.Range)
Dim i As Integer
For i = 1 To 5
rng.Offset(i, 0).Value = i.ToString
Next
// C#
rng = (Excel.Range) ws.Cells[1, 1];
for (int i = 1; i <= 5; i++)
{
rng.get_Offset(i, 0).Value2 = i.ToString();
}
ヒント    Range.Offset プロパティはパラメータ化されたプロパティなので、C# コードは直接その値を検索することはできません。代わりに、C# 開発者は get_Offset メソッドを呼び出す必要があります。
現在作業中の領域を示す範囲を検索するには、範囲の CurrentRegion プロパティを使用します。たとえば 図 20 で示されるような一番近くの空の行と列で囲まれた領域です。以下の表現式を使用して現在作業中の領域のフォントを太字にできます。
' Visual Basic
ThisApplication.Range("C3").CurrentRegion.Font.Bold = True
// C#
ThisApplication.get_Range("C3", Type.Missing).
CurrentRegion.Font.Bold = True;

範囲の操作

ある範囲の参照を取得した後に何ができるか見ていきます。実にさまざまなことができます。このセクションでは Range オブジェクトの操作のためのいくつかのテクニックに焦点を当て、各テクニックの簡単な例を示します。このセクション内のすべてのサンプルはサンプル ワークブックの Range Class シート内にあります。

範囲のオートフィル

B>Range クラスの AutoFill メソッドを使用すると、ある範囲内に自動的に値を入力することができます。多くの場合、AutoFill メソッドは、連続して増加または減少する値を範囲内に入力するときに利用します。XlAutoFillType 列挙体 (xlFillDaysxlFillFormatsxlFillSeriesxlFillWeekdaysxlGrowthTrendxlFillCopyxlFillDefaultxlFillMonthsxlFillValuesxlFillYearsxlLinearTrend) の中から任意の定数を供給すると、フィルの形式を指定することができます。フィル タイプを指定しない場合、Excel はデフォルトのフィル タイプ (xlFillDefault) が要求されていると判断し、適合する値を指定の範囲にフィルします。

図 24 のサンプル ワークシートはオートフィルされる 4 つの範囲を示しています。列 B は 5 つの平日の曜日を含み、列 C は5 つの月を含み、列 D は 年ごとに増加する 5 年分の日を含み、列 E はそれぞれの行ごとに 2 ずつ増える一連の数を含みます。サンプル コードを実行すると、同じ範囲が図 25 のようになります。

図 24. 4 つのサンプル範囲に AutoFill メソッドを呼び出す前

図 25. 範囲をオート フィルした後

[AutoFill] リンクをクリックすると以下のようなプロシージャが実行されます。

' Visual Basic
Private Sub AutoFill()
Dim rng As Excel.Range = ThisApplication.Range("B1")
rng.AutoFill(ThisApplication.Range("B1:B5"), _
Excel.XlAutoFillType.xlFillDays)
rng = ThisApplication.Range("C1")
rng.AutoFill(ThisApplication.Range("C1:C5"), _
Excel.XlAutoFillType.xlFillMonths)
rng = ThisApplication.Range("D1")
rng.AutoFill(ThisApplication.Range("D1:D5"), _
Excel.XlAutoFillType.xlFillYears)
rng = ThisApplication.Range("E1:E2")
rng.AutoFill(ThisApplication.Range("E1:E5"), _
Excel.XlAutoFillType.xlFillSeries)
End Sub
// C#
private void AutoFill()
{
Excel.Range rng = ThisApplication.get_Range("B1", Type.Missing);
rng.AutoFill(ThisApplication.get_Range("B1:B5", Type.Missing), Excel.XlAutoFillType.xlFillDays);
rng = ThisApplication.get_Range("C1", Type.Missing);
rng.AutoFill(ThisApplication.get_Range("C1:C5", Type.Missing), Excel.XlAutoFillType.xlFillMonths);
rng = ThisApplication.get_Range("D1", Type.Missing);
rng.AutoFill(ThisApplication.get_Range("D1:D5", Type.Missing), Excel.XlAutoFillType.xlFillYears);
rng = ThisApplication.get_Range("E1:E2", Type.Missing);
rng.AutoFill(ThisApplication.get_Range("E1:E5", Type.Missing), Excel.XlAutoFillType.xlFillSeries);
}

各ケースについて 2 つの範囲を指定する必要があります。

  • AutoFill メソッドを呼び出す範囲で、フィルの "開始点" を指定します。
  • フィルの範囲で、AutoFill メソッドにパラメータとして渡されます。パラメータを受け取る範囲はソースの範囲を含んでいる必要があります。

AutoFill メソッドの 2 番目のパラメータとなる XlAutoFillType 列挙体の値は任意です。通常、必要な動作を取得するためにはこの値を供給する必要があります。たとえば、以下のコードを変更してみます。

' Visual Basic
rng.AutoFill(ThisApplication.Range("D1:D5"), _
Excel.XlAutoFillType.xlFillYears)
// C#
rng.AutoFill(ThisApplication.get_Range("D1:D5", Type.Missing), Excel.XlAutoFillType.xlFillYears);

so that it looks like this:

' Visual Basic
rng.AutoFill(ThisApplication.Range("D1:D5"))
// C#
rng.AutoFill(ThisApplication.get_Range("D1:D5", Type.Missing), Excel.XlAutoFillType.xlFillDefault);

日付の値を年ごとに増加させる代わりに、毎日増加させるように変更されました。

範囲内での検索

Range クラスの Find メソッドを使うことにより、その範囲内のテキストの検索ができます。この柔軟性のあるメソッドは図 26 で示されている Excel の [検索と置換] ダイアログ ボックスと動作が類似しています。実際、このメソッドはこのダイアログ ボックスと直接、対話しています。つまり、Range.Find メソッドは検索方法を決定するために渡されたパラメータを使用しますが、パラメータが渡されない場合、[検索と置換] ダイアログ ボックス内のパラメータを使用します。表 4Range.Find メソッドで使用するパラメータのリストです。最初の 1 つ以外はすべて任意です。

図 26. このダイアログ ボックス内の選択が Find メソッドの動作に影響

注意    Range.Find のパラメータの大半は任意で、ユーザーが [検索と置換] ダイアログ ボックスの中の値を変更する可能性があるため、Find メソッドに実際にすべての値を確実に渡す必要があります。ただし、ユーザーの選択を考慮するのが目的である場合はこの限りではありません。C# 開発者はメソッド呼び出しごとにすべてのパラメータを供給する必要があるため、この問題を考慮する必要はありません。

表 4. Range.Find メソッドのパラメータ

パラメータタイプ説明
What (必須)Object検索するデータ。文字列もしくは Excel データ タイプ。
AfterRange検索を開始する範囲 (このセルは検索対象には含まれません)。このセルを指定しない場合は、検索は範囲内の左上から始まります。
LookInXlFindLookin (xlValue, xlComments, xlFormulas)検索される情報のタイプ。Or 演算子を使用して複数の値を組み合わせることはできません。
LookAtXlLookAt (xlWhole, xlPart)セル内容の検索の、完全一致または部分一致を指定します。
SearchOrderXlSearchOrder (xlByRows, xlByColumns)検索の順位を決定します。xlByRows (デフォルト値) は最初に左から右へ、次に上から下へ検索します。xlByColumns は最初に上から下へ、次に左から右へ検索します。
SearchDirectionXlSearchDirection (xlNext, xlPrevious)検索方向を決定します。デフォルト値は xlNext です。
MatchCaseBoolean検索で大文字と小文字を区別するかどうかを決定します。
MatchByteBoolean検索で全角文字を全角文字のみに一致させる (True) または、対応する半角文字とも一致させる (False) かを決定します。全角文字をサポートしている場合のみ適用されます。

サンプル ワークブックの以下の例では、("Fruits" という名前の) ある範囲を検索し、"apples" という言葉を含むセルのフォントを変更します (図 27 は検索結果を示しています)。このプロシージャでは、以前に設定された検索設定で再度検索する FindNext メソッドも使用されます (Range.FindPrevious メソッドの動作は Range.FindNext メソッドとほぼ同一ですが、この例では使用しません)。検索を始めるセルを指定すると、FindNext メソッドが残りの操作を処理します。

図 27. "apples" という言葉を含むセルの検索結果

ヒント    FindNext (および FindPrevious) メソッドによる検索では、範囲の最後まで検索されると範囲の最初に戻ります。コードを確認して、検索が永久に続くことがないようにしてください。サンプル プロシージャではこの問題に対処する方法が 1 つ示されています。この問題を完全に回避する、もしくは Find/FindNext/FindPrevious メソッドでは不可能な複雑な検索を実行するには、 For Each ループ を使用して範囲内のすべてのセルをループすることも可能です。

サンプル ワークブックの Range Class シートの Find リンクをクリックすると、以下のプロシージャが実行されます。

' Visual Basic
Private Sub DemoFind()
Dim rng As Excel.Range = ThisApplication.Range("Fruits")
Dim rngFound As Excel.Range
' 最初に検索した範囲を記録します。
Dim rngFoundFirst As Excel.Range
' このメソッドを呼び出すごとに、
' すべてのパラメータを指定する必要があります。
' これはユーザー インターフェイス上で値が上書きされるためです。
rngFound = rng.Find( _
"apples", , _
Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, _
Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, False)
While Not rngFound Is Nothing
If rngFoundFirst Is Nothing Then
rngFoundFirst = rngFound
ElseIf rngFound.Address = rngFoundFirst.Address Then
Exit While
End If
With rngFound.Font
.Color = ColorTranslator.ToOle(Color.Red)
.Bold = True
End With
rngFound = rng.FindNext(rngFound)
End While
End Sub
// C#
private void DemoFind()
{
Excel.Range rng = ThisApplication.
get_Range("Fruits", Type.Missing);
Excel.Range rngFound;
// 最初に検索した範囲を記録します。
Excel.Range rngFoundFirst = null;
// このメソッドを呼び出すごとに、
// すべてのパラメータを指定する必要があります。
// これはユーザー インターフェイス上で値が上書きされるためです。
rngFound = rng.Find("apples", Type.Missing, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false, Type.Missing, Type.Missing);
while (rngFound != null)
{
if (rngFoundFirst == null ) {
rngFoundFirst = rngFound;
}
else if (GetAddress(rngFound) == GetAddress(rngFoundFirst))
{
break;
}
rngFound.Font.Color = ColorTranslator.ToOle(Color.Red);
rngFound.Font.Bol



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值