So-net無料ブログ作成
Programming .NET Tips ブログトップ

[.NET]JSON.NET(.NET4以降)その1 [Programming .NET Tips]

[はじめに]
.NETJSONデータを扱う機会があったので、予習がてらに作ってみました。
 JSONの解析には、逆シリアライズを使用します。
 .NET3.5以降であれば、.NET標準のクラスライブラリでも実装できますが、
 逆シリアライズの結果を格納するクラスを、別途定義する必要があるので、
 もっとシンプルにできないか調べてみました。
 フリーのライブラリで『JSON.NET』を使うと、よりシンプルに実装できそうなので、
 サンプルを作ってみました。(.NET4で作成します。)
[JSON.NETについて]
・ダウンロード元
 下記サイトからダウンロードできます。
 http://json.codeplex.com/
・対象フレームワーク
 ・.NET 2.0
 ・.NET 3.5
 ・.NET 4
 ・Silverlight
 ・Windows Phone and Windows 8
・オープンソース
 ソースが公開されているので、
 ソリューションにプロジェクトに追加して、そのままビルドできます。
 プロジェクトファイルが、.NETのバージョン毎に用意されているので、
 対応するプロジェクトを追加します。
・言語
 C#で記述していますが、
 ライブラリの呼出しは、.NET言語であれば、C#以外でも可能です。

[ソース]
コードのコピー
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace SerialSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //前提条件
            //※参照設定に『Newtonsoft.Json.NET40』を追加

            //JSON文字列を作成
            var sb = new StringBuilder();
            sb.Append(@"{");
            sb.Append(@"  ""キー1"":""値1"",");
            sb.Append(@"  ""キー2"":""値2"",");
            sb.Append(@"  ""キー3"":");
            sb.Append(@"    {");
            sb.Append(@"      ""キー3_1"":""値3_1"",");
            sb.Append(@"      ""キー3_2"":""値3_2""");
            sb.Append(@"    },");
            sb.Append(@"  ""キー4"":");
            sb.Append(@"    [");
            sb.Append(@"      {");
            sb.Append(@"        ""キー4_1"":""値4_0_1"",");
            sb.Append(@"        ""キー4_2"":""値4_0_2""");
            sb.Append(@"      },");
            sb.Append(@"      {");
            sb.Append(@"        ""キー4_1"":""値4_1_1"",");
            sb.Append(@"        ""キー4_2"":""値4_1_2""");
            sb.Append(@"      }");
            sb.Append(@"    ],");
            sb.Append(@"  ""キー5"":");
            sb.Append(@"    [");
            sb.Append(@"      ""値5_0_1"",");
            sb.Append(@"      ""値5_0_2"",");
            sb.Append(@"      ""値5_0_3""");
            sb.Append(@"    ]");
            sb.Append(@"}");

            //JSON文字列を逆シリアル化
            var jobj = JsonConvert.DeserializeObject<JContainer>(sb.ToString());

            //結果を表示
            Console.WriteLine("キー1:{0}", jobj["キー1"].ToString());
            Console.WriteLine("キー2:{0}", jobj["キー2"].ToString());
            Console.WriteLine("キー3.キー3_1:{0}", jobj["キー3"]["キー3_1"].ToString());
            Console.WriteLine("キー3.キー3_2:{0}", jobj["キー3"]["キー3_2"].ToString());

            for (int i = 0; i < jobj["キー4"].Count(); i++) 
            {
                Console.WriteLine(
                    "キー4.[{0}].キー4_X_1:{1}",
                    i.ToString(),
                    jobj["キー4"][i]["キー4_1"].ToString());
                Console.WriteLine(
                    "キー4.[{0}].キー4_X_2:{1}",
                    i.ToString(),
                    jobj["キー4"][i]["キー4_2"].ToString());
            }

            for (int i = 0; i < jobj["キー5"].Count(); i++)
            {
                Console.WriteLine(
                    "キー5.[{0}]:{1}",
                    i.ToString(),
                    jobj["キー5"][i].ToString());
            }

            Console.ReadLine();

            //出力結果
            // キー1:値1
            // キー2:値2
            // キー3.キー3_1:値3_1
            // キー3.キー3_2:値3_2
            // キー4.[0].キー4_X_1:値4_0_1
            // キー4.[0].キー4_X_2:値4_0_2
            // キー4.[1].キー4_X_1:値4_1_1
            // キー4.[1].キー4_X_2:値4_1_2
            // キー5.[0]:値5_0_1
            // キー5.[1]:値5_0_2
            // キー5.[2]:値5_0_3
        }
    }
}
[C#]JSON.NET

タグ:.net JSON JSON.NET

[.NET]C#、VB.NET相互変換 [Programming .NET Tips]

ネットを徘徊していたら、こんなのを見つけました。
[Convert C# to VB.NET]、[Convert VB.NET to C#]
C#、VB.NETの相互変換のサイト

配列の宣言の添え字も正しく変換できるかなと思い、
試しに配列のコードを入力すると、
正しく変換してくれました。

[VB.NET]
Dim a() As Integer = New Integer(5){}
    ↓
[C#]
int[] a = new int[6];

精度はよいと思います。

しかし、やはり言語特有の文法は無理のようで、
C#のyieldや、VB.NETのHandles等はエラーになりました。

Handlesがエラーになると、
画面系が変換できなくなるので、
融通を利かせて欲しいなぁ。。。

[.NET]VisualStudio2005でデバッグできない。(ASP.NET、IE8) [Programming .NET Tips]

下記環境で、ASP.NETの開発を行うと、
デバッグが行えないらしい。

・開発ツール:『Visual Studio 2005』(以下VS2005)
・ブラウザ:『Internet Explorer 8』(以下IE8)

よくよく調べてみるとこんな情報が。。。(英語ですが)

『Tip #51 Did you know… how to use VS2005 to debug with IE8?』

最近はVS2005を使う人は少ないかもしれませんが、
もしいたらはまってしまうと思うので、
メモを残しておきます。
(…というよりも私がはまったので(笑))

 ↓
【手順】
 1.RegEditを開きます。
 2.HKEY_LOCALMACHINE ->
  SOFTWARE ->
  Microsoft ->
  Internet Explorer ->
  Mainを表示します。
 3.「TabProcGrowth」キーを追加します。(DWORD値)
 4.値を0にします。

[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page1] [Programming .NET Tips]

[はじめに]
 ・プログラムソース(C#、VB.NET)をHTMLに変換するツールを
  作ってみましたので、ご紹介します。
  (全てのソースは膨大なので、変換処理のみ)
  このブログに貼り付けているプログラムソースもこのツールで変換したものです。
[機能]
  プログラムソースの文字列を、HTMLに変換する。
  変換後のHTMLは、<table>タグで整形した形になります。
[変換後HTML]
 ・インデントのスペースが「& nbsp;」に変換され、ブラウザ上でも表示される。
  (インデントが無視されない)
 ・予約語、コメント、文字列(ダブルコーテーションで囲んだ部分)に色がつく。
 ・ソースコードをクリップボードにコピーする機能を提供。(「コードのコピー」リンクを付加)
  但し、IEのJScriptであるclipboardData.setDataメソッドを使用している為、IE限定です。
[制限事項]
 ・言語は、C#とVB.NETのみです。
  但し、VB6やVBA等はVB.NETと言語仕様が似ている為、
  制限事項を考慮の上、利用することもできます。
 ・C#のコメントは、行の先頭の「//」のみサポート。
  行の途中の「//」や「/*」~「*/」はサポートしません。
 ・VB.NETのコメントは、行の先頭の「'」のみサポート。
  行の途中の「'」はサポートしません。
[使い方]
 (1)ビルド前に、「System.Web」を参照設定に追加する。
   追加しないとコンパイルエラーになります。
 (2)CodeConverterToHtml クラスのGetInstanceメソッドで、
   変換オブジェクトを取得します。
   言語の種類(C#かVB.NET)は、GetInstanceメソッドの第1引数で指定します。 
 (3)CodeConverterToHtml クラスのConvertCodeToHtmlメソッドで、
   ソースをHTMLに変換します。
   ConvertCodeToHtmlメソッドの仕様
   ・第1引数:プログラムソースの文字列
   ・第2引数:整形後HTMLのタイトル。(省略可能)
   ・戻り値:変換後のHTMLの文字列
        変換後の文字列(HTML)は、
        <table>タグで整形した形となります。
        (<html>タグでは囲みません。)
コードのコピー
'変換クラスを取得する。
Dim conv As CodeConverterToHtml = _
        CodeConverterToHtml.GetInstance( _
            CodeConverterToHtml.ProgLangType.VBNet _
        )

'プログラムソース
Dim strPgSource As String = "・…(プログラムソース)…"

'変換処理(変換結果はブログ等に貼り付けて、利用できます。)
Dim strConv As String = _
    conv.ConvertCodeToHtml(strPgSource, "[VB.NET]変換機能の使用例")
[VB.NET]変換機能の使用例

[改造ポイント]
 ・拡張性
  言語(C#、VB.NET)の固有ロジックを、
  CodeConverterToHtml の派生クラスに定義しています。
  (VBCodeConverterToHtml、CSharpCodeConverterToHtml)
  予約語一覧、キーワードの前景色、背景色、検索条件(正規表現)、変換仕様は、
  派生クラスの修正で変更できます。
  また、言語を追加する場合も、既存の派生クラスの流用が簡単です。
 ・予約語一覧
  予約語一覧は各派生クラスに定義しています。
  予約語の追加、変更、削除が簡単です。
 ・キーワードの検索条件
  正規表現を各派生クラスに定義しています。
  正規表現を修正することで、キーワードの検索条件を変更できます。
 ・キーワードの変換仕様
  正規表現の検索結果毎に、
  MatchEvaluator()メソッドが呼ばれます。
  MatchEvaluator()メソッドの修正で変換仕様を変更できます。
 ・マルチスレッド対応
  スレッドセーフではありません。
  派生クラスのGetRegEx() とGetReservedWords()に、
  複数スレッドが同時アクセスした場合、
  m_RegEx変数、m_ReservedWords変数の値に
  矛盾が生じる可能性があります。
  ASP.NET等のマルチスレッド環境で安全に使用する為には、
  SyncLockで排他をかける必要があります。

[プログラムソース]
ブログの容量制限の為、下記に分けて記述しています。
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page1]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page2]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page3]
コードのコピー
Imports System.Text.RegularExpressions

''' <summary>
''' 変換(ソースコード→HTML)
''' </summary>
''' <remarks></remarks>
Public MustInherit Class CodeConverterToHtml

#Region "定数定義"
    ''' <summary>
    ''' HTMLレイアウト
    ''' </summary>
    ''' <remarks></remarks>
    Private Const TABLE_STRING As String = _
        "<table width=""100%"" border=""0"" " & _
        " bgcolor=""@@@TITLEBGCOLOR@@@"" " & _
        " cellspacing=""0"">" & _
        " <tr><td>" & _
        "  <span " & _
        "   onmouseover=""this.style.color='green';""" & _
        "   onmouseout=""this.style.color='black';"" " & _
        "   onClick=""window.clipboardData.setData('Text', " & _
        "   this.parentNode.parentNode.parentNode.getElementsByTagName('tr')[1].innerText);"">" & _
        "   <u>コードのコピー</u>" & _
        "  </span>" & _
        " </td></tr>" & _
        " <tr><td>" & _
        " <table width=""100%"" border=""0"" " & _
        "  cellpadding=""10"" " & _
        "  bgcolor=""@@@BGCOLOR@@@"" " & _
        "  cellspacing=""0"">" & _
        "  <tr><td>" & _
        "   <font color=""@@@FORECOLOR@@@"" " & _
        "    style=""font-size: 9pt"">" & _
        "    <code>@@@CODE@@@</code>" & _
        "   </font>" & _
        "  </td></tr>" & _
        " </table>" & _
        " </td></tr>" & _
        " <tr><td>" & _
        " <b><font size=""2"">@@@TITLE@@@</font></b>" & _
        " </td></tr>" & _
        "</table>"
#End Region

#Region "列挙定義"
    ''' <summary>
    ''' 言語の種類
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum ProgLangType
        ''' <summary>
        ''' VB.NET
        ''' </summary>
        ''' <remarks></remarks>
        VBNet = 0
        ''' <summary>
        ''' C#.NET
        ''' </summary>
        ''' <remarks></remarks>
        CSharp = 1
        ''' <summary>
        ''' SQLServer
        ''' </summary>
        ''' <remarks></remarks>
        SQLServer = 2
    End Enum

#End Region

#Region "変数定義"
    ''' <summary>
    ''' インスタンス
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared instanceList() As CodeConverterToHtml = _
        New CodeConverterToHtml() { _
            New VbCodeConverterToHtml(), _
            New CSharpCodeConverterToHtml(), _
            New SqlServerCodeConverterToHtml() _
        }

#End Region

#Region "コンストラクタ"
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub New()

    End Sub

#End Region

#Region "インスタンスを取得"
    ''' <summary>
    ''' インスタンスを取得
    ''' </summary>
    ''' <param name="type">言語の種類</param>
    ''' <returns>インスタンス</returns>
    ''' <remarks></remarks>
    Public Shared Function GetInstance( _
        ByVal type As ProgLangType) As CodeConverterToHtml

        Return instanceList(type)
    End Function
#End Region

#Region "ソースコードをHTMLに変換する。"
    ''' <summary>
    ''' ソースコードをHTMLに変換する。
    ''' </summary>
    ''' <param name="src">ソースコード</param>
    ''' <returns>HTML</returns>
    ''' <remarks></remarks>
    Public Function ConvertCodeToHtml(ByVal src As StringAs String
        Return Me.ConvertCodeToHtml(src, Me.GetDefaultTitle())
    End Function

    ''' <summary>
    ''' ソースコードをHTMLに変換する。
    ''' </summary>
    ''' <param name="src">ソースコード</param>
    ''' <param name="title">タイトル</param>
    ''' <returns>HTML</returns>
    ''' <remarks></remarks>
    Public Function ConvertCodeToHtml( _
        ByVal src As StringByVal title As StringAs String

        Dim wkSrcList() As String = Nothing

        'ソースコードを行単位に分割する。
        '(vbCrLf, vbLf, vbCr毎)
        wkSrcList = src.Split( _
            New String() {vbCrLf, vbLf, vbCr}, _
            StringSplitOptions.None)

        '先頭の空白文字数を取得
        Dim cntIndent As Integer = _
            Me.GetHeadSpaceCount(wkSrcList)

        '先頭の空白文字を削除
        Me.RemoveStringList(wkSrcList, cntIndent)

        'HTMLエンコード
        Me.HtmlEncode(wkSrcList)

        Dim regEx As Regex = Me.GetRegEx()
        Dim regMatchEvaluator As _
            New MatchEvaluator(AddressOf Me.MatchEvaluator)

        'キーワードにタグを付加
        For i As Integer = 0 To wkSrcList.Length - 1
            wkSrcList(i) = wkSrcList(i).Replace( _
                    " ""&nbsp;")
            wkSrcList(i) = regEx.Replace( _
                    wkSrcList(i), regMatchEvaluator)
        Next

        Dim wkStr As String

        wkStr = String.Join(vbCrLf, wkSrcList)
        wkStr = wkStr.Replace(vbCrLf, "<br/>" & vbCrLf)

        Dim wkStrTable As String = Nothing

        wkStrTable = TABLE_STRING.Replace( _
            "@@@TITLE@@@", title)
        wkStrTable = wkStrTable.Replace( _
            "@@@BGCOLOR@@@"Me.GetBackColor())
        wkStrTable = wkStrTable.Replace( _
            "@@@FORECOLOR@@@"Me.GetForeColor())
        wkStrTable = wkStrTable.Replace( _
            "@@@TITLEBGCOLOR@@@"Me.GetTitleBackColor())
        wkStr = wkStrTable.Replace("@@@CODE@@@", wkStr)


        Return wkStr
    End Function

#Region "ヘルパーメソッド"
    ''' <summary>
    ''' HTMLにエンコードする
    ''' </summary>
    ''' <param name="srcLineList">ソース</param>
    ''' <returns>ソース(HTMLエンコード済)</returns>
    ''' <remarks></remarks>
    Private Function HtmlEncode(ByVal srcLineList() As StringAs String()

        For i As Integer = 0 To srcLineList.Length - 1
            srcLineList(i) = System.Web.HttpUtility.HtmlEncode(srcLineList(i))
        Next

        Return srcLineList

    End Function

    ''' <summary>
    ''' インデントの桁数を取得。
    ''' </summary>
    ''' <param name="srcLineList">ソース</param>
    ''' <returns>インデントの桁数</returns>
    ''' <remarks></remarks>
    Private Function GetHeadSpaceCount( _
        ByVal srcLineList() As StringAs Integer

        Const CHR_BLANK As Char = " "c
        Return Me.GetHeadSpaceCount(srcLineList, CHR_BLANK)
    End Function

    ''' <summary>
    ''' インデントの桁数を取得。
    ''' </summary>
    ''' <param name="srcLineList">ソース</param>
    ''' <param name="indentChar">インデントの文字</param>
    ''' <returns>インデントの桁数</returns>
    ''' <remarks></remarks>
    Private Function GetHeadSpaceCount( _
        ByVal srcLineList() As String, _
        ByVal indentChar As CharAs Integer

        Dim cntIndent As Integer = Int32.MaxValue

        If srcLineList.Length = 0 Then
            Return 0
        End If

        For Each wkSrc As String In srcLineList

            For i As Integer = 0 To wkSrc.Length - 1

                If wkSrc.Trim() = "" Then
                    Exit For
                End If

                If i >= cntIndent Then
                    Exit For
                End If

                If wkSrc(i) = indentChar.ToString() Then

                Else
                    cntIndent = Math.Min(i, cntIndent)
                    Exit For
                End If
            Next
        Next

        If cntIndent = Int32.MaxValue Then
            Return 0
        End If

        Return cntIndent

    End Function

    ''' <summary>
    ''' 各行からインデントを除去する。
    ''' </summary>
    ''' <param name="srcLineList">ソース</param>
    ''' <param name="cnt">インデントの桁数</param>
    ''' <returns>処理結果</returns>
    ''' <remarks></remarks>
    Private Function RemoveStringList( _
        ByVal srcLineList() As String, _
        ByVal cnt As IntegerAs Boolean

        If cnt = 0 Then
            Return True
        End If

        For i As Integer = 0 To srcLineList.Length - 1
            If srcLineList(i).Trim() = "" Then
                Continue For
            End If
            srcLineList(i) = srcLineList(i).Substring(cnt)
        Next

        Return True

    End Function
#End Region

#End Region

#Region "変換対象の文字列を検索する正規表現を取得する。"
    ''' <summary>
    ''' 変換対象の文字列を検索する正規表現を取得する。
    ''' </summary>
    ''' <returns>正規表現</returns>
    ''' <remarks></remarks>
    Protected MustOverride Function GetRegEx() As Regex
#End Region

#Region "正規表現の検索結果を編集する。"
    ''' <summary>
    ''' 正規表現の検索結果を編集する。
    ''' </summary>
    ''' <param name="match">検索結果</param>
    ''' <returns>編集結果</returns>
    ''' <remarks></remarks>
    Protected MustOverride Function MatchEvaluator( _
        ByVal match As Match) As String
#End Region

#Region "予約語一覧を取得する。"
    ''' <summary>
    ''' 予約語一覧を取得する。
    ''' </summary>
    ''' <returns>予約語一覧</returns>
    ''' <remarks></remarks>
    Public MustOverride Function GetReservedWords() As String()
#End Region

#Region "タイトルを取得"
    ''' <summary>
    ''' タイトルを取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public MustOverride Function GetDefaultTitle() As String
#End Region

#Region "タイトルを取得"
    ''' <summary>
    ''' 前景色(タイトル)を取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public MustOverride Function GetTitleBackColor() As String
#End Region

#Region "背景色を取得"
    ''' <summary>
    ''' 背景色を取得
    ''' </summary>
    ''' <returns>背景色</returns>
    ''' <remarks></remarks>
    Public MustOverride Function GetBackColor() As String
#End Region

#Region "前景色を取得"
    ''' <summary>
    ''' 前景色を取得
    ''' </summary>
    ''' <returns>前景色</returns>
    ''' <remarks></remarks>
    Public MustOverride Function GetForeColor() As String
#End Region


End Class

[VB.NET]CodeConverterToHtml

続きを読む


[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page2] [Programming .NET Tips]

[はじめに]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page1]」からの続きです。

[プログラムソース]
ブログの容量制限の為、下記に分けて記述しています。
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page1]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page2]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page3]
コードのコピー
Imports System.Text.RegularExpressions

''' <summary>
''' 変換(C#ソースコード→HTML)
''' </summary>
''' <remarks></remarks>
Public Class CSharpCodeConverterToHtml
    Inherits CodeConverterToHtml

#Region "定数定義"
    ''' <summary>
    ''' 背景色
    ''' </summary>
    ''' <remarks></remarks>
    Private Const BACK_COLOR As String = "#FFFFE0"

    ''' <summary>
    ''' 背景色(タイトル)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const BACK_COLOR_TITLE As String = "#66CCCC"

    ''' <summary>
    ''' 前景色
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR As String = "#000000"

    ''' <summary>
    ''' 前景色(コメント)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR_COMMENT As String = "#008040"

    ''' <summary>
    ''' 前景色(文字列)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR_STRING As String = "#FF0000"

    ''' <summary>
    ''' 前景色(予約語)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR_RESERVED_WORD As String = "#0000FF"
#End Region

#Region "変数定義"
    ''' <summary>
    ''' 正規表現
    ''' </summary>
    ''' <remarks></remarks>
    Private m_RegEx As Regex = Nothing

    ''' <summary>
    ''' 予約語一覧
    ''' </summary>
    ''' <remarks></remarks>
    Private m_ReservedWords As New List(Of String)
#End Region

#Region "コンストラクタ"
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()

    End Sub
#End Region

#Region "変換対象の文字列を検索する正規表現を取得する。"
    ''' <summary>
    ''' 変換対象の文字列を検索する正規表現を取得する。
    ''' </summary>
    ''' <returns>正規表現</returns>
    ''' <remarks></remarks>
    Protected Overrides Function GetRegEx() As Regex
        If Not (Me.m_RegEx Is NothingThen
            Return Me.m_RegEx
        End If

        Dim strPatternAll As String = Nothing
        '正規表現パターン
        '※コメント判別
        '(先頭開始、0個以上の「&nbsp;」、1個以上の「//」、0個以上の任意文字)
        Dim strPattern1 As String = "^(&nbsp;)*(//)+.*"
        '※コメント判別
        '(先頭開始、0個以上の空白、1個以上の「//」、0個以上の任意文字)
        Dim strPattern2 As String = "^\s*(//)+.*"
        '※文字列判別
        '(「"」開始、0個以上の任意文字、最も手前の「"」終了)
        Dim strPattern3 As String = """.*?"""
        '※文字列判別
        '(「&quot;」開始、0個以上の任意文字、最も手前の「&quot;」終了)
        Dim strPattern4 As String = "&quot;.*?&quot;"
        '※予約語判別
        '(単語単位で予約語の何れかと同じ)
        Dim wkStr As String = String.Join("|"Me.GetReservedWords())
        Dim strPattern5 As String = "\b(" & wkStr & ")\b"

        strPatternAll = _
                    strPattern1 & "|" & strPattern2 & "|" & _
                    strPattern3 & "|" & strPattern4 & "|" & _
                    strPattern5

        Me.m_RegEx = New Regex(strPatternAll)

        Return Me.m_RegEx
    End Function
#End Region

#Region "正規表現の検索結果を編集する。"
    ''' <summary>
    ''' 正規表現の検索結果を編集する。
    ''' </summary>
    ''' <param name="match">検索結果</param>
    ''' <returns>編集結果</returns>
    ''' <remarks></remarks>
    Protected Overrides Function MatchEvaluator(ByVal match As Match) As String
        If match.Value.Replace("&nbsp;""").StartsWith("//"OrElse _
            match.Value.Trim().StartsWith("//"Then
            'コメントの場合            
            Dim wk1 As Integer = match.Value.IndexOf("//")
            If wk1 = 0 Then
                Return String.Format( _
                    "<font color='{0}'>{1}</font>", _
                    FORE_COLOR_COMMENT, _
                    match.Value.Substring(wk1))
            End If
            Return match.Value.Substring(0, wk1) & _
                    String.Format( _
                    "<font color='{0}'>{1}</font>", _
                    FORE_COLOR_COMMENT, _
                    match.Value.Substring(wk1))
        End If

        If (match.Value.StartsWith("&quot;"AndAlso _
            match.Value.EndsWith("&quot;")) OrElse _
           (match.Value.StartsWith(""""AndAlso _
            match.Value.EndsWith("""")) Then
            '文字列の場合            
            Return String.Format( _
                "<font color='{0}'>{1}</font>", _
                FORE_COLOR_STRING, _
                match.Value)
        End If

        '予約語の場合
        Return String.Format( _
            "<font color='{0}'>{1}</font>", _
            FORE_COLOR_RESERVED_WORD, _
            match.Value)
    End Function
#End Region

#Region "予約語一覧を取得する。"
    ''' <summary>
    ''' 予約語一覧を取得する。
    ''' </summary>
    ''' <returns>予約語一覧</returns>
    ''' <remarks></remarks>
    Public Overrides Function GetReservedWords() As String()
        If Me.m_ReservedWords.Count > 0 Then
            Return Me.m_ReservedWords.ToArray()
        End If

        With Me.m_ReservedWords

            .AddRange(New String() {"abstract""as""base""bool""break"})
            .AddRange(New String() {"byte""case""catch""char""checked"})
            .AddRange(New String() {"class""const""continue""decimal""decimal"})
            .AddRange(New String() {"default""delegate""do""double""else"})
            .AddRange(New String() {"enum""event""explicit""extern""false"})
            .AddRange(New String() {"finally""fixed""float""for""foreach"})
            .AddRange(New String() {"from""get""goto""group""if"})
            .AddRange(New String() {"implicit""in""int""interface""internal"})
            .AddRange(New String() {"into""is""join""let""lock"})
            .AddRange(New String() {"long""namespace""new""null""object"})
            .AddRange(New String() {"operator""orderby""out""override""params"})
            .AddRange(New String() {"partial""private""protected""public""readonly"})
            .AddRange(New String() {"ref""return""sbyte""sealed""select"})
            .AddRange(New String() {"set""short""sizeof""stackalloc""static"})
            .AddRange(New String() {"string""struct""switch""this""throw"})
            .AddRange(New String() {"true""try""typeof""uint""ulong"})
            .AddRange(New String() {"unchecked""unsafe""ushort""using""value"})
            .AddRange(New String() {"virtual""void""volatile""where""while"})
            .AddRange(New String() {"yield"})

        End With

        Return Me.m_ReservedWords.ToArray()

    End Function
#End Region

#Region "タイトルを取得"
    ''' <summary>
    ''' タイトルを取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function GetDefaultTitle() As String
        Return "C#"
    End Function
#End Region

#Region "背景色(タイトル)を取得"
    ''' <summary>
    ''' 背景色(タイトル)を取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function GetTitleBackColor() As String
        Return BACK_COLOR_TITLE
    End Function
#End Region

#Region "背景色を取得"
    ''' <summary>
    ''' 背景色を取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function GetBackColor() As String
        Return BACK_COLOR
    End Function
#End Region

#Region "前景色を取得"
    ''' <summary>
    ''' 前景色を取得
    ''' </summary>
    ''' <returns>前景色</returns>
    ''' <remarks></remarks>
    Public Overrides Function GetForeColor() As String
        Return FORE_COLOR
    End Function
#End Region

End Class

[VB.NET]CSharpCodeConverterToHtml.vb

[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page3] [Programming .NET Tips]

[はじめに]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page2]」からの続きです。

[プログラムソース]
ブログの容量制限の為、下記に分けて記述しています。
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page1]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page2]
[.NET]プログラムコードの変換(C#、VB.NET→HTML)[Page3]
コードのコピー
Imports System.Text.RegularExpressions

''' <summary>
''' 変換(SQLServerコード→HTML)
''' </summary>
''' <remarks></remarks>
Public Class SqlServerCodeConverterToHtml
    Inherits CodeConverterToHtml

#Region "定数定義"
    ''' <summary>
    ''' 背景色
    ''' </summary>
    ''' <remarks></remarks>
    Private Const BACK_COLOR As String = "#FFFFE0"

    ''' <summary>
    ''' 背景色(タイトル)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const BACK_COLOR_TITLE As String = "#66CCCC"

    ''' <summary>
    ''' 前景色
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR As String = "#000000"

    ''' <summary>
    ''' 前景色(コメント)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR_COMMENT As String = "#008040"

    ''' <summary>
    ''' 前景色(文字列)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR_STRING As String = "#FF0000"

    ''' <summary>
    ''' 前景色(予約語)
    ''' </summary>
    ''' <remarks></remarks>
    Private Const FORE_COLOR_RESERVED_WORD As String = "#0000FF"
#End Region

#Region "変数定義"
    ''' <summary>
    ''' 正規表現
    ''' </summary>
    ''' <remarks></remarks>
    Private m_RegEx As Regex = Nothing

    ''' <summary>
    ''' 予約語一覧
    ''' </summary>
    ''' <remarks></remarks>
    Private m_ReservedWords As New List(Of String)
#End Region

#Region "コンストラクタ"
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()

    End Sub
#End Region

#Region "変換対象の文字列を検索する正規表現を取得する。"
    ''' <summary>
    ''' 変換対象の文字列を検索する正規表現を取得する。
    ''' </summary>
    ''' <returns>正規表現</returns>
    ''' <remarks></remarks>
    Protected Overrides Function GetRegEx() As Regex
        If Not (Me.m_RegEx Is NothingThen
            Return Me.m_RegEx
        End If

        Dim strPatternAll As String = Nothing
        '正規表現パターン
        '※コメント判別
        '(先頭開始、0個以上の「&nbsp;」、1個以上の「--」、0個以上の任意文字)
        Dim strPattern1 As String = "^(&nbsp;)*(--)+.*"
        '※コメント判別
        '(先頭開始、0個以上の空白、1個以上の「--」、0個以上の任意文字)
        Dim strPattern2 As String = "^\s*(--)+.*"
        '※文字列判別
        '(「'」開始、0個以上の任意文字、最も手前の「'」終了)
        Dim strPattern3 As String = "'.*?'"
        '※予約語判別
        '(単語単位で予約語の何れかと同じ)
        Dim wkStr As String = String.Join("|"Me.GetReservedWords())
        Dim strPattern4 As String = "\b(" & wkStr & ")\b"

        strPatternAll = _
                    strPattern1 & "|" & strPattern2 & "|" & _
                    strPattern3 & "|" & strPattern4 

        Me.m_RegEx = New Regex(strPatternAll, RegexOptions.IgnoreCase)

        Return Me.m_RegEx
    End Function
#End Region

#Region "正規表現の検索結果を編集する。"
    ''' <summary>
    ''' 正規表現の検索結果を編集する。
    ''' </summary>
    ''' <param name="match">検索結果</param>
    ''' <returns>編集結果</returns>
    ''' <remarks></remarks>
    Protected Overrides Function MatchEvaluator(ByVal match As Match) As String
        If match.Value.Replace("&nbsp;""").StartsWith("--"OrElse _
            match.Value.Trim().StartsWith("--"Then
            'コメントの場合            
            Dim wk1 As Integer = match.Value.IndexOf("--")
            If wk1 = 0 Then
                Return String.Format( _
                    "<font color='{0}'>{1}</font>", _
                    FORE_COLOR_COMMENT, _
                    match.Value.Substring(wk1))
            End If
            Return match.Value.Substring(0, wk1) & _
                    String.Format( _
                    "<font color='{0}'>{1}</font>", _
                    FORE_COLOR_COMMENT, _
                    match.Value.Substring(wk1))
        End If

        If match.Value.StartsWith("'"AndAlso _
            match.Value.EndsWith("'"Then
            '文字列の場合            
            Return String.Format( _
                "<font color='{0}'>{1}</font>", _
                FORE_COLOR_STRING, _
                match.Value)
        End If

        '予約語の場合
        Return String.Format( _
            "<font color='{0}'>{1}</font>", _
            FORE_COLOR_RESERVED_WORD, _
            match.Value)
    End Function
#End Region

#Region "予約語一覧を取得する。"
    ''' <summary>
    ''' 予約語一覧を取得する。
    ''' </summary>
    ''' <returns>予約語一覧</returns>
    ''' <remarks></remarks>
    Public Overrides Function GetReservedWords() As String()
        If Me.m_ReservedWords.Count > 0 Then
            Return Me.m_ReservedWords.ToArray()
        End If

        With Me.m_ReservedWords

            .AddRange(New String() {"ADD""ALL""ALTER""AND""ANY"})
            .AddRange(New String() {"AS""ASC""AUTHORIZATION""BACKUP""BEGIN"})
            .AddRange(New String() {"BETWEEN""BREAK""BROWSE""BULK""BY"})
            .AddRange(New String() {"CASCADE""CASE""CHECK""CHECKPOINT""CLOSE"})
            .AddRange(New String() {"CLUSTERED""COALESCE""COLLATE""COLUMN""COMMIT"})
            .AddRange(New String() {"COMPUTE""CONSTRAINT""CONTAINS""CONTAINSTABLE""CONTINUE"})
            .AddRange(New String() {"CONVERT""CREATE""CROSS""CURRENT""CURRENT_DATE"})
            .AddRange(New String() {"CURRENT_TIME""CURRENT_TIMESTAMP""CURRENT_USER""CURSOR""DATABASE"})
            .AddRange(New String() {"DBCC""DEALLOCATE""DECLARE""DEFAULT""DELETE"})
            .AddRange(New String() {"DENY""DESC""DISK""DISTINCT""DISTRIBUTED"})
            .AddRange(New String() {"DOUBLE""DROP""DUMP""ELSE""END"})
            .AddRange(New String() {"ERRLVL""ESCAPE""EXCEPT""EXEC""EXECUTE"})
            .AddRange(New String() {"EXISTS""EXIT""EXTERNAL""FETCH""FILE"})
            .AddRange(New String() {"FILLFACTOR""FOR""FOREIGN""FREETEXT""FREETEXTTABLE"})
            .AddRange(New String() {"FROM""FULL""FUNCTION""GOTO""GRANT"})
            .AddRange(New String() {"GROUP""HAVING""HOLDLOCK""IDENTITY""IDENTITY_INSERT"})
            .AddRange(New String() {"IDENTITYCOL""IF""IN""INDEX""INNER"})
            .AddRange(New String() {"INSERT""INTERSECT""INTO""IS""JOIN"})
            .AddRange(New String() {"KEY""KILL""LEFT""LIKE""LINENO"})
            .AddRange(New String() {"LOAD""MERGE""NATIONAL""NOCHECK""NONCLUSTERED"})
            .AddRange(New String() {"NOT""NULL""NULLIF""OF""OFF"})
            .AddRange(New String() {"OFFSETS""ON""OPEN""OPENDATASOURCE""OPENQUERY"})
            .AddRange(New String() {"OPENROWSET""OPENXML""OPTION""OR""ORDER"})
            .AddRange(New String() {"OUTER""OVER""PERCENT""PIVOT""PLAN"})
            .AddRange(New String() {"PRECISION""PRIMARY""PRINT""PROC""PROCEDURE"})
            .AddRange(New String() {"PUBLIC""RAISERROR""READ""READTEXT""RECONFIGURE"})
            .AddRange(New String() {"REFERENCES""REPLICATION""RESTORE""RESTRICT""RETURN"})
            .AddRange(New String() {"REVERT""REVOKE""RIGHT""ROLLBACK""ROWCOUNT"})
            .AddRange(New String() {"ROWGUIDCOL""RULE""SAVE""SCHEMA""SECURITYAUDIT"})
            .AddRange(New String() {"SELECT""SEMANTICKEYPHRASETABLE""SEMANTICSIMILARITYDETAILSTABLE"})
            .AddRange(New String() {"SEMANTICSIMILARITYTABLE""SESSION_USER"})
            .AddRange(New String() {"SET""SETUSER""SHUTDOWN""SOME"})
            .AddRange(New String() {"STATISTICS""SYSTEM_USER""TABLE"})
            .AddRange(New String() {"TABLESAMPLE""TEXTSIZE""THEN"})
            .AddRange(New String() {"TO""TOP""TRAN"})
            .AddRange(New String() {"TRANSACTION""TRIGGER""TRUNCATE"})
            .AddRange(New String() {"TRY_CONVERT""TSEQUAL""UNION"})
            .AddRange(New String() {"UNIQUE""UNPIVOT""UPDATE"})
            .AddRange(New String() {"UPDATETEXT""USE""USER"})
            .AddRange(New String() {"VALUES""VARYING""VIEW"})
            .AddRange(New String() {"WAITFOR""WHEN""WHERE"})
            .AddRange(New String() {"WHILE""WITH""WITHINGROUP""WRITETEXT"})

        End With

        Return Me.m_ReservedWords.ToArray()

    End Function
#End Region

#Region "タイトルを取得"
    ''' <summary>
    ''' タイトルを取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function GetDefaultTitle() As String
        Return "SQLServer"
    End Function
#End Region

#Region "背景色(タイトル)を取得"
    ''' <summary>
    ''' 背景色(タイトル)を取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function GetTitleBackColor() As String
        Return BACK_COLOR_TITLE
    End Function
#End Region

#Region "背景色を取得"
    ''' <summary>
    ''' 背景色を取得
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function GetBackColor() As String
        Return BACK_COLOR
    End Function
#End Region

#Region "前景色を取得"
    ''' <summary>
    ''' 前景色を取得
    ''' </summary>
    ''' <returns>前景色</returns>
    ''' <remarks></remarks>
    Public Overrides Function GetForeColor() As String
        Return FORE_COLOR
    End Function
#End Region

End Class

[VB.NET]SqlServerCodeConverterToHtml

[.NET]QRコードの変換 [Programming .NET Tips]

[はじめに]
・最近、仕事でQRコードを扱うシステム開発に携わる機会が多いので、
 .NETでも作ってみました。
 .NET FrameworkではQRコードを標準でサポートしていない為、
 外部のコンポーネントを利用しています。

[関連情報]
QRコードの仕様 (デンソーウェーブのサイト)
 http://www.qrcode.com
外部コンポーネント
 「ThoughtWorks.QRCode.dll」を参照しています。
 [Open Source QRCode Library] からダウンロードできます。
 「ThoughtWorks.QRCode.dll」を参照は、「参照設定」から追加して下さい。
 (※追加しないとコンパイルエラーになります。)
  参照設定

[ソース]
 QRコードの変換ユーティリティクラスです。
 提供するメソッドは、以下の2つです。
 ・Encodeメソッド:文字列をQRコードのイメージに変換する。
 ・Decodeメソッド:QRコードのイメージから文字列を取得する。
コードのコピー
Imports System.IO
Imports System.Text
Imports ThoughtWorks.QRCode.Codec
Imports ThoughtWorks.QRCode.Codec.Data
Imports ThoughtWorks.QRCode.Codec.Util

''' <summary>
''' QRコード関連のユーティリティ
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class QRCodeUtil

    '[説明]
    '[参照設定]
    '   ThoughtWorks.QRCode.dll
    '  上記DLLは、以下のサイトよりダウンロード可能
    '  [Open Source QRCode Library]
    '  [http://www.codeproject.com/KB/cs/qrcode.aspx]
    '[QRコードの仕様]
    '   デンソーウェーブの下記サイトをご参照下さい。
    '   [QR Code.com]
    '   [http://www.qrcode.com]


    ''' <summary>
    ''' デフォルトのエンコーディング名
    ''' </summary>
    ''' <remarks></remarks>
    Private Const DEFAULT_ENCODING_NAME As String = "shift_jis"

    ''' <summary>
    ''' デフォルトのエンコーディング
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared ReadOnly DEFAULT_ENCODING As Encoding _
             = Encoding.GetEncoding(DEFAULT_ENCODING_NAME)

#Region "文字列をQRコードに変換する。"

    ''' <summary>
    ''' 文字列をQRコードに変換する。
    ''' </summary>
    ''' <param name="txtData">変換元の文字列</param>
    ''' <param name="encMode">情報の種類(Byte/AlphaNumeric/Numeric)</param>
    ''' <param name="errCorrect">誤り訂正能力(L/M/Q/H)</param>
    ''' <param name="scale">1セル当りのピクセル数</param>
    ''' <param name="version">QRコードに格納する情報量を決める型番(1~40)</param>
    ''' <returns>QRコードのイメージ</returns>
    ''' <remarks></remarks>
    Public Shared Function Encode( _
        ByVal txtData As String, _
        ByVal encMode As QRCodeEncoder.ENCODE_MODE, _
        ByVal errCorrect As QRCodeEncoder.ERROR_CORRECTION, _
        ByVal scale As Integer, _
        ByVal version As Integer _
        ) As Image

        Return Encode( _
            txtData, encMode, errCorrect, _
            scale, version, DEFAULT_ENCODING)
    End Function


    ''' <summary>
    ''' 文字列をQRコードに変換する。
    ''' </summary>
    ''' <param name="txtData">変換元の文字列</param>
    ''' <param name="encMode">情報の種類(Byte/AlphaNumeric/Numeric)</param>
    ''' <param name="errCorrect">誤り訂正能力(L/M/Q/H)</param>
    ''' <param name="scale">1セル当りのピクセル数</param>
    ''' <param name="version">QRコードに格納する情報量を決める型番(1~40)</param>
    ''' <param name="encoding">エンコーディング</param>
    ''' <returns>QRコードのイメージ</returns>
    ''' <remarks></remarks>
    Public Shared Function Encode( _
        ByVal txtData As String, _
        ByVal encMode As QRCodeEncoder.ENCODE_MODE, _
        ByVal errCorrect As QRCodeEncoder.ERROR_CORRECTION, _
        ByVal scale As Integer, _
        ByVal version As Integer, _
        ByVal encoding As System.Text.Encoding _
        ) As Image

        Dim errMsg As String = Nothing

        Dim qrEnc As QRCodeEncoder = Nothing
        Dim img As Image = Nothing

        '引数チェック
        '[変換元の文字列]
        '   Nothingと空文字列はNGとする。
        If String.IsNullOrEmpty(txtData) Then
            Throw New ArgumentException( _
                "Encode#txtDataが、Nothingか空文字列です。")
        End If

        '[QRコードに格納する情報量を決める型番]
        '   1~40の範囲外はNGとする。
        If version < 1 OrElse version > 40 Then
            errMsg = String.Format( _
                "Versionが範囲外[1~40]です。値:[{0}]", version)
            Throw New ArgumentOutOfRangeException( _
                "Encode#version", errMsg)
        End If

        qrEnc = New QRCodeEncoder()

        '「情報の種類」を設定
        '   QRCodeEncoder.ENCODE_MODE.BYTE
        '   QRCodeEncoder.ENCODE_MODE.NUMERIC
        '   QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC
        qrEnc.QRCodeEncodeMode = encMode

        '「誤り訂正能力」を設定
        '   QRCodeEncoder.ERROR_CORRECTION.L
        '   QRCodeEncoder.ERROR_CORRECTION.M
        '   QRCodeEncoder.ERROR_CORRECTION.Q
        '   QRCodeEncoder.ERROR_CORRECTION.H
        qrEnc.QRCodeErrorCorrect = errCorrect

        '「1セル当りのピクセル数」を設定
        '   数値が大きい程、画像のサイズは大きくなる。
        qrEnc.QRCodeScale = scale

        '「QRコードに格納する情報量を決める型番」を設定
        '   1から40までの整数を指定
        '   格納するデータ長が長い程、
        '   より大きいバージョン番号を必要とする。
        '   QRコードを構成するセルの数も多くなる。
        qrEnc.QRCodeVersion = version

        img = qrEnc.Encode(txtData, encoding)

        Return img
    End Function
#End Region

#Region "QRコードのイメージから文字列を復元する。"

    ''' <summary>
    ''' QRコードのイメージから文字列を復元する。
    ''' </summary>
    ''' <param name="imgData">QRコードのイメージ</param>
    ''' <returns>復元後の文字列</returns>
    ''' <remarks></remarks>
    Public Shared Function Decode( _
        ByVal imgData As Image _
        ) As String
        Return Decode(imgData, DEFAULT_ENCODING)
    End Function


    ''' <summary>
    ''' QRコードのイメージから文字列を復元する。
    ''' </summary>
    ''' <param name="imgData">QRコードのイメージ</param>
    ''' <param name="encoding">エンコーディング</param>
    ''' <returns>復元後の文字列</returns>
    ''' <remarks></remarks>
    Public Shared Function Decode( _
        ByVal imgData As Image, _
        ByVal encoding As System.Text.Encoding _
        ) As String

        Dim qrDec As QRCodeDecoder = Nothing
        Dim qrBitmap As QRCodeBitmapImage = Nothing
        Dim txtData As String = Nothing

        '引数チェック
        '[変換元の文字列]
        '   NothingはNGとする。
        If imgData Is Nothing Then
            Throw New ArgumentNullException( _
                "Decode#imgDataがNothingです。")
        End If

        qrDec = New QRCodeDecoder()
        qrBitmap = New QRCodeBitmapImage(New Bitmap(imgData))

        txtData = qrDec.decode(qrBitmap, encoding)

        Return txtData
    End Function

#End Region

End Class
[VB.NET]QRコードの変換ユーティリティ

[.NET]データベースの接続文字列の書式を簡単に知るには? [Programming .NET Tips]

[はじめに]
・.NETのアプリケーションからデータベースに接続する場合、
 接続文字列という情報が必要になります。(.NETに限った話ではありませんが…)
 .NETのアプリケーション開発で、接続文字列の書式が分からない場合、
 書籍やインターネット、他のアプリケーションを参考にすることがありますが、
 「Visual Studio 2008」の機能を使って、接続文字列を簡単に取得する方法があります。
 (※「Visual Studio 2008」とありますが、
   「Visual Studio.NET 2002」、「Visual Studio.NET 2003」、
   「Visual Studio 2005」でも可能です。
   試していないので若干方法が異なると思いますがご了承下さい。)

[前提条件]
・「Visual Studio 2008」がインストールされていること。
・データベースにアクセスできること。

[手順]
(1)「Visual Studio 2008」を起動し、「サーバーエクスプローラ」を選択します。
  (※「サーバーエクスプローラ」が表示されない場合は、「ツール」から表示可能にできます。)
sql2005_01.JPG

(2)「データ接続」を右クリックし、「接続の追加」を選択します。
sql2005_02.JPG

sql2005_03.JPG

(3)「データソースの変更」画面で、「データソース」や「データプロバイダ」を選択します。
  選択する内容は、接続するデータベースの種類によって変わります。
  ここでは、「SQL Server 2005 Express Edition」に接続する例として、
  「データソース」に「Microsoft SQL Server」、
  「データプロバイダ」に「.NETFrameworkSQLServer用データプロバイダ」を選択します。
sql2005_04.JPG

(4)「接続の追加」画面で、接続情報を入力します。
  ここでは、
  ・接続先のサーバを「(local)」、
  ・認証方式を「Windows認証」、
  ・接続先データベースを「master」
  とします。
 接続情報を入力したら、「テスト接続」ボタンを押して、
 データベースの接続がうまく行えることを確認します。
sql2005_05.JPG

(5)データベースの接続が成功したら、確認画面が表示されます。
  確認メッセージを「OK」ボタンで閉じ、
  「詳細設定」ボタンを押し「詳細プロパティ」画面を表示します。
sql2005_06.JPG

(6)「詳細プロパティ」画面の一番下の欄に、接続文字列が表示されます。
  通常のテキストなので、コピーして流用することもできます。
  この場合の書式文字列は、
  「Data Source=(local);Initial Catalog=master;Integrated Security=True」
  です。
sql2005_07.JPG

[関連サイト]
(1)接続文字列の使用
 http://msdn.microsoft.com/ja-jp/library/ms254978(VS.80).aspx

[.NET]例外の再スロー(Throwの引数の有無) [Programming .NET Tips]

[ポイント]
・.NET系言語(C#、VB.NET)のプログラムコードで、
 以下のような構文を見かけることがあります。
コードのコピー
  Try 
    Dim x As Integer = func2(a) 
    Return x 
  Catch ex As Exception 
    '何らかの例外後の後処理をして、再スロー 
    '(例外後の処理は割愛)... 
    Throw ex    '←ここに注目 
  End Try
[VB.NET]例外の再スロー[Throwの引数がある場合]
 Tryステートメント内で発生した例外をCatchして、
 再度スローする処理で、「Throw ex」と書く人が結構多いようですが、
 実はこのような書き方をすると、
 ここでCatchする以前のトレース情報が失われてしまうのです。

 トレース情報を保持しつつ再スローするには、
 以下の様に、「Throw ex」ではなく「Throw 」と記述します。
コードのコピー
  Try 
      Dim x As Integer = func2(a) 
      Return x 
  Catch ex As Exception 
      '何らかの例外後の後処理をして、再スロー 
      '(例外後の処理は割愛)... 
      Throw    '←exは省略します。 
  End Try 
[VB.NET]例外の再スロー[Throwの引数がない場合]

 なぜか書籍やMSDNにも、前者の書き方でサンプルを紹介している為、
 知らない人が多いようです。
 (Throwステートメントとは直接関係ないサンプルだから、
  あまり重要視していないのだと思いますが…)
[参考文献]
「C#クックブック 第3版」
 「レシピ4.1 キャッチした例外を再スローするタイミングを把握する」で、
 Throwステートメントの引数の有無の違いを明確に説明しています。
 「Throw」(引数なし)の記述を推奨しています。
「プログラミングC#―C#2.0/.NET2.0/Visual Studio2005対応」
 「11.4 例外の再スロー」で、
 理由の説明はないが、「Throw」(引数なし)の記述を推奨しています。

[検証]
 Throwステートメントの仕様について、
 2つのパターンの検証プログラムを実行して、結果を比較してみた。
パターン1
 Throwステートメントに引数がある場合、
 Button1_Click()→Method1()→Method2()→Method3()→Method4()と
 メソッドを呼び、最下層のMethod4()で
 ゼロ除算の例外(System.DevideByZeroException)を意図的に発生させる。
 各々のメソッドのCatch句では、「Throw ex」(引数あり)で例外を再Throwする。
 最上位メソッドにて、例外の内容(ToString()した結果)を表示する。
パターン2
 Throwステートメントに引数がない場合、
 Button1_Click()→Method1()→Method2()→Method3()→Method4()と
 メソッドを呼び、最下層のMethod4()で
 ゼロ除算の例外(System.DevideByZeroException)を意図的に発生させる。
 各々のメソッドのCatch句では、「Throw 」(引数なし)で例外を再Throwする。
 最上位メソッドにて、例外の内容(ToString()した結果)を表示する。

・パターン1(Throwステートメントに引数がある場合)
コードのコピー
Private Sub Button1_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    Dim num As Integer

    Try
        num = Method1(1, 0)
    Catch ex As Exception
        MessageBox.Show( _
            ex.ToString(), _
            "例外[Throwの引数がある場合]")
    End Try
End Sub

Private Function Method1( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method2(a, b)
    Catch ex As Exception
        Throw ex
    End Try
End Function

Private Function Method2( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method3(a, b)
    Catch ex As Exception
        Throw ex
    End Try
End Function

Private Function Method3( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method4(a, b)
    Catch ex As Exception
        Throw ex
    End Try
End Function

Private Function Method4( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        'b=0の時に例外が発生する。
        Return a \ b
    Catch ex As Exception
        Throw ex
    End Try
End Function
[VB.NET]例外[Throwの引数がある場合]
・パターン1の実行結果(Throwステートメント[引数あり])
 Throwの引数を指定した場合は、
 保持されているトレース情報は、Method1、Button1_Clickのみで、
 Method2、Method3、Method4は保持されていないことがわかります。
 引数指定での再スローでは、それより前のトレース情報を保持しない為です。
 この例では、
  Method3で再スローする時に、Method4以降のトレース情報を保持しない、
  Method2で再スローする時に、Method3以降のトレース情報を保持しない、
  Method1で再スローする時に、Method2以降のトレース情報を保持しない為、
 図のような結果になります。
例外[Throwの引数がある場合]

・パターン2(Throwステートメント[引数なし])
コードのコピー
Private Sub Button1_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    Dim num As Integer

    Try
        num = Method1(1, 0)
    Catch ex As Exception
        MessageBox.Show( _
            ex.ToString(), _
            "例外[Throwの引数がない場合]")
    End Try
End Sub

Private Function Method1( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method2(a, b)
    Catch ex As Exception
        Throw
    End Try
End Function

Private Function Method2( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method3(a, b)
    Catch ex As Exception
        Throw
    End Try
End Function

Private Function Method3( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method4(a, b)
    Catch ex As Exception
        Throw
    End Try
End Function

Private Function Method4( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        'b=0の時に例外が発生する。
        Return a \ b
    Catch ex As Exception
        Throw
    End Try
End Function
[VB.NET]例外[Throwの引数がない場合]
・パターン2の実行結果(Throwステートメント[引数なし])
 Throwの引数を指定しない場合は、
 関連するトレース情報(Method1、Method2、Method3、Method4、Button1_Click)を
 全て保持していることがわかります。
例外[Throwの引数がない場合]

[.NET]カスタマイズした構成情報の利用(.NET1.1以前が対象) [Programming .NET Tips]

[ポイント]
(1)カスタム構成セクションとは?
  通常、アプリケーションの構成情報は、appSettingsノード配下の
  addノード(key属性とvalue属性)に記述するルールですが、
  独自のルール(独自のXMLタグ)で定義することもできます。
  この独自のXMLタグで定義された構成情報を、「カスタム構成セクション」と呼びます。
  「カスタム構成セクション」にアクセスする為には、
  プログラム上で「カスタム構成セクションハンドラ」クラスを実装し、
  構成ファイルに「カスタム構成セクションハンドラ」を追加する必要があります。
(2)カスタム構成セクションハンドラとは?
  カスタム構成セクションにアクセスする為には、
  その独自のXMLタグを解析する必要があります。
  その独自のXMLタグを解析するクラスを、「カスタム構成セクションハンドラ」と呼びます。
  カスタム構成セクションハンドラは、以下の(a)(b)の条件に従って実装する必要があります。
   (a)System.Configuration.IConfigurationSectionHandlerインタフェースを実装する。
   (b)IConfigurationSectionHandlerインタフェースのCreateメソッドに、
     カスタム構成セクションを解析する処理を実装する。
(3)カスタム構成セクションハンドラが、カスタム構成セクションにアクセスするには?
  カスタム構成セクションハンドラがカスタムセクションにアクセスする為には、
  構成ファイルに、構成セクションハンドラを追加する必要があります。
  追加することにより、カスタム構成セクションハンドラとカスタムセクションの対応付けを
  定義したことになります。
(4)利用可能な.NET Frameworkのバージョンは?
  本記事のサンプルは、.NET1.1以前で主流だった方法です。
  .NET2.0以降では、「ConfigurationSection」クラスを使用する方法が
  推奨されています。(.NET2.0以降でも使用可能)
(5))参考文献
  ・『MSDN Library for VisualStudio2008日本語版』
  ・『MCTSスキルチェック問題集70-536 .NET Framework2.0アプリケーション構築基礎』

カスタム構成セクションにアクセスする例を、以下の(1)~(4)に分けて示します。
(1)カスタム構成セクションの定義
  例として、日本の地域と県、県と県庁所在地の対応を定義しています。
[ソース]
コードのコピー
<configuration>
  <myCustomGroup>
    <Country Name="Japan">
      <Area Name="Kanto">
        <Prefecture Name="Tokyo" MajorCity="Tokyo"/>
        <Prefecture Name="Kanagawa" MajorCity="Yokohama"/>
        <Prefecture Name="Ibaragi" MajorCity="Mito"/>
      </Area>
      <Area Name="Chubu">
        <Prefecture Name="Aichi" MajorCity="Nagoya"/>
        <Prefecture Name="Gifu" MajorCity="Gifu"/>
        <Prefecture Name="Mie" MajorCity="Tsu"/>
      </Area>
    </Country>
  </myCustomGroup>
        (以下省略)
          :
例:カスタム構成セクションの定義

(2)カスタム構成セクションハンドラの実装
  System.Configuration.IConfigurationSectionHandlerインタフェースを
  実装したクラスを定義します。
  System.Configuration.IConfigurationSectionHandlerインタフェースの
  Createメソッドに、カスタム構成セクションのアクセス処理を実装します。
  この例では、カスタム構成セクションから、県と県庁所在地の一覧を取得し、
  HashTableに格納しています。
[ソース]
コードのコピー
''' <summary>
''' カスタム構成セクションハンドラ
''' ※.NET1.1以前で使用可能。
'''  .NET2.0以降ではSystem.Configuration.ConfigurationSectionクラスを推奨
''' </summary>
''' <remarks></remarks>
Public Class MyCustomConfigHandler1_1
    Implements System.Configuration.IConfigurationSectionHandler

    ''' <summary>
    ''' 構成セクションハンドラを作成する。
    ''' </summary>
    ''' <param name="parent">親オブジェクト</param>
    ''' <param name="configContext">構成コンテキストオブジェクト</param>
    ''' <param name="section">セクションXMLノード</param>
    ''' <returns>作成されたセクションハンドラオブジェクト</returns>
    ''' <remarks></remarks>
    Public Function Create( _
        ByVal parent As Object, _
        ByVal configContext As Object, _
        ByVal section As System.Xml.XmlNode) As Object _
        Implements _
        System.Configuration.IConfigurationSectionHandler.Create

        Dim configTable As New Hashtable()

        For Each areaNode As XmlNode In section.ChildNodes
            For Each prefNode As XmlNode In areaNode.ChildNodes
                configTable.Add( _
                    prefNode.Attributes("Name").Value, _
                    prefNode.Attributes("MajorCity").Value)
            Next
        Next

        Return configTable

    End Function
End Class
[VB.NET]例:カスタム構成セクションハンドラの実装

(3)構成ファイルにカスタム構成セクションハンドラの追加
  「myCustomGroup」、「Country」の対応付けを定義し、
  更に「Country」のセクションハンドラを定義しています。
  type属性には、カスタム構成セクションハンドラのアセンブリ修飾名を指定します。
  アセンブリ修飾名については、
  MessageBox.Show( _
   New MyCustomConfigHandler1_1().GetType().AssemblyQualifiedName)
  で確認できます。
[ソース]
コードのコピー
<configuration>
  <configSections>
    <sectionGroup name="myCustomGroup" >
      <section 
        name="Country" 
        type="CustomConfig.MyCustomConfigHandler1_1, 
              CustomConfig, 
              Version=1.0.0.0, 
              Culture=neutral, 
              PublicKeyToken=null"/>
    </sectionGroup>
  </configSections>
        (以下省略)
          :
例:カスタム構成セクションハンドラの追加

(4)構成情報の取得
  以下に、カスタム構成セクションハンドラを使用して構成情報を取得する例を示します。
  取得には、System.Configuration.ConfigurationSettingsクラスの
  GetConfigメソッドを使用します。(※.NET2.0以降では警告がでます。)
  GetConfigの引数には、起点となるカスタム構成セクションのノード名を指定します。
[ソース]
コードのコピー
Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click

    Dim rtn As Object = Nothing
    Dim configTable As Hashtable = Nothing

    '「myCustomGroup/Country」のXMLノードを起点とし、
    '構成情報を取得する。
    rtn = System.Configuration.ConfigurationSettings.GetConfig( _
        "myCustomGroup/Country")
    configTable = CType(rtn, Hashtable)

    '取得した構成情報をメッセージボックスに表示
    Dim sb As New StringBuilder()
    For Each k As String In configTable.Keys
        sb.Append(k & ":" & configTable(k).ToString() & vbCrLf)
    Next
    MessageBox.Show(sb.ToString())

End Sub
[VB.NET]例:カスタム構成セクションハンドラを使用して構成情報を取得する

[.NET]メールの送信(.NET2.0以降) [Programming .NET Tips]

[ポイント]
メールを送信するサンプルプログラムです。(最も簡単な例)
クラスライブラリ
 .NETFramework2.0から新たに追加されたクラスを使用しています。
 (1.1以前では『System.Web.Mail』名前空間のクラスが使用されていましたが、
  2.0以降は『System.Net.Mail』名前空間のクラスが推奨されています。)
クラス名/列挙体名概要
System.Net.Mail.SmtpClientクラスSMTPサーバを表すクラスです。
System.Net.Mail.MailMessageクラスメールを表すクラスです。
System.Net.Mail.MailAddressクラスメールアドレスを表すクラスです。
System.Net.Mail.Attachmentクラス添付ファイルを表すクラスです。
System.Net.NetworkCredential認証情報を表すクラスです。
System.Net.Mail.MailPriority列挙体メールの優先度を表す列挙体です。

CDO(Microsoft Collaboration Data Objects)
 Windowsでは、メールの送信機能として『CDO』を用意しています。
 CDOは、VB6やEXCEL VBA等からも利用することができますが、
 インタフェースがわかりにくいものでした。
 .NETでは、CDOの呼び出しをカプセル化することで、
 よりわかりやすいインタフェースを提供しています。
・参考文献
 『MSDN Library for VisualStudio2008日本語版』
 
以下にサンプルソースを示します
コードのコピー
''' <summary>
''' メールを送信する
''' </summary>
''' <param name="argSmtpServer">SMTPサーバ名</param>
''' <param name="argPortNo">ポート番号</param>
''' <param name="argSmtpAuth">SMTP認証の有無</param>
''' <param name="argUserName">認証ユーザ</param>
''' <param name="argPassword">認証パスワード</param>
''' <param name="argEnableSsl">SSLの使用有無</param>
''' <param name="argTimeout">タイムアウト(ミリ秒)(Nothingで100000)</param>
''' <param name="argFrom">メールアドレス(From)</param>
''' <param name="argTo">メールアドレス(To)</param>
''' <param name="argCc">メールアドレス(Cc)</param>
''' <param name="argBcc">メールアドレス(Bcc)</param>
''' <param name="argPriority">優先度</param>
''' <param name="argSubject">件名</param>
''' <param name="argBody">本文</param>
''' <param name="argIsHtml">HTMLかどうか</param>
''' <param name="argFile">添付ファイル</param>
''' <param name="argSubEnc">エンコード(件名)</param>
''' <param name="argBodyEnc">エンコード(本文)</param>
''' <remarks></remarks>
Private Sub SendMail( _
    ByVal argSmtpServer As String, _
    ByVal argPortNo As Integer, _
    ByVal argSmtpAuth As Boolean, _
    ByVal argUserName As String, _
    ByVal argPassword As String, _
    ByVal argEnableSsl As Boolean, _
    ByVal argTimeout As Integer?, _
    ByVal argFrom As String, _
    ByVal argTo() As String, _
    ByVal argCc() As String, _
    ByVal argBcc() As String, _
    ByVal argPriority As System.Net.Mail.MailPriority, _
    ByVal argSubject As String, _
    ByVal argBody As String, _
    ByVal argIsHtml As Boolean, _
    ByVal argFile() As System.IO.FileInfo, _
    ByVal argSubEnc As String, _
    ByVal argBodyEnc As String _
    )
    'SMTPサーバを設定
    '※サーバ名、ポート番号を設定
    Dim sClient As New System.Net.Mail.SmtpClient( _
        argSmtpServer, argPortNo _
    )

    'SMTP認証の設定
    If argSmtpAuth Then
        '認証が必要な場合は、ユーザ名とパスワードを設定
        sClient.Credentials = New System.Net.NetworkCredential( _
            argUserName, argPassword _
        )
    End If

    'SSLの使用有無を設定
    sClient.EnableSsl = argEnableSsl

    'タイムアウトを設定
    If argTimeout.HasValue Then
        sClient.Timeout = argTimeout
    End If

    'メールの設定
    Dim mail As New System.Net.Mail.MailMessage
    Try
        'メールアドレス(From)
        mail.From = New System.Net.Mail.MailAddress(argFrom)
        '※メールアドレス(To)を設定
        If Not (argTo Is NothingThen
            For Each addr As String In argTo
                mail.To.Add(addr)
            Next
        End If
        'メールアドレス(Cc)
        If Not (argCc Is NothingThen
            For Each addr As String In argCc
                mail.CC.Add(addr)
            Next
        End If
        'メールアドレス(Bcc)
        If Not (argBcc Is NothingThen
            For Each addr As String In argBcc
                mail.Bcc.Add(addr)
            Next
        End If

        '優先度
        '   高い:System.Net.Mail.MailPriority.High
        '   普通:System.Net.Mail.MailPriority.Normal
        '   低い:System.Net.Mail.MailPriority.Low
        mail.Priority = argPriority
        '件名を設定
        mail.Subject = argSubject
        '本文を設定
        mail.Body = argBody
        '本文をHTML形式にするかどうか
        mail.IsBodyHtml = argIsHtml
        '添付ファイル
        If Not (argFile Is NothingThen
            For Each f As FileInfo In argFile
                mail.Attachments.Add( _
                    New System.Net.Mail.Attachment(f.FullName))
            Next
        End If
        'エンコード(件名)
        '例:shift_jis、iso-2022-jp
        mail.SubjectEncoding = Encoding.GetEncoding(argSubEnc)
        'エンコード(本文)
        mail.BodyEncoding = Encoding.GetEncoding(argBodyEnc)

        'メールを送信
        sClient.Send(mail)
    Finally
        mail.Dispose()
    End Try
End Sub
[VB.NET]メールを送信するサンプル

コードのコピー
/// <summary>
/// メールを送信する
/// </summary>
/// <param name="argSmtpServer">SMTPサーバ名</param>
/// <param name="argPortNo">ポート番号</param>
/// <param name="argSmtpAuth">SMTP認証の有無</param>
/// <param name="argUserName">認証ユーザ</param>
/// <param name="argPassword">認証パスワード</param>
/// <param name="argEnableSsl">SSLの使用有無</param>
/// <param name="argTimeout">タイムアウト(ミリ秒)(nullで100000)</param>
/// <param name="argFrom">メールアドレス(From)</param>
/// <param name="argTo">メールアドレス(To)</param>
/// <param name="argCc">メールアドレス(Cc)</param>
/// <param name="argBcc">メールアドレス(Bcc)</param>
/// <param name="argPriority">優先度</param>
/// <param name="argSubject">件名</param>
/// <param name="argBody">本文</param>
/// <param name="argIsHtml">HTMLかどうか</param>
/// <param name="argFile">添付ファイル</param>
/// <param name="argSubEnc">エンコード(件名)</param>
/// <param name="argBodyEnc">エンコード(本文)</param>
/// <remarks></remarks>
private void SendMail(
    string argSmtpServer, int argPortNo, bool argSmtpAuth, 
    string argUserName, string argPassword, bool argEnableSsl, 
    int? argTimeout, string argFrom, 
    string[] argTo, string[] argCc, string[] argBcc, 
    System.Net.Mail.MailPriority argPriority, 
    string argSubject, string argBody, bool argIsHtml, 
    System.IO.FileInfo[] argFile, 
    string argSubEnc, string argBodyEnc)
{
    //SMTPサーバを設定
    //※サーバ名、ポート番号を設定
    System.Net.Mail.SmtpClient sClient = 
        new System.Net.Mail.SmtpClient(argSmtpServer, argPortNo);
    
    //SMTP認証の設定
    if (argSmtpAuth) {
        //認証が必要な場合は、ユーザ名とパスワードを設定
        sClient.Credentials = 
            new System.Net.NetworkCredential(
                argUserName, argPassword);
    }
    
    //SSLの使用有無を設定
    sClient.EnableSsl = argEnableSsl;
    
    //タイムアウトを設定
    if (argTimeout.HasValue) {
        sClient.Timeout = argTimeout;
    }
    
    //メールの設定
    System.Net.Mail.MailMessage mail = 
        new System.Net.Mail.MailMessage();
    try {
        //メールアドレス(From)
        mail.From = new System.Net.Mail.MailAddress(argFrom);
        //※メールアドレス(To)を設定
        if (argTo != null) {
            foreach (string addr in argTo) {
                mail.To.Add(addr);
            }
        }
        //メールアドレス(Cc)
        if (argCc != null) {
            foreach (string addr in argCc) {
                mail.CC.Add(addr);
            }
        }
        //メールアドレス(Bcc)
        if (argBcc != null) {
            foreach (string addr in argBcc) {
                mail.Bcc.Add(addr);
            }
        }
        
        //優先度
        // 高い:System.Net.Mail.MailPriority.High
        // 普通:System.Net.Mail.MailPriority.Normal
        // 低い:System.Net.Mail.MailPriority.Low
        mail.Priority = argPriority;
        //件名を設定
        mail.Subject = argSubject;
        //本文を設定
        mail.Body = argBody;
        //本文をHTML形式にするかどうか
        mail.IsBodyHtml = argIsHtml;
        //添付ファイル
        if (argFile != null) {
            foreach (FileInfo f in argFile) {
                mail.Attachments.Add(
                    new System.Net.Mail.Attachment(f.FullName));
            }
        }
        //エンコード(件名)
        //例:shift_jis、iso-2022-jp
        mail.SubjectEncoding = Encoding.GetEncoding(argSubEnc);
        //エンコード(本文)
        mail.BodyEncoding = Encoding.GetEncoding(argBodyEnc);
        
        //メールを送信
        sClient.Send(mail);
    }
    finally {
        mail.Dispose();
    }
}
[C#]メールを送信するサンプル
補足
本サンプルは、送信元メールアドレスをYahooメールで確認しています。(2008.12.29現在)
Yahooメールで確認するには、
『Yahooメールを他のメーラーで送受信できるようにする』必要があります。
Yahooメールの『POPアクセスとメール転送』で、『ブラウザアクセスとPOPアクセス』に設定して下さい。
あとは、
ユーザ名:YahooID
パスワード:YahooIDのパスワード
SMTPサーバ:『smtp.mail.yahoo.co.jp』
SMTPのポート番号:『587』
でメールを送信できます。

[.NET]関数(y=f(x))のグラフをImageに描画する [Programming .NET Tips]

[ポイント]
・関数(y=f(x))の呼び出しは、デリゲート経由で行います。
 これにより、描画メソッド(DrawFunctionメソッド)を変更することなく、
 関数(y=f(x))を切替えることができます。
・非関数(xとyが1対1に対応していない)には対応していません。
 例えば、x2+y2=r2のような円を表すグラフは描画できません。
・Graphics.DrawLineメソッドで、一つ前の座標との直線を描画している為、
 連続していない関数(離散型)では一部正しく描画されないことがあります。
 例えば、y=tan(x)の場合、x=π/2で縦線が描画されます。
コードのコピー
''' <summary>
''' 関数(y=f(x))のデリゲート
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Delegate Function FuncHandler(ByVal x As IntegerAs Integer

''' <summary>
''' 関数(y=f(x))のグラフをイメージに描画する。
''' </summary>
''' <param name="targetImage">描画対象のイメージ</param>
''' <param name="fnc">関数(y=f(x))</param>
''' <param name="xFrom">X座標の最小値</param>
''' <param name="xTo">X座標の最大値</param>
''' <remarks></remarks>
Public Shared Sub DrawFunction( _
    ByVal targetImage As Image, ByVal fnc As FuncHandler, _
    ByVal xFrom As IntegerByVal xTo As Integer)

    Dim g As Graphics = Nothing

    Try
        g = Graphics.FromImage(targetImage)

        '描画領域を初期化(白で塗りつぶす)
        g.FillRectangle(Brushes.White, 0, 0, _
            targetImage.Width, targetImage.Height)

        '描画領域の原点を中央に移動
        Dim xMax As Integer = targetImage.Width * 0.5
        Dim xMin As Integer = -1 * xMax
        Dim yMax As Integer = targetImage.Height * 0.5
        Dim yMin As Integer = -1 * yMax
        g.TranslateTransform(xMax, yMax)
        '描画領域のY座標の向きを逆にする(Y座標の上方向をプラスにする)
        g.ScaleTransform(1, -1)

        '格子を描画する(水平線)
        For y As Single = 0 To yMax Step 10
            g.DrawLine(Pens.Cyan, xMin, y, xMax, y)
        Next
        For y As Single = 0 To yMin Step -10
            g.DrawLine(Pens.Cyan, xMin, y, xMax, y)
        Next

        '格子を描画する(垂直線)
        For x As Single = 0 To xMax Step 10
            g.DrawLine(Pens.Cyan, x, yMin, x, yMax)
        Next
        For x As Single = 0 To xMin Step -10
            g.DrawLine(Pens.Cyan, x, yMin, x, yMax)
        Next

        'X軸を描画
        g.DrawLine(Pens.Blue, xMin, 0, xMax, 0)
        'Y軸を描画
        g.DrawLine(Pens.Blue, 0, yMin, 0, yMax)

        '関数のグラフを描画
        For x As Integer = xFrom To xTo
            Try
                g.DrawLine( _
                    Pens.Black, x - 1, _
                    fnc.Invoke(x - 1), x, fnc.Invoke(x))
            Catch ex As ArithmeticException
                'ゼロ除算、数値演算のオーバーフロー、
                '定義されていない演算エラーは無視する
            End Try
        Next
    Finally
        If Not (g Is NothingThen
            g.Dispose()
        End If
    End Try
End Sub
[VB.NET]関数のグラフをImageに描画する例

(1)PictureBoxに、一次関数(y=2x)のグラフを描画する例
・上記で定義したメソッド(DrawFunction)の使用例を以下に示します。
 まずは、一次関数(y=2x)を定義します。
コードのコピー
''' <summary>
''' 関数(一次関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return x * 2
End Function
[VB.NET]例:一次関数の定義

・適当なイベント処理内で、DrawFunctionメソッドを呼ぶ処理を記述します。
 DrawFunctionメソッドに渡す引数は、
 ・グラフを描画するImageインスタンス
 ・一次関数(y=2x)のデリゲート (※デリゲートとはメソッドの参照を格納する変数、型です。)
 ・X座標の範囲(From、To)
 です。
 [デリゲートについて]
  .NETでは、メソッドの参照を変数に格納し、変数経由でメソッドに
  アクセスすることができます。 (デリゲート変数)
  この例では、一次関数の定義をデリゲート変数に格納し、DrawFunctionメソッドに渡します。
  メソッドの参照はAddressOf演算子で取得します。
  デリゲート変数はFuncHandler型で定義し、fnc1と関連付けします。
コードのコピー
Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
    Dim img As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)

    '関数の参照をデリゲート変数に格納する
    '※関数を変更する場合は、デリゲート変数の中身を変更する。
    Dim f As New FuncHandler(AddressOf Me.fnc1)
    '関数のグラフを描画する。
    DrawFunction(img, f, img.Width * -0.5, img.Width * 0.5)

    Me.PictureBox1.Image = img
End Sub
[VB.NET]DrawFunctionメソッドの呼び出し
実行結果
一次関数

(2)PictureBoxに、二次関数のグラフを描画する例
・デリゲート変数の内容を、二次関数のデリゲートに置き換えるだけで、描画内容を変更できます。
コードのコピー
''' <summary>
''' 関数(二次関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 0.05 * (x - 10) * (x + 50)
End Function
[VB.NET]関数を二次関数で定義した場合
実行結果
関数を二次関数で定義した場合
(3)PictureBoxに、三角関数のグラフを描画する例
・同様に三角関数も描画可能です。
コードのコピー
''' <summary>
''' 関数(三角関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 50 * Math.Sin(x / 15)
End Function
[VB.NET]関数を三角関数で定義した場合
実行結果
関数を三角関数で定義した場合
(4)PictureBoxに、平方根の関数のグラフを描画する例
・平方根の関数も同様です。
コードのコピー
''' <summary>
''' 関数(平方根)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 10 * Math.Sqrt(x)
End Function
[VB.NET]関数を平方根で定義した場合
実行結果
関数を平方根で定義した場合

[.NET]Imageの分割 [Programming .NET Tips]

ファイルから取り込んだImageを複数に分割する機会があったので、
作ってみました。

[ポイント]
(1)Imageオブジェクトを指定した個数で分割します。
   例:縦5個、横10個と指定すると、5×10の2次元配列でImageを作成します。
(2)Imageを分割するには、
   Graphics.DrawImage(Image, Integer, Integer, Rectangle, GraphicsUnit)
   を使います。
(3)参考文献
   『MSDN Library for VisualStudio2008日本語版』

[ソース]
コードのコピー
''' <summary>
''' 指定したImageを分割する。
''' </summary>
''' <param name="originalImage">オリジナルImage</param>
''' <param name="verticalNum">分割数(垂直)</param>
''' <param name="horizontalNum">分割数(水平)</param>
''' <returns>分割済Image</returns>
''' <remarks></remarks>
Public Shared Function DivideImage( _
    ByVal originalImage As Image, _
    ByVal verticalNum As IntegerByVal horizontalNum As Integer _
    ) As Image()()

    '引数チェック
    If originalImage Is Nothing Then
        Throw New ArgumentNullException("originalImage is null")
    End If

    If verticalNum < 1 Then
        Throw New ArgumentOutOfRangeException("verticalNum < 1")
    End If

    If horizontalNum < 1 Then
        Throw New ArgumentOutOfRangeException("horizontalNum < 1")
    End If

    Dim g As Graphics = Nothing

    Dim rtnImage()() As Image = New Image(verticalNum - 1)() {}
    For i As Integer = 0 To verticalNum - 1
        rtnImage(i) = New Image(horizontalNum - 1) {}
    Next

    Dim originalSize As Size = originalImage.Size
    Dim divWidth As Integer = originalSize.Width / horizontalNum
    Dim divHeight As Integer = originalSize.Height / verticalNum

    For vCnt As Integer = 0 To verticalNum - 1
        For hCnt As Integer = 0 To horizontalNum - 1
            Try
                '空のImageを作成
                rtnImage(vCnt)(hCnt) = New Bitmap(divWidth, divHeight)
                'Imageを描画する為のGraphicsオブジェクトを作成
                g = System.Drawing.Graphics.FromImage( _
                       rtnImage(vCnt)(hCnt))
                'オリジナルImageから描画対象の領域を算出
                '[補足]
                '   領域の開始座標を
                '   ・hCnt * divWidth
                '   ・vCnt * divHeight
                '   ではなく、
                '   ・hCnt * originalSize.Width / horizontalNum
                '   ・vCnt * originalSize.Height / verticalNum
                '   にしているのは、誤差を軽減する為です。
                Dim rect As New Rectangle( _
                    hCnt * originalSize.Width / horizontalNum, _
                    vCnt * originalSize.Height / verticalNum, _
                    divWidth, _
                    divHeight _
                    )
                'オリジナルImageの内容を描画
                g.DrawImage( _
                     originalImage, 0, 0, rect, GraphicsUnit.Pixel)
            Finally
                If Not (g Is NothingThen
                    'Graphicsオブジェクトを解放
                    g.Dispose()
                End If
            End Try
        Next
    Next

    Return rtnImage
End Function
[VB.NET]Imageを分割する例


コードのコピー
/// <summary>
/// 指定したImageを分割する。
/// </summary>
/// <param name="originalImage">オリジナルImage</param>
/// <param name="verticalNum">分割数(垂直)</param>
/// <param name="horizontalNum">分割数(水平)</param>
/// <returns>分割済Image</returns>
/// <remarks></remarks>
public static Image[][] DivideImage(
    Image originalImage, int verticalNum, int horizontalNum)
{
    
    //引数チェック
    if (originalImage == null) {
        throw new ArgumentNullException("originalImage is null");
    }
    
    if (verticalNum < 1) {
        throw new ArgumentOutOfRangeException("verticalNum < 1");
    }
    
    if (horizontalNum < 1) {
        throw new ArgumentOutOfRangeException("horizontalNum < 1");
    }
    
    Graphics g = null;
    
    Image[][] rtnImage = new Image[verticalNum][];
    for (int i = 0; i <= verticalNum - 1; i++) {
        rtnImage(i) = new Image[horizontalNum];
    }
    
    Size originalSize = originalImage.Size;
    int divWidth = originalSize.Width / horizontalNum;
    int divHeight = originalSize.Height / verticalNum;
    
    for (int vCnt = 0; vCnt < verticalNum ; vCnt++) {
        for (int hCnt = 0; hCnt < horizontalNum ; hCnt++) {
            try {
                //空のImageを作成
                rtnImage(vCnt)(hCnt) = new Bitmap(divWidth, divHeight);
                //Imageを描画する為のGraphicsオブジェクトを作成
                g = System.Drawing.Graphics.FromImage(
                    rtnImage(vCnt)(hCnt));
                //オリジナルImageから描画対象の領域を算出
                //[補足]
                // 領域の開始座標を
                // ・hCnt * divWidth
                // ・vCnt * divHeight
                // ではなく、
                // ・hCnt * originalSize.Width / horizontalNum
                // ・vCnt * originalSize.Height / verticalNum
                // にしているのは、誤差を軽減する為です。
                Rectangle rect = new Rectangle(
                     hCnt * originalSize.Width / horizontalNum, 
                     vCnt * originalSize.Height / verticalNum, 
                     divWidth, divHeight);
                //オリジナルImageの内容を描画
                g.DrawImage(
                    originalImage, 0, 0, 
                    rect, GraphicsUnit.Pixel);
            }
            finally {
                if (g != null) {
                    //Graphicsオブジェクトを解放
                    g.Dispose();
                }
            }
        }
    }
    
    return rtnImage;
}
[C#]Imageを分割する例

Programming .NET Tips ブログトップ
メッセージを送る

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。