パラメータクエリーを使用しOracleのDateTime型フィールドにDbNullをInsertまたはUpdateすると「リテラル文字が一致しません」と失敗する場合があります。
なぜだろうとググってみると・・・自分のブログがヒットした・・・
OracleのフィールドにDbNull.Valueを登録する際の注意
かなりの時間を無駄にした(ヽ´ω`)ゲッソリ
.NET 定数ファイルを作成する~その2~
今回はWeekDayクラス、WeekDayHasNoneクラス、WeekDayHasNotSunクラスに
インスタンス化せずにCDから名前を検索できるメソッドを追加します。
前回、作成したコードをまとめるとこんな感じです。
簡単に思いついたのは各クラスに下記のようなコードを追加していくことでした。
・・・これじゃぁダメだよね(;´∀`)
次に思いついたのはList<Of T>のFindメソッドで探すことです。
Findメソッドの使い方は以下のようなコードになります。
これが結構面倒なんですよね。
そこでList(Of T)を継承したConstListクラスを作成し、Find(Cd)メソッドを追加します。
ついでに名前から検索するFind(Name)も作っておきます。
Findメソッドで実際に検索するFilterクラスを作成します。
ConstItemクラスの修正はありません。
定数ファイルのCreateListメソッドを修正し、ConstListクラスを返すようにします。
使い方
難点はCdから定数アイテムを検索する際にCreateList経由でしかできない事です。
一応これで要件はすべて満たしたのでOKとします。
インスタンス化せずにCDから名前を検索できるメソッドを追加します。
前回、作成したコードをまとめるとこんな感じです。
NameSpace Constant Public Class ConstItem Private _Cd As Integer Private _Name As String Private _AliasName As String Private Sub New End Sub Public Sub New(cd As Integer, name As String) Me._Cd = cd Me._Name = name Me._AliasName = String.Empty End Sub Public Sub New(cd As Integer, name As String, aliasName As String) Me._Cd = cd Me._Name = name Me._AliasName = aliasName End Sub Public ReadOnly Property Cd() As Integer Get Return Me._Cd End Get End Property Public ReadOnly Property Name() As String Get Return Me._Name End Get End Property Public ReadOnly Property AliasName() As String Get Return Me._AliasName End Get End Property End Class End NameSpace
NameSpace Constant Public Class WeekDay Public Shared ReadOnly SUN As New ConstItem(1, "日曜日","日") Public Shared ReadOnly MON As New ConstItem(2, "月曜日","月") Public Shared ReadOnly TUE As New ConstItem(3, "火曜日","火") Public Shared ReadOnly WED As New ConstItem(4, "水曜日","水") Public Shared ReadOnly THR As New ConstItem(5, "木曜日","木") Public Shared ReadOnly FRI As New ConstItem(6, "金曜日","金") Public Shared ReadOnly SAT As New ConstItem(7, "土曜日","土") Public Shared Function CreateList As List(Of ConstItem) Dim list As New List(Of ConstItem) list.Add(SUN) list.Add(MON) list.Add(TUE) list.Add(WED) list.Add(THR) list.Add(FRI) list.Add(SAT) Return list End Function End Class Public Class WeekDayHasNone Inherits WeekDay Public Shared ReadOnly NONE As New ConstItem(0, "なし") Public Shared Shadows Function CreateList As List(Of ConstItem) Dim list As List(Of ConstItem) list = WeekDay.CreateList list.InsertAt(0,NONE) Return list End Function End Class Public Class WeekDayHasNotSun Inherits WeekDay Private Shared Shadows ReadOnly SUN As New ConstItem(1, "日曜日","日") Public Shared Shadows Function CreateList As List(Of ConstItem) Dim list As List(Of ConstItem) list = WeekDay.CreateList list.RemoveAt(WeekDay.SUN) Return list End Function End Class End NameSpace
簡単に思いついたのは各クラスに下記のようなコードを追加していくことでした。
Public Shared Function Find(ByVal cd As Integer) As ConstItem Dim item As ConstItem = Nothing Dim list As List(Of ConstItem) = 各クラス名.CreateList For idx As Integer = 0 To list.Count - 1 If list.Item(idx).Cd = cd Then item = list.Item(idx) Continue For End If Next Return item End Function
・・・これじゃぁダメだよね(;´∀`)
次に思いついたのはList<Of T>のFindメソッドで探すことです。
Findメソッドの使い方は以下のようなコードになります。
これが結構面倒なんですよね。
Public Class Test Private _SearchCd As Integer Public Sub Test() Dim list As New List(Of KeyValuePair(Of Integer, String)) list.Add(New KeyValuePair(Of Integer, String)(1, "日曜日")) list.Add(New KeyValuePair(Of Integer, String)(2, "月曜日")) list.Add(New KeyValuePair(Of Integer, String)(3, "火曜日")) 'CD=2を検索 Me._SearchCd = 2 Dim findItem As KeyValuePair(Of Integer, String) = list.Find(AddressOf IsMatch) If IsNothing(findItem) Then Console.WriteLine("該当データなし") Else Console.WriteLine("Key:{0},Value:{1},", findItem.Key, findItem.Value) End If End Sub Private Function IsMatch(ByVal item As KeyValuePair(Of Integer, String)) As Boolean Return item.Key = Me._SearchCd End Function End Class
そこでList(Of T)を継承したConstListクラスを作成し、Find(Cd)メソッドを追加します。
ついでに名前から検索するFind(Name)も作っておきます。
Namespace Constant ''' <summary> ''' 定数アイテムのリストを管理するクラスです。 ''' </summary> ''' <remarks></remarks> Public Class ConstList Inherits List(Of ConstItem) ''' <summary> ''' CDに該当する最初のConstItemを取得します。 ''' </summary> ''' <param name="cd"></param> ''' <returns></returns> ''' <remarks></remarks> Public Overloads Function Find(ByVal cd As Integer) As ConstItem Dim filter As New ConstItemFilter(Of Integer) filter.FilterValue = cd Return Me.Find(AddressOf filter.IsMatchCd) End Function ''' <summary> ''' Nameに該当する最初のConstItemを取得します。 ''' </summary> ''' <param name="name"></param> ''' <returns></returns> ''' <remarks></remarks> Public Overloads Function Find(ByVal name As String) As ConstItem Dim filter As New ConstItemFilter(Of String) filter.FilterValue = name Return Me.Find(AddressOf filter.IsMatchName) End Function End Class End Namespace
Findメソッドで実際に検索するFilterクラスを作成します。
Namespace Constant ''' <summary> ''' 定数リストより定数アイテムを検索するためのFilterクラスです。 ''' </summary> ''' <remarks></remarks> Public Class ConstItemFilter(Of TValue) ''' <summary>検索する値です</summary> Private _FilterValue As TValue ''' <summary>デフォルトコンストラクタ</summary> Public Sub New() End Sub ''' <summary>コンストラクタ</summary> ''' <param name="filterValue">検索する値</param> Public Sub New(ByVal filterValue As TValue) Me.New() Me._FilterValue = filterValue End Sub ''' <summary>検索する値を取得および設定します。</summary> Public Property FilterValue() As TValue Get Return _FilterValue End Get Set(ByVal value As TValue) _FilterValue = value End Set End Property ''' <summary>引数に指定した定数アイテムのCDと検索値が一致するかを取得します。</summary> ''' <param name="item">定数アイテム</param> ''' <returns>一致する場合はTrue。それ以外はFalse。</returns> Public Function IsMatchCd(ByVal item As ConstItem) As Boolean If (Me._FilterValue Is Nothing) Then Return False Return (Me._FilterValue.Equals(item.Cd)) End Function ''' <summary>引数に指定した定数アイテムのNameと検索値が一致するかを取得します。</summary> ''' <returns>一致する場合はTrue。それ以外はFalse。</returns> Public Function IsMatchName(ByVal item As ConstItem) As Boolean If (Me._FilterValue Is Nothing) Then Return False Return (Me._FilterValue.Equals(item.Name)) End Function End Class End Namespace
ConstItemクラスの修正はありません。
Namespace Constant ''' <summary> ''' 定数アイテムクラスです。 ''' </summary> ''' <remarks></remarks> Public Class ConstItem ''' <summary>コードです</summary> Private _Cd As Integer ''' <summary>名前です</summary> Private _Name As String ''' <summary>別名です</summary> Private _AliasName As String ''' <summary>デフォルトコンストラクタ</summary> Private Sub New() End Sub ''' <summary>コンストラクタ</summary> ''' <param name="cd">コード</param> ''' <param name="name">名前</param> Public Sub New(ByVal cd As Integer, ByVal name As String) Me._Cd = cd Me._Name = name Me._AliasName = String.Empty End Sub ''' <summary>コンストラクタ</summary> ''' <param name="cd">コード</param> ''' <param name="name">名前</param> ''' <param name="aliasName">別名</param> Public Sub New(ByVal cd As Integer, ByVal name As String, ByVal aliasName As String) Me._Cd = cd Me._Name = name Me._AliasName = aliasName End Sub ''' <summary>コードを取得します。</summary> Public ReadOnly Property Cd() As Integer Get Return Me._Cd End Get End Property ''' <summary>名前を取得します。</summary> Public ReadOnly Property Name() As String Get Return Me._Name End Get End Property ''' <summary>別名を取得します。</summary> Public ReadOnly Property AliasName() As String Get Return Me._AliasName End Get End Property End Class End Namespace
定数ファイルのCreateListメソッドを修正し、ConstListクラスを返すようにします。
Namespace Constant ''' <summary> ''' 曜日リストです。 ''' </summary> ''' <remarks></remarks> Public Class WeekDay Public Shared ReadOnly SUN As New ConstItem(1, "日曜日", "日") Public Shared ReadOnly MON As New ConstItem(2, "月曜日", "月") Public Shared ReadOnly TUE As New ConstItem(3, "火曜日", "火") Public Shared ReadOnly WED As New ConstItem(4, "水曜日", "水") Public Shared ReadOnly THR As New ConstItem(5, "木曜日", "木") Public Shared ReadOnly FRI As New ConstItem(6, "金曜日", "金") Public Shared ReadOnly SAT As New ConstItem(7, "土曜日", "土") Public Shared Function CreateList() As ConstList Dim list As New ConstList list.Add(SUN) list.Add(MON) list.Add(TUE) list.Add(WED) list.Add(THR) list.Add(FRI) list.Add(SAT) Return list End Function End Class ''' <summary> ''' なしを保有する曜日リストです。 ''' </summary> ''' <remarks></remarks> Public Class WeekDayHasNone Inherits WeekDay Public Shared ReadOnly NONE As New ConstItem(0, "なし") Public Shared Shadows Function CreateList() As ConstList Dim list As ConstList list = WeekDay.CreateList list.Insert(0, NONE) Return list End Function End Class ''' <summary> ''' 日曜日を保有しない曜日リストです。 ''' </summary> ''' <remarks></remarks> Public Class WeekDayHasNotSun Inherits WeekDay Private Shared Shadows ReadOnly SUN As New ConstItem(1, "日曜日", "日") Public Shared Shadows Function CreateList() As ConstList Dim list As ConstList list = WeekDay.CreateList list.Remove(WeekDay.SUN) Return list End Function End Class End Namespace
使い方
'名前を取得します。 Console.WriteLine(Constant.WeekDay.SUN.Name) '別名を取得します。 Console.WriteLine(Constant.WeekDay.SUN.AliasName) 'コンボボックスに設定します。 ComboBox1.ValueMember = "Cd" ComboBox1.DisplayMember = "Name" '別名の場合 'ComboBox1.DisplayMember = "AliasName" ComboBox1.DataSource = Constant.WeekDay.CreateList 'CD=1に該当する定数アイテムを取得します。 Dim findCd As Integer = 1 Dim findItem As ConstItem = WeekDay.CreateList.Find(findCd) If IsNothing(findItem) Then Console.WriteLine("Cd={0}に該当するアイテムはありません。",findCd) Else Console.WriteLine("Cd:{0},Name:{1},Name:{2}",findItem.Cd, findItem.Name, findItem.AliasName") End If 'Name="木曜日"に該当する定数アイテムを取得します。 Dim findName As String = "木曜日" Dim findItem As ConstItem = WeekDay.CreateList.Find(findName) If IsNothing(findItem) Then Console.WriteLine("Name={0}に該当するアイテムはありません。",findName) Else Console.WriteLine("Cd:{0},Name:{1},Name:{2}",findItem.Cd, findItem.Name, findItem.AliasName") End If
難点はCdから定数アイテムを検索する際にCreateList経由でしかできない事です。
一応これで要件はすべて満たしたのでOKとします。
.NET 定数ファイルを作成する~その1~
定数ファイル「Constant」に「曜日」に関する定数を作ったとします。
こんな感じでしょうか。
この定数ファイル「Constant」にどんどん定数を作っていくと、
Constantoのインテリセンスから定数を探すのが大変です。
そこでグループ化したいと考えて、簡単に列挙体にしました。
よくある事ですが
SUNを指定したとき「1」を取得したい場合と「日曜日」を取得したい場合があると思います。
そこで列挙体をクラスに変え、KeyValuePairで値と名前をセットで宣言するようにしました。
使うときはConstant.WeekDay.SUN.Keyで「1」を取得し、Constant.WeekDay.SUN.Valueで「日曜日」を取得します。
ところが
SUNを指定したとき「日曜日」とは別に「日」を取得したい場合が出てきました。
そこで値「1」と名前「日曜日」と別名「日」をセットで管理するクラスを作成します。
これで「Sunday」や「Sun」など別名がふえても、プロパティを追加すれば大丈夫です。
使うときはConstant.WeekDay.SUN.Cdで「1」を取得し、Constant.WeekDay.SUN.Nameで「日曜日」を取得し、Constant.WeekDay.SUN.AliasNameで「日」を取得します。
今度はこの定数をコンボボックスのリストアイテムにセットしたい場面が出てきました。
その都度リストを作るのが面倒とのことで、WeekDayクラスにリストを作るメソッドを用意します。
※インスタンス化せずに使える事が前提です。
コンボボックスにWeekDayリスト設定するときは以下のようにします。
ComboBox1.ValueMember = "Cd"
ComboBox1.DisplayMember = "Name"
’別名の場合
'ComboBox1.DisplayMember = "AliasName"
ComboBox1.DataSource = Constant.WeekDay.CreateList
ところがWeekDayクラスにNone[0]を追加してほしい。しかしNone[0]がないWeekDayもそのまま使いたいとの要望がありました。
仕方がないのでWeekDayクラスを継承してWeekDayHasNoneクラスを作成しました。
さらにWeekDayクラスからSUN[1]を削除したものが欲しい。しかしSUN[1]があるWeekDayもそのまま使いたいとの要望がありました。
WeekDayクラスを継承してWeekDayHasNotSunクラスを作成しました。
CDから名前を検索できるメソッドがあればいいよね(もちろんインスタンス化せずに)との要望。←今ココ
・・・どうするかなぁ
こんな感じでしょうか。
Public Class Constant Public Const SUN As Integer = 1 Public Const MON As Integer = 2 Public Const TUE As Integer = 3 Public Const WED As Integer = 4 Public Const THR As Integer = 5 Public Const FRI As Integer = 6 Public Const SAT As Integer = 7 End Class
この定数ファイル「Constant」にどんどん定数を作っていくと、
Constantoのインテリセンスから定数を探すのが大変です。
そこでグループ化したいと考えて、簡単に列挙体にしました。
Public Class Constant Public Enum WeekDay SUN = 1 MON = 2 TUE = 3 WED = 4 THR = 5 FRI = 6 SAT = 7 End Enum End Class
よくある事ですが
SUNを指定したとき「1」を取得したい場合と「日曜日」を取得したい場合があると思います。
そこで列挙体をクラスに変え、KeyValuePairで値と名前をセットで宣言するようにしました。
使うときはConstant.WeekDay.SUN.Keyで「1」を取得し、Constant.WeekDay.SUN.Valueで「日曜日」を取得します。
Namespace Constant Public Class WeekDay Public Shared ReadOnly SUN As New KeyValuePair(Of Integer, String)(1, "日曜日") Public Shared ReadOnly MON As New KeyValuePair(Of Integer, String)(2, "月曜日") Public Shared ReadOnly TUE As New KeyValuePair(Of Integer, String)(3, "火曜日") Public Shared ReadOnly WED As New KeyValuePair(Of Integer, String)(4, "水曜日") Public Shared ReadOnly THR As New KeyValuePair(Of Integer, String)(5, "木曜日") Public Shared ReadOnly FRI As New KeyValuePair(Of Integer, String)(6, "金曜日") Public Shared ReadOnly SAT As New KeyValuePair(Of Integer, String)(7, "土曜日") End Class End Namespace
ところが
SUNを指定したとき「日曜日」とは別に「日」を取得したい場合が出てきました。
そこで値「1」と名前「日曜日」と別名「日」をセットで管理するクラスを作成します。
これで「Sunday」や「Sun」など別名がふえても、プロパティを追加すれば大丈夫です。
NameSpace Constant Public Class ConstItem Private _Cd As Integer Private _Name As String Private _AliasName As String Private Sub New End Sub Public Sub New(cd As Integer, name As String) Me._Cd = cd Me._Name = name Me._AliasName = String.Empty End Sub Public Sub New(cd As Integer, name As String, aliasName As String) Me._Cd = cd Me._Name = name Me._AliasName = aliasName End Sub Public ReadOnly Property Cd() As Integer Get Return Me._Cd End Get End Property Public ReadOnly Property Name() As String Get Return Me._Name End Get End Property Public ReadOnly Property AliasName() As String Get Return Me._AliasName End Get End Property End Class End NameSpace
NameSpace Constant Public Class WeekDay Public Shared ReadOnly SUN As New ConstItem(1, "日曜日","日") Public Shared ReadOnly MON As New ConstItem(2, "月曜日","月") Public Shared ReadOnly TUE As New ConstItem(3, "火曜日","火") Public Shared ReadOnly WED As New ConstItem(4, "水曜日","水") Public Shared ReadOnly THR As New ConstItem(5, "木曜日","木") Public Shared ReadOnly FRI As New ConstItem(6, "金曜日","金") Public Shared ReadOnly SAT As New ConstItem(7, "土曜日","土") End Class End NameSpace
使うときはConstant.WeekDay.SUN.Cdで「1」を取得し、Constant.WeekDay.SUN.Nameで「日曜日」を取得し、Constant.WeekDay.SUN.AliasNameで「日」を取得します。
今度はこの定数をコンボボックスのリストアイテムにセットしたい場面が出てきました。
その都度リストを作るのが面倒とのことで、WeekDayクラスにリストを作るメソッドを用意します。
※インスタンス化せずに使える事が前提です。
NameSpace Constant Public Class WeekDay Public Shared ReadOnly SUN As New ConstItem(1, "日曜日","日") Public Shared ReadOnly MON As New ConstItem(2, "月曜日","月") Public Shared ReadOnly TUE As New ConstItem(3, "火曜日","火") Public Shared ReadOnly WED As New ConstItem(4, "水曜日","水") Public Shared ReadOnly THR As New ConstItem(5, "木曜日","木") Public Shared ReadOnly FRI As New ConstItem(6, "金曜日","金") Public Shared ReadOnly SAT As New ConstItem(7, "土曜日","土") Public Shared Function CreateList As List(Of ConstItem) Dim list As New List(Of ConstItem) list.Add(SUN) list.Add(MON) list.Add(TUE) list.Add(WED) list.Add(THR) list.Add(FRI) list.Add(SAT) Return list End Function End Class End NameSpace
コンボボックスにWeekDayリスト設定するときは以下のようにします。
ComboBox1.ValueMember = "Cd"
ComboBox1.DisplayMember = "Name"
’別名の場合
'ComboBox1.DisplayMember = "AliasName"
ComboBox1.DataSource = Constant.WeekDay.CreateList
ところがWeekDayクラスにNone[0]を追加してほしい。しかしNone[0]がないWeekDayもそのまま使いたいとの要望がありました。
仕方がないのでWeekDayクラスを継承してWeekDayHasNoneクラスを作成しました。
NameSpace Constant Public Class WeekDayHasNone Inherits WeekDay Public Shared ReadOnly NONE As New ConstItem(0, "なし") Public Shared Shadows Function CreateList As List(Of ConstItem) Dim list As List(Of ConstItem) list = WeekDay.CreateList list.InsertAt(0,NONE) Return list End Function End Class End NameSpace
さらにWeekDayクラスからSUN[1]を削除したものが欲しい。しかしSUN[1]があるWeekDayもそのまま使いたいとの要望がありました。
WeekDayクラスを継承してWeekDayHasNotSunクラスを作成しました。
NameSpace Constant Public Class WeekDayHasNotSun Inherits WeekDay Private Shared Shadows ReadOnly SUN As New ConstItem(1, "日曜日","日") Public Shared Shadows Function CreateList As List(Of ConstItem) Dim list As List(Of ConstItem) list = WeekDay.CreateList list.RemoveAt(WeekDay.SUN) Return list End Function End Class End NameSpace
CDから名前を検索できるメソッドがあればいいよね(もちろんインスタンス化せずに)との要望。←今ココ
・・・どうするかなぁ
登録:
投稿 (Atom)
-
DataTableから重複を除くには と DataTableの集約計算を行う(Compute) を利用して、DataTableをグループ化し集計を行います。 以下のようなデータが入ったDataTableから、Field1とField2で重複を取り除き集計をおこないます。...
-
前回「 PLSQL SELECTの結果を取得する ~取得結果が1行の場合~ 」に続き 今回はSELECTの結果が複数行の場合です。 SELECTの結果が複数行の場合はカーソルを使用します。 カーソルとは SELECTの結果セットに対して、1行ずつデータを取り出し、順次...
-
datatableの集約計算を行うにはDataTable.Compute メソッドを使用します。 Dim As Object '最大値を求める value = datatable.Compute("Max(集計列名)", Nothing) ...