黙々とC#

"In a mad world of VBA, only the mad are sane" 『VBAという名の狂った世界で狂っているというのなら私の気は確かだ』

switch

本記事は、Excel C# Script入門講座の1記事です。

switch case

複数の条件により処理を分岐させたい場合はswitchステートメントを使用します。

switchステートメントには、1つ以上のswitchセクションが含まれ、各switchセクションには、1つ以上のcaseラベルと、そのあとに続く1つ以上のステートメントのリストが含まれています。具体的には以下の様に書きます。

switch(変数)
{
  case1:
    // 変数の値 == 値1 のとき実行される処理
    break;
  case2:
    // 変数の値 == 値2 のとき実行される処理
    break;
  default:
    // 変数の値がどの値とも異なるとき実行される処理
    break;
}

"switch (変数)" で書かれた変数の値が "case 値:"の値と一致するかを評価し、caseの値と一致した場合にだけ、その次の文を実行します。条件がtrueでないときは、次の条件を調べます。どのcaseの条件にも当てはまらない場合は、"default:"以下の文を実行します。 複数のcaseラベルで同一の定数値を指定することはできません。

各case以下の文の最後にはbraek*1を記載します。

以下の例では、アクティブシートのA1セルに入力された文字により処理を分岐させています。

var a1 = Excel.ActiveWorkbook.ActiveSheet.Range("A1");
var v = a1.Value;

switch(v)
{
  case "りんご":
    a1.Value = "Apple";
    break;
  case "もも":
    a1.Value = "Peach";
    break;
  default:
    a1.Value = "Unknown";
    break;
}

case に指定できる値は、整数型(int)もしくは文字列型(string)のみです。

比較演算子による処理の分岐や、値の範囲指定による分岐はできません。これらの分岐を行いたい場合には、if ~ else if … を利用してください。

フォールスルー禁止の原則

C#では、switchステートメントは、最終セクションも含め、各 switch セクションの最終文ではswitchステートメントの外側、もしくは他のcaseラベルに移動することが必須要件とされています。つまり、他のいくつかの言語とは異なり、コードが1つのswitch セクション実行後に、連続して続くswitchセクションを実行する(フォール スルーする)ことはできません。

フォールスルー禁止の例外

以下のように、caseラベルが連続している場合に限りフォールスルーが可能です。

var a1 = Excel.ActiveWorkbook.ActiveSheet.Range("A1");
var v = a1.Value;

switch(v)
{
  case "Apple": 
  case "apple":
    a1.Value = "りんご";
    break;
  case "Peach":
  case "peach":
    a1.Value = "もも";
    break;
  default:
    a1.Value = "?";
    break;
}

*1:もしくは、goto, return, throwなどのジャンプステートメント

if ~ else

本記事は、Excel C# Script入門講座の1記事です。

if ~ else

条件により処理を分岐させたい場合は、if ~ else ステートメントを使用します。

ifは、"if (condition)" の形式で条件を調べて、 条件式がtrueである場合に続くステートメントを実行します。条件がtrue出ない場合には、else に続くステートメントを実行します。

bool condition; // true または falseが代入される

if (condition) 
{
    // condition がtrueの場合に実行される
}
else
{
    // condition がfalseの場合に実行される
}

条件によって、2つ以上に処理を分岐させたい場合には、 if ステートメントをelseブロック内に入れ子にすることができます。

bool condition1; // true または falseが代入される
bool condition2; // true または falseが代入される

if (condition1) 
{
    // condition1 がtrueの場合に実行される
}
else if (condition2)
{
    // condition1 がfalseで、 condition2 がtrueの場合に実行される
}
else
{
    // condition1 及びcondition2がfalseの場合に実行される
}

関係演算子と等値演算子

条件式でよく使われる演算子には、以下の関係演算子及び等値演算子があります。

概要
x < y xがyより小さい場合true
x > y xがyより大きい場合true
x <= y xがy以下の場合true
x >= y xがy以上の場合true
x == y xとyが等しい場合にtrue。string以外の参照型の場合、参照の等価性を調べます。
x != y xがyと等しくない場合true。==と同様。

型検査演算子

この他にも、型検査演算子があります。

概要
is 型の互換性を調べます。評価される左側のオペランドを右側のオペランドで指定された型にキャスト出来る場合、trueとなります。
as 型変換。左側のオペランドを右側のオペランドで指定された型にキャストして返します。変換可能でない場合、nullが返ってきます。

論理演算子

概要
x && y 論理AND。最初のオペランドがfalseの場合、2番目のオペランドは評価されません。
x | y |論理 OR。 最初のオペランドが true の場合、2番目のオペランドが評価されません。

単項演算子

概要
!x 論理否定

コレクション(配列・リスト)

本記事は、Excel C# Script入門講座の1記事です。

コレクション(配列・リスト)

配列

配列とは、一つの変数に対して複数の同じ型のデータを格納する場合に使用します。

配列は、以下のようにして宣言することが出来ます。

型名[] 変数名;

また、利用にあたっては、初期化が必要です。ここでは、配列の実体を生成する(サイズを決定する)必要があります。配列のサイズは以下のようにして決定します。

変数名 = new 型名[配列の長さ]

なお、C# Script(C#3.0以降)では、以下のように型名を省略して初期化することが可能です。

var a = new[]{0, 1, 2, 3};
var b = new[]{"C#", "VBA", "VB.NET"};

また、配列の型を明示して宣言する場合には、new[] を省略することも可能です。

int[] a = {0, 1, 2, 3};

なお、配列の各要素には、以下のようにしてアクセスすることができます。

変数名[要素番号]

要素番号は「0」から始まります。例えば「var a = new string[3];」と初期化すると、要素数は「0」から「2」の「3つ」となります。配列にデータを代入する場合は、「変数名[要素番号] = データ」で代入できます。

リスト

リストは、要素を順番に保持するコレクションクラスです。動的に要素の数を増減できるという特徴があり、動的配列のように扱うことができます。

リストは、型名を指定して宣言・初期化することができます。

var 変数名 = new List<型名>();

配列のように、要素番号を指定して各要素にアクセス可能です。

var list = List<string>(){"C#", "VBA", "VB.NET"};
list[1] = "F#"; //2つ目の要素に値を設定
list.Add("PowerShell"); //要素を追加

他にもコレクションを便利に扱うためのメソッドが用意されています。詳しくはMSDNを参照して下さい。

変数のスコープ

本記事は、Excel C# Script入門講座の1記事です。

変数のスコープ

C# スクリプトにおいてクラス、メソッドで囲むこと無く直接宣言された変数は、publicな変数となり、スクリプトのいかなる箇所からでも参照可能となります。なお、static変数を宣言した場合、スクリプトの実行インスタンスを使い回す限りにおいて、値が保持されます。

なお、メソッド内で宣言された変数は、そのメソッド内でのみ参照可能です。また、クラス内で宣言された変数は、そのクラス内でのみ参照可能です。

アクセス修飾子

本記事は、Excel C# Script入門講座の1記事です。

アクセス修飾子

C# Scriptでは、直接記載したメソッドやクラスのアクセス修飾子は、明示しなかった場合 publicとなります。

すなわち、#load で他のスクリプトファイル(*.csx)を読み込んだ際には、他のスクリプトファイルにおいてアクセス修飾子が明示されていないメソッドやクラスを参照することが可能です。

メソッド、クラスの宣言

本記事は、Excel C# Script入門講座の1記事です。

メソッド、クラスの宣言

C# Scriptでは、メソッドの定義を直接書き始めることが可能です。

test();

void test(){
    var a1 = Excel.ActiveWorkbook.ActiveSheet.Range("A1")
    a1.Value = "C# Script Test";
}

クラスの定義もどこにかいても大丈夫です。

var d = new D();
d.method();

class D
{
   public void method()
   {
        var a1 = Excel.ActiveWorkbook.ActiveSheet.Range("A1")
        a1.Value = "C# Script Test";
   }  
}

C# Script環境では、クラスなどで囲まずに直接記載したコードは、Roslyn内部でコード生成された際に、 いい感じにスクリプト全体を囲うクラスが作られ実行されます。

拡張メソッドの宣言

拡張メソッドはクラスを宣言せずに、直接スクリプト中で宣言します。

using System;
 
static void ShowInA1(this string msg)
{
    var a1 = Excel.ActiveWorkbook.ActiveSheet.Range("A1")
    a1.Value = msg;
}
 
"Hello World".ShowInA1();

上述の通り、Roslyn内部でコード生成された際に、 スクリプト全体を囲うクラスが作られるため、クラスを宣言してしまうと入れ子状にクラスが宣言されてしまい、コンパイルエラーが発生します。