.NETで文字列を連結すると効率が悪いといわれています。
例えばこんな具合です。
Dim str As String str = "雨にも負けず" str = str & "風にも負けず" & vbCrLf str = str & "雪にも夏の暑さにも負けぬ" & vbCrLf str = str & "丈夫なからだをもち" & vbCrLf str = str & "慾はなく" & vbCrLf str = str & "決して怒らず" & vbCrLf str = str & "いつも静かに笑っている" & vbCrLf
マイクロソフトでは、StringBuilderを使うように推奨しています。
(ただし、文字列が決まっていればStringの連結が勝っているようです。)
そこでStringBuilderを自分の都合に合わせてを改良したいと思います。
StringBuilderが継承できれば楽なのですが、StringBuilderは継承できませんので、StringBuilderを要素にもつ独自のStringBuilderを作成しました。
主要な部分は次のとおりです。
Public Class MyStringBuilder Private m_sb As StringBuilder .... Public Sub Append(ByVal strIn As String, Optional ByVal blnReset As Boolean = False) If blnReset Then Reset() m_sb.Append(strIn) End Sub Public Sub AppendFormat(ByVal strFormat As String, ByVal ParamArray args() As Object) m_sb.AppendFormat(strFormat, args) End Sub ..... Public Function Conc(ByVal strAdd As String, Optional ByVal blnReset As Boolean = False) If blnReset Then Reset() m_sb.Append(strAdd) m_sb.Append(ControlChars.CrLf) End Function Public Function ConcFormat(ByVal strFormat As String, ByVal ParamArray args() As Object) m_sb.AppendFormat(strFormat, args) m_sb.Append(ControlChars.CrLf) End Function
Appendは機能的にはStgringBuilderと同じです。
Concは次のようにメッセージの作成等改行を入れたいとき使います。先の例では、
Dim MySB As New MyStingBuilder With MySB .Conc("雨にも負けず") .Conc("風にも負けず") .Conc("雪にも夏の暑さにも負けぬ") .Conc("丈夫なからだをもち") .Conc("慾はなく") .Conc("決して怒らず") .ConcFormat("{0}{1}{2}", "いつも", "静かに", "笑っている") End With MessageBox.Show(MySB.ToString, "MyStringBuilder", )
読みやすくなっていると思いませんか。
SQLでは改行を入れるといけません。プロパーのStringBuilderのAppendでいいのですが、一貫して[MyStringBuilder]を使いたいので[MyStringBuilder]用のAppendを定義しています。次のように使います。
Dim MySB As New MyStingBuilder With MySB .Append("Select * From 書籍") .AppendFormat(" Where 著者名='{0}'", "司馬 遼太郎") .AppendFormat(" And 出版日 Between '{0}' And {1}", _ New Date(1990, 1, 1), New Date(1996, 2, 1)) End With
連続する二つの句の間にスペースが必要なので、実際にはスペースを入れるようなメソッドを用意しています。
ところで、ここには誤りがあります。
最後の文の{1}プレースホルダをクォートする必要があります。
日付リテラルはSQL Serverではシングルクォートで、Accessでは#で囲む必要があります。
私は、ディレクティブを使ってラッパー関数を用意しています。
Public Function DateWrapper(ByVal dte As Date) As String #If DB = "SQLServer" Then Return (String.Format("'{0}'", dte.ToShortDateString)) #ElseIf DB = "Access" Return (String.Format("#{0}#", dte.ToShortDateString)) #Else .... #End If End Function[DateWrapper]を通せば、DBに何を使っているかその都度気にする必要はありません。
従って先の例は次の通りです。
.AppendFormat(" And 出版日 Between {0} And {1}", _ DateWrapper(New Date(1990, 1, 1)), DateWrapper(New Date(1996, 2, 1)))