第 6 回 VC# によるプラグイン開発
〜 Visual C# .NET による MSDNAA おもしろプログラミング 〜
6.1 はじめに
Visual C# .NET は、Microsoft 社の .NET 戦略上で重要な位置を占める言語であり、Web アプリケーション開発を始めとする様々なアプリケーション開発の現場でその高い開発効率とハイパフォーマンスを実現します。
プログラムを作成する場合、特定の手順や一連のキーストロークを繰り返し実行する場合が多々あります。Visual Studio .NET には、単調な処理を自動化する機能があります。処理を自動化することでヒューマンエラーによるプログラムミスなどの危険性も最小限に抑えることができるため、より堅牢なプログラミングを実装できます。また、開発効率も向上します。Visual Studio .NET には、頻繁に行う作業の一連の動作を短縮するための機能として、「マクロ」があります。マクロには、プログラムにアクセスするためのオブジェクトがあり、それらのオブジェクトを利用することにより、直接プログラムを触らずにマクロから変更できます。そこで、本章では、Visual Studio .NET に用意されているマクロについて解説します。また、本章の後半では、実際にマクロを作成し、マクロに対する理解をより深めます。
6.2 マクロ
Visual Studio .NET におけるマクロとは、ファイルに保存した後、実行できる命令のセットです。マクロ IDE により、単調な一連の動作を記録することで容易にマクロを作成できます。また、マクロは、Microsoft Word や Microsoft Excel 等でもよく利用されています。例えば、同様の文章やグラフを作成する場合にマクロを利用することで自動的に作成でき、文書作成に要する時間を大幅に削減することができます。
Visual Studio .NET では、作成したマクロは、マクロ エクスプローラやマクロ IDE による実行やショートカットキーによる実行ができます。マクロのイメージを図 1 に示します。

図 1 マクロのイメージ
6.2.1 マクロ IDE
IDE とは、Integrated Development Environment の略で、統合開発環境ツールのことで、Visual Studioマクロ IDE とは、Visual Studio .NET におけるマクロを開発するための統合開発環境ツールを指します。マクロ IDE では、Visual Basic を開発言語として利用します。
Visual Studioマクロ IDE は、Visual Studio .NET IDE と外観や操作性は同様です。しかし、Visual Studio .NET IDE とは、使用目的が全く異なります。マクロ IDE は、マクロを開発するために使用するもので、Visual Studio .NET IDE は、Visual Studio によるプロジェクトを開発するために使用します。マクロ IDE には、コードウィンドウなどのツールウィンドウがさまざま含まれています。これらのウィンドウは、Visual Studio .NET IDE に用意されているウィンドウと同様の機能を実装しています。しかし、これらの機能は、マクロ環境内のコードおよびプロジェクトにだけ適用され、Visual Studio .NET IDE で作成しているコードやプロジェクトには、全く影響しません。マクロ IDE の表示方法は、メニューの 【ツール】 → 【マクロ】 を選択し、【マクロ IDE】 をクリックします。マクロ IDE の表示方法を図 2 に示します。

図 2 マクロ IDE の表示方法
6.2.2 マクロ エクスプローラ
マクロ エクスプローラは、マクロの表示および実行がメインとなるツールで、利用できるすべてのマクロが一覧表示できます。最上位のノードにはマクロプロジェクトがあり、MyMacros という名前の既定のプロジェクトが含まれています。各マクロプロジェクトには、1 つ以上のモジュールが存在し、各モジュールには個別のマクロコマンドが含まれています。マクロ エクスプローラを表示するには、メニューの 【表示】 → 【その他のウィンドウ】 を選択し、【マクロ エクスプローラ】 をクリックします。マクロ エクスプローラの表示方法を図 3 に示します。

図 3 マクロ エクスプローラの表示方法
6.3 マクロの作成
本節では、マクロの一連の作成方法を解説します。マクロを利用するには、大きく 3 つの手順を踏みます。まずマクロの記録を行い、次に、マクロの変更、最後にマクロの実行を行います。
6.3.1 マクロの記録
マクロの記録は、マクロを新規に作成するための最も簡単で一般的な方法です。ユーザは、マクロを記録する代わりに、手入力で作成することもできます。マクロの記録は、その環境で実行した作業を単純に「記憶しておくこと」と考えられます。マクロを記録することは、テープに音楽を録音する動作と似ています。「録音」することにより、「停止」するまでの全ての音楽がテープに記録されます。マクロの記録も同様で、「マクロの記録」ボタンを押すことにより、「マクロの停止」ボタンを押すまで、ユーザが行った作業が、マクロコードとして記録されます。記録したマクロの実行については、第 6.3.2 項で解説します。
マクロの記録機能により、生成されたコードは、マクロ IDE で編集できます。作成したマクロが意図した処理を正確に実行しない場合、または機能を追加する必要がある場合は、記録した後でマクロを編集し、ソースコードをカスタマイズできます。マクロの編集については第 6.3.3 項で解説します。
簡単なマクロを作成するための手順を次に示します。まず、メニューの 【ツール】 → 【マクロ】 を選択し、【TemporaryMacroの記録】 をクリックして、その環境のマクロ記録モードを開始します。次に、マクロ記録モードを開始することで、【レコーダ】 ツールバーが表示されます。ユーザは、【レコーダ】 ツールバーを利用することにより、容易にマクロの記録や停止ができます。【レコーダ】 ツールバーを図 4 に示します。

図 4 【レコーダ】 ツールバー
マクロの記録では、マクロ記録モードを開始した時点から、【記録の終了】 ボタンが押されるまでのユーザによる操作を記録します。記録の終了を行うには、【レコーダ】 ツールバーの 【記録の終了】 をクリックして、マクロの記録を停止します。【レコーダ】 ツールバーは、マクロの記録を停止すると自動的に消えます。
上記の操作により、「TemporaryMacro」という名前の新しいマクロが作成できます。新しく記録したマクロには、既定の名前 (TemporaryMacro) が付けられます。記録したマクロは、マクロ エクスプローラを利用することにより確認できます。記録したマクロは、マクロ エクスプローラの MyMacros ノードの RecordingModule ノードの下に作成されます。作成されたマクロを図 5 に示します。

図 5 作成されたマクロ
6.3.2 マクロの実行
記録したマクロを実行するには、さまざま方法があります。本節では、マクロ エクスプローラによるマクロの実行方法とマクロ IDE によるマクロの実行方法を紹介します。
(1) マクロ エクスプローラによる実行
一般的にマクロを実行する場合は、マクロ エクスプローラから実行します。マクロを実行するには、【マクロ エクスプローラ】 → 【MyMacros】 ノードを開き、【RecordingModule】 ノードを開きます。上記の操作で表示された 【TemporaryMacro】 を選択し、ダブルクリックすることにより、指定したマクロが実行されます。マクロ エクスプローラによるマクロの実行を図 6 に示します。

図 6 マクロ エクスプローラによる実行方法
(2) マクロ IDE による実行
マクロは、マクロ IDE を利用することでも実行できます。この方法は、主にマクロをデバッグするときに利用します。マクロ IDE が表示されていない場合は、メニューの 【ツール】 → 【マクロ】 を選択し、【マクロ IDE】 をクリックして、マクロ IDE を表示します。
まず、マクロ IDE で TemporaryMacro をダブルクリックしてコードを表示します。次に、カーソルを TemporaryMacro 関数の中に置き、メニューから 【デバッグ】 → 【開始】 をクリックすることにより、指定したマクロが実行されます。マクロ IDE によるマクロの実行方法を図 7 に示します。

図 7 マクロ IDE による実行方法
6.3.3 マクロの変更
ユーザは、記録したマクロのコードを編集して機能の追加、変更や削除などが必要な場合があります。また、マクロを記録するのではなく独自のマクロを手入力で作成することもあります。これらの作業は、マクロ IDE を利用することで可能です。
ユーザは、マクロ IDE により、記録したマクロを編集することで、無駄なソースコードを記述する手間を省き、最小限の労力でマクロを作成できます。
記録したマクロを編集するには、マクロ エクスプローラ内の作成したマクロを右クリックし、【編集】 を選択します。この操作により、マクロ IDE が表示され、記録したマクロの自動生成されたコードが表示されます。現在のカーソルの右側の 1 単語削除するコードを次に示します。
Sub TemporaryMacro()
DTE.ActiveDocument.Selection.WordRight(True)
DTE.ActiveDocument.Selection.Delete()
End Sub
上記のソースコードは、マクロの記録により、右側の 1 語が削除されるマクロを作成したものです。このマクロを右側の 1 単語だけではなく、2 語が削除されるように変更します。2 語が削除されるように変更するには、コードの 1 行目の最後に新しい引数を追加するだけです。変更部分のソースコードを次に示します。
Sub TemporaryMacro()
DTE.ActiveDocument.Selection.WordRight(True, 2)
DTE.ActiveDocument.Selection.Delete()
End Sub
このようにマクロ記録し、自動生成されたソースコードを利用することにより、容易にマクロの変更や追加、削除ができます。また、ユーザは、記録したマクロを少し変更するだけで自分のニーズにあったマクロを作成することができます。
6.4 Visual Studio .NET オートメーション技術
6.4.1 Visual Studio .NET オートメーションとは
前述のとおり、Visual Studio .NET には、定型的な作業を簡易化するためにマクロ機能が用意されています。また、マクロから Visual Studio .NET の開発環境を操作することが可能です。Visual Studio .NET の開発環境をマクロから操作するために用意されているオブジェクトの集まりをオートメーションと呼びます。オートメーションには、プロジェクトを操作するためのオブジェクトやクラスを操作するためのオブジェクトなどが用意されており、これらのオブジェクトを利用することにより、「クラスを参照・追加・削除する」「メソッドのパラメータを参照・追加・削除する」などの操作をマクロから容易にできます。オートメーションとマクロの関係を図 8 に示します。

図 8 Visual Studio .NET オートメーションとマクロ
Visual Studio .NET のオートメーション機能を利用することにより、ソースコードのクラスやメソッドの情報を取得することや編集することができるようになります。そのため、いくつかのベンダーが、本技術を利用して「ソースコードの自動生成システム」や「仕様書の自動生成システム」を開発しています。
6.4.2 Visual Studio .NET オートメーションを構成するオブジェクト
Visual Studio .NET オートメーションは、非常に多くのオブジェクトで構成されています。代表的なものでは、開発環境へのアクセスの最上位である「DTE オブジェクト」、変数やメソッドなどクラスを構成する要素への操作を行うための「CodeElement」などが挙げられます。Visual Studio .NET オートメーションの主なクラスの一覧を表1に示します。
表 1 主なオブジェクトの一覧
| クラス名 | 説明 |
| DTE | Development Tools Extensibility の略。
Visual Studio .NET の開発環境にアクセスするためのオートメーションの最上位オブジェクト |
| Document | 開発画面で、開発用に開いているソースコードドキュメント |
| CodeElement | クラスを構成する要素.変数・メソッド・プロパティなど |
| CodeVariable | クラスを構成する変数要素 |
| CodeFunction | クラスを構成するメソッド要素 |
| TextDocument | Visual Studio IDE などのエディタで開いているテキストファイル |
| FileCodeModel | ソースコードを階層構造状のオブジェクトとして提供 |
表 1 に示すオブジェクトを操作することにより、Visual Studio .NET をマクロから操作することができます。例えば、Visual Studio .NET IDE を全く操作せずにクラスを定義したり、マクロからソースコードの内容を取得し、変更したりできます。各オブジェクトと開発環境画面との関係を図 9 に示します。

図 9 オブジェクトと開発環境画面の対応
6.5 コメント自動生成プログラム
6.5.1 サンプルプログラムの概要
本節では、Visual Studio .NET オートメーション技術したサンプルプログラムを作成します。サンプルプログラムは、選択したメソッドに対して自動的にコメント文を付けるマクロです。作成するコメント文は、メソッド名や戻り値の型名、引数の情報等を自動的に記述します。マクロを作成し、自動化することで、無駄な手間が省けるだけでなく、全てのコメント文を統一できます。コメント文を統一することにより、チーム開発する場合、他人との意思疎通が容易になります。また、どのクラスにどのようなメソッドが実装されているかが一目でわかるため、開発効率が大幅に向上します。サンプルプログラムの実行結果を図 10 に示します。

図 10 プログラムの実行結果
6.5.2 モジュールの追加
本章のサンプルプログラムは、マクロ IDE を利用して作成します。まず、マクロを作成するには、マクロモジュールを追加する必要があります。マクロモジュールを追加するには、マクロ IDE のメニューから 【ファイル】 → 【新しい項目の追加】 を選択し、【新しい項目の追加】 ダイアログを表示します。【新しい項目の追加】 ダイアログでテンプレートでは、【モジュール】 を選択し、ファイル名を入力して 【開く】 ボタンをクリックします。マクロモジュールの追加方法を図 11 に示します。

図 11 モジュールの追加方法
6.5.3 ソースコードの追加
Module1 に追加するソースコードを次に示します。
Imports EnvDTE
Imports System.Diagnostics
Imports Microsoft.VisualBasic
Imports Microsoft.VisualBasic.ControlChars
Public Module Module1
'定数を宣言
Private Const METHOD = "// メソッド名 : "
Private Const CONTENTS = "// 内容 : このメソッドに関する説明"
Private Const PARAM = "// 引数 : "
Private Const FUNCTIONKIND = "// 戻り値 : "
Private Const PARAMINFO = " : 引数の説明"
Sub AddDescription()
'各種オブジェクト用変数の宣言
Dim objTextDocument As TextDocument ' テキスト情報取得用オブジェクト
Dim objFileCodeModel As FileCodeModel ' コードモデル情報取得オブジェクト
Dim objCodeElement As CodeElement ' コード情報取得用オブジェクト
Dim objCodeFunction As CodeFunction ' メソッド情報取得用オブジェクト
Dim objCodeTypeRef As CodeTypeRef ' 戻り値情報取得用オブジェクト
Dim objParamater As CodeParameter ' 引数情報取得用オブジェクト
Dim strFuncKind, strFuncName As String ' メソッド情報格納用変数
Dim tempparamName, strParamName, strParamKind,
strParamMaster As String ' 引数に関する情報格納用変数
Dim paramCount As Integer ' 引数の個数
Dim i As Integer ' ループ回数
Try
'各種オブジェクトの取得
objTextDocument = CType(DTE.ActiveDocument.Object("TextDocument"),
TextDocument) ' アクティブなテキスト情報の取得
objFileCodeModel =
DTE.ActiveDocument.ProjectItem.FileCodeModel ' コードモデル情報の取得
objCodeElement =
objFileCodeModel.CodeElementFromPoint(objTextDocument.Selection.ActivePoint,
vsCMElement.vsCMElementVariable) ' ソースコード情報の取得
objCodeFunction = CType(objCodeElement, CodeFunction) ' メソッド情報の取得
'メソッドの情報取得
paramCount = objCodeFunction.Parameters.Count ' 引数の個数を取得
strFuncName = objCodeFunction.Name ' メソッド名の取得
objCodeTypeRef = objCodeFunction.Type 'メソッドの型を取得
strFuncKind = objCodeTypeRef.AsString 'メソッドの型を文字列に変換
'引数の情報取得
For i = 1 To paramCount
strParamName = objCodeFunction.Parameters.Item(i).Name ' 引数名を取得
objParamater = objCodeFunction.Parameters.Item(i) ' 型を取得する引数の指定
strParamKind = objParamater.Type.AsString ' 引数の型を取得
strParamMaster = strParamMaster + PARAM + strParamName
+ " " + strParamKind + PARAMINFO + CStr(Lf) ' 引数名と引数の型の結合
Next
' メソッドの詳細をソースコードに追加
putDiscription(strFuncKind, strFuncName, strParamMaster)
Catch e As System.Exception
MsgBox("failed")
End Try
End Sub
Sub putDiscription(ByVal strFuncKind As String,
ByVal strFuncName As String, ByVal strParamName As String)
Dim objSelection As TextSelection '選択中のテキスト情報取得用オブジェクト
Dim strDescription As String 'コメント文格納用変数
' メソッドの詳細の追加場所を設定
DTE.ActiveDocument.Selection.LineUp()
DTE.ActiveDocument.Selection.LineDown()
DTE.ActiveDocument.Selection.StartOfLine()
objSelection = DTE.ActiveDocument.Selection()
'コメント文の生成
strDescription = CStr(Lf) + METHOD + strFuncName + CStr(Lf) ' メソッド名の設定
strDescription = strDescription + FUNCTIONKIND + strFuncKind + CStr(Lf) ' 戻り値の設定
strDescription = strDescription + strParamName ' 引数の設定
strDescription = strDescription + CONTENTS + CStr(Lf) ' 内容の設定
'コメント文挿入の実行
objSelection = DTE.ActiveDocument.Selection()
objSelection.Text = strDescription 'メソッドのコメントを追加
End Sub
End Module
6.5.4 ソースコードの解説
本プログラムでは、まず、DTE オブジェクトを利用し、マクロから Visual C# のプロジェクトにアクセスします。次に、選択した部分のメソッドに関するコメントを作成するには、選択された部分のソースコードを取得する必要があります。選択された部分のソースコードを取得するための構文を次に示します。
| TextDocument オブジェクト.Selection.ActivePoint |
次に、コメントのメソッド名、引数名や戻り値の型名などを取得します。これらを取得するには、CodeFunction、CodeTypeRef、CodeParameter などのオブジェクトを生成し、各情報を取得します。CodeFunction オブジェクトは、メソッドの情報を取得するために使用されます。メソッド名を取得するための構文を次に示します。
また、戻り値の型を取得するには、CodeFunction オブジェクトの Type プロパティにより、CodeTypeRef オブジェクトを生成します。生成した CodeTypeRef オブジェクトの AsString プロパティを利用することにより、戻り値の型を取得できます。戻り値の型を取得するための構文を次に示します。
CodeTypeRef オブジェクト = CodeFunction オブジェクト.Type
CodeTypeRef オブジェクト.AsString |
引数の情報を取得するには、CodeFunction オブジェクトに用意されている Parameters プロパティを利用します。Parameters プロパティを利用することにより、各引数情報を容易に取得できます。引数情報を取得するための構文を次に示します。
CodeFunction オブジェクト.Parameters.Item(i).Name
Paramater オブジェクト = CodeFunction オブジェクト.Parameters.Item(i)
Paramater オブジェクト.Type.AsString |
最後に、取得した引数名や返り値の型名からコメント文を生成し、Visual C# のソースコードに追加します。生成したコメントを Visual C# のソースコードに追加するには、まず、生成したコメントをどこに追加するかを指定します。次に、 TextSelection オブジェクトを利用し、文字列を追加します。文字列を追加するための構文を次に示します。
DTE.ActiveDocument.Selection.LineUp()
DTE.ActiveDocument.Selection.LineDown()
DTE.ActiveDocument.Selection.StartOfLine()
TextSelection オブジェクト = DTE.ActiveDocument.Selection()
TextSelection オブジェクト.Text = 追加する文字列 |
6.5.5 実行結果
本節で作成したプログラムの使用方法は、まず、コメント文を追加するメソッドを選択します。メソッドを選択した状態で、マクロ エクスプローラから作成したマクロを選択し、ダブルクリックします。この操作により、自動的にメソッド名、引数、戻り値などの情報を取得し、コメント文が追加されます。本節で作成したマクロの実行結果を図 12 に示します。

図 12 実行結果
6.6 おわりに
本章では、前章までのコラムと少し趣向を変え、プログラミングの開発効率を向上させるためのテクニックの一つとして、Visual Studio .NET に用意されているマクロ機能を紹介しました。マクロを利用することにより、特定の手順や一連のキーストロークの繰り返しなどが必要なくなり、単調な作業を自動化できます。そのため、無駄な作業に時間をかけることや入力ミスによるヒューマンエラーなどの問題点を最小限に抑えることができ、開発効率を大幅に向上させることができます。また、Visual Studio .NET のオートメーション技術は、システム開発の場面において非常に役立ちます。例えば、本章で作成したサンプルプログラムのようにコメントの自動化することにより、チーム開発する場合、全てのコメントが統一されるため、可読性が向上し、他人との意思疎通が容易になります。また、ドキュメントの自動作成なども簡単にできます。
今回でおもしろプログラミング全 6 回の連載が終了となります。本連載を通してプログラミングのおもしろさが読者の皆さまに伝われば幸いです。
Visual C# .NET による MSDNAA おもしろプログラミング
本コラムでは、MSDN や MSDNAA の中で公開されているリソースの中でも、プログラミングの楽しさを追及できるものを集めて紹介し、新しいオブジェクト指向言語 「Visual C#. NET」 での利用法を解説していきます。
著者略歴
田中 成典 (たなか しげのり)
| 1986 年 | 関西大学工学部土木工学科卒業 |
| 1988 年 | 関西大学大学院工学研究科 土木工学専攻博士課程前期課程修了 |
| 1996 年 | 博士 (工学) 授与,関西大学 |
| 1997 年 | 関西大学総合情報学部助教授 (現在に至る) |
| 主な著書: | やさしい C のはじめかた,オーム社,1993 年 |
| | 建設技術者のための知識情報処理の実践,関西大学出版部,1999 年 |
| | DirectX8,工学社,2001 年 |
| | ステップアップ XML,工学社,2002 年 |
| | Linux アプリケーション入門,森北出版,2002年 ほか |
中山 浩太郎 (なかやま こうたろう)
| 2001 年 3 月 | 関西大学総合情報学部総合情報学科卒業 |
| 2003 年 3 月 | 関西大学大学院総合情報学研究科 博士課程前期課程修了 |
| 2003 年 4 月 | 関西大学大学院総合情報学研究科 博士課程後期課程入学 (現在に至る) |
| 主な著書: | Web 工房シリーズ Perl の達人,森北出版,1999 年 |
| | 決定版 Visual Basic,共立出版,2000年 |
| | DirectX8,工学社,2001 年 |
| | Linux アプリケーション入門,森北出版,2002 年 |
| | ステップアップ Visual C# .NET 入門,工学社,2002 年 ほか |
中村 健二 (なかむら けんじ)
| 2000 年 4 月 | 関西大学総合情報学部総合情報学科入学 (現在に至る) |
| 主な著書: | DirectX8 & VC++ 3D の基礎とゲームの作り方,工学社,2002年 |
北川 悦司 (きたがわ えつじ)
| 2000 年 3 月 | 関西大学総合情報学部総合情報学科卒業 |
| 2002 年 3 月 | 関西大学大学院総合情報学研究科 博士課程前期課程修了 |
| 2002 年 4 月 | 関西大学大学院総合情報学研究科 博士課程後期課程入学 (現在に至る) |
| 主な著書: | Web 工房シリーズ Java の達人,森北出版,1999 年 |
| | デジカメ活用によるデジタル写真測量入門,森北出版,2000 年 |
| | ステップアップ XML 活用法,工学社,2002 年 |
上山 智士 (うえやま さとし)
| 2002 年 4 月 | 関西大学総合情報学部総合情報学科入学 (現在に至る) |
杉町 敏之 (すぎまち としゆき)
| 2003 年 3 月 | 関西大学総合情報学部総合情報学科卒業 |
| 2003 年 4 月 | 関西大学大学院総合情報学研究科入学 (現在に至る) |
| 主な著書: | ステップアップ Visual C# .NET 入門,工学社,2002 年 |
野中 一希 (のなか かずき)
| 2003 年 3 月 | 関西大学総合情報学部総合情報学科卒業 |
| 2003 年 4 月 | 関西大学大学院総合情報学研究科入学 (現在に至る) |
| 主な著書: | ステップアップ Visual C# .NET 入門,工学社,2002 年 |
|