質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

14575閲覧

NULLの処理

yyy

総合スコア49

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2016/08/02 11:05

編集2016/08/04 00:29

VB.NETでDataGridViewにMDBファイルをバインドし、編集後にその内容をMDBファイル(元データ)に反映するプログラムを作成しています。

上記の内容が通るコードを書けるようになったのですが、今度はNULLの置換処理が必要なようで、困っています。

NULLに対して以下のような変換をしたい。
数値型→NULL
文字型→String.Empty(0文字列)
チェックボックス→FALSE

また、置換の書き方もよくわかっていないので教えていただけると嬉しいです。
使用言語はVB.NETです。

列の型を調べて、置換の際に型指定が必要なようなのですが、そちらもやり方が出来ていません。
なんとなくでも言いたいことがわかる、という方がいらっしゃいましたら教えてください。

よろしく願いします。

###追記

Imports Microsoft.VisualBasic.ControlChars Imports System.Data.OleDb Public Class Form1 Private Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\コピー.mdb") Private SQLCm As OleDbCommand = Cn.CreateCommand Private Adapter As New OleDbDataAdapter(SQLCm) Private Table As New DataTable 'Loadイベント Private Sub form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load '自分で定義した列しかバインドしない DataGridView1.AutoGenerateColumns = False SQLCm.CommandText = "SELECT a, b, c, d, e, f, g, h, IDNo FROM tblL WHERE DELFLG <> TRUE" Dim cb As New System.Data.OleDb.OleDbCommandBuilder() Adapter.Fill(Table) '▼値の表示 DataGridView1.DataSource = Table End Sub '削除 Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click MessageBox.Show("選択したデータを削除してもよろしいですか", "加工ラベル印刷", MessageBoxButtons.YesNo, MessageBoxIcon.Question) Dim i As Integer If Windows.Forms.DialogResult.Yes Then For i = DataGridView1.Rows.Count - 1 To 0 Step -1 If DataGridView1("a", i).Value = True Then DataGridView1.Rows.RemoveAt(i) End If Next End If End Sub '全選択 Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim i As Integer For i = 0 To DataGridView1.Rows.Count - 1 DataGridView1("a", i).Value = True Next End Sub '全解除 Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Dim i As Integer For i = 0 To DataGridView1.Rows.Count - 1 DataGridView1("a", i).Value = False Next End Sub '閉じる Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click Close() End Sub Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed Dim SQLCm As OleDbCommand = Cn.CreateCommand Dim Table As DataTable = DirectCast(DataGridView1.DataSource, DataTable) For Each Row As DataRow In Table.Rows Dim SQL As String = "" '●SQL文の生成 Select Case Row.RowState Case DataRowState.Added '▼追加されたレコード SQL = "INSERT INTO tblL ( " SQL &= "a" & ", " SQL &= "b" & ", " SQL &= "c" & ", " SQL &= "d" & ", " SQL &= "e" & ", " SQL &= "f" & ", " SQL &= "g" & ", " SQL &= "h" & ") " SQL &= "VALUES" & " (" SQL &= Row("a") & "," SQL &= "'" & Row("b") & "', " SQL &= "'" & Row("c") & "', " SQL &= "'" & Row("d") & "', " SQL &= "'" & Row("e") & "', " SQL &= "'" & Row("f") & "', " SQL &= "'" & Row("g") & "', " SQL &= Row("h") SQL &= ")" '▼削除されたレコード Case DataRowState.Deleted SQL = "DELETE FROM tblL WHERE " SQL &= " IDNo = " & Row("IDNo", DataRowVersion.Original) '▼更新されたレコード Case DataRowState.Modified SQL = "UPDATE tblL SET" SQL &= " a = " & Row("a") & ", " SQL &= "b = '" & Row("b") & "', " SQL &= "c = '" & Row("c") & "', " SQL &= "d = '" & Row("d") & "', " SQL &= "e = '" & Row("e") & "', " SQL &= "f = '" & Row("f") & "', " SQL &= "g = '" & Row("g") & "', " SQL &= "h = " & Row("h") SQL &= " WHERE " SQL &= "IDNo = " & Row("IDNo", DataRowVersion.Original) Case Else Continue For End Select '●更新実行 SQLCm.CommandText = SQL Cn.Open() SQLCm.ExecuteNonQuery() Cn.Close() Next '▼後処理 Table.Dispose() Adapter.Dispose() SQLCm.Dispose() Cn.Dispose()

上記が作成コードです。
Form1のLoadイベントでMDBファイルの取込、展開をしています。
Buttonイベントなどももっと上に書いてあるのですが、最終的にClosedイベントが発生したらデータ反映がされるように想定しています。

その際に、今後何か変更があってもすぐに対応ができるようにVB.NET上でNULLの置換処理をしたいと考えています。

見え方としては
数値がNULLの場合→ブランク
文字列がNULLの場合→ブランク
チェックボックスがNULLの場合→FALSE
というようにしたいと考えています。

これが自分のやりたいことを詳しく説明できているかはちょっとわからないのですが、動作としては上記のようにしたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

データ取得時のNULLをなんとかしたいということならば、
アプローチとしては以下の2点かなと。

  1. データ取得時にSQL(データベース側)でNULLが混入しないようにする

(Nz関数とかIIfとか利用すると良さ気ですよ。2013以降だとAccessでもCoalesce関数が使えるそう)

  1. 取得後にプログラム側でNULLを変換・エスケープする

質問者さんは後者で考えておられるようですが、
前者のアプローチを取ると受け取る側のPGの手直しは不要なのかな思います。

蛇足ですが、.NETの数値型でNullを表したいというのであれば、
Null許容型がというのがサポートされています。

確かVB.NETだと下記の感じで定義したはず…

VB

1Dim a As Nullable(Of Integer) 2Dim b As Integer?

上記のようにすると、
Null(VBだとNothing)を扱うことのできる整数型(Integerなど)を定義することができます。
詳しくは以下をどうぞ。
Null許容型

投稿2016/08/02 13:11

Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Mr_Roboto

2016/08/02 13:16

やばい、KotoriMaturiさんの前にデータベースの回答をするなんて (恥 w
Panzer_vor

2016/08/02 13:41

まだまだSQLに定期的にハマるレベルなんですがそれはw SQLの表現力はすごく魅力的なんですが、拘り過ぎるとすぐ迷宮入りするのが玉に瑕ですね^^;
yyy

2016/08/03 01:49

はい、KotoriMaturiさんが仰る通り 取得後にプログラム側でNULLを変換・エスケープする という処理をしたいと考えています(そのように依頼されておりまして…)。 回答内容を見るに、前者の方が使い勝手がよさそうですね…。 後者で作業することを考えると、データ反映のタイミングでNULL置換を行うと思っていいのでしょうか? 正直、どこでその処理をするべきかもよくわかっていません。
Panzer_vor

2016/08/03 03:13 編集

ソースコードの掲載がないので予測になりますが、 仮にDataGridViewの各項目にDBから取った値を設定するようPG側(VB)でコーディングしているのであれば、そのタイミングで置換処理を挟むと良いです。 ただバインドと記載してるので、DBから取得した結果セットをDataSourceで設定してるのかな…。 その場合はDataSourceに指定しているもの(DataTableなどの各項目値)に対して変換処理が必要となります。
Panzer_vor

2016/08/05 19:52

ソース追記していただいてたのですね、すみません見落としてました。 NULLの問題についてはもう解消しましたでしょうか? 後蛇足ですが文字列連結を何度も繰り返す場合は、 組み立てたSQLのソース整形などで行ごとの末尾に改行を入れたい場合などは、 StringBuilderクラスが便利です。 末尾に改行を入れる場合はAppendLineメソッドを利用します。 詳しくは以下URLよりどうぞ https://msdn.microsoft.com/ja-jp/library/system.text.stringbuilder(v=vs.110).aspx 
yyy

2016/08/08 01:16 編集

遅くなりまして申し訳ありません。 コード追記後ご連絡ができないままになってしまいました。すみません・・。 色々とお教えいただき、ありがとうございます。 結局、NULLの置換処理はFunctionで関数を作り、引数で判断(If文・Select文)することにしました。(以下、NULL処理と更新処理コード) Public Function Type(ByVal RowValue As Object, ByVal RowType As String) As Object If IsDBNull(RowValue) Then Select Case RowType Case "String" Return (String.Empty) Case Else Return ("NULL") End Select Else Return (RowValue) End If End Function Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed Dim SQLCm As OleDbCommand = Cn.CreateCommand Dim Table As DataTable = DirectCast(DataGridView1.DataSource, DataTable) For Each Row As DataRow In Table.Rows Dim SQL As String = "" '●SQL文の生成 Select Case Row.RowState '▼更新されたレコード Case DataRowState.Modified SQL = "UPDATE tblL SET " SQL &= "SELFLG = " & Type(Row("a"), "String") & ", " SQL &= "SYOHCD = '" & Type(Row("b"), "String") & "', " SQL &= "SYOHMEI1 = '" & Type(Row("c"), "String") & "', " SQL &= "SYOHMEI2 = '" & Type(Row("d"), "String") & "', " SQL &= "SYOHMEI3 = '" & Type(Row("e"), "String") & "', " SQL &= "IRISU = '" & Type(Row("f"), "String") & "', " SQL &= "IRISUTAN = '" & Type(Row("g"), "String") & "', " SQL &= "SURYO = " & Type(Row("h"), "Integer") SQL &= " WHERE " SQL &= "IDNo = " & Row("IDNo", DataRowVersion.Original) Case Else Continue For End Select ありがとうございました。
guest

0

取得する時にSQL書いているなら関数で変換すればいけますね。
AccessのクエリでNVL(NULL置換)

でもバインドしてるってことは、そうじゃないのかな?

NULLに関してDBでは特別な処理が必要なことが多くてハマりどころです。(IS NULLとか)

今書いているコードなり、もう少しやりたいことを具体的に書くと適切な回答が得られると思いますよ。

投稿2016/08/02 12:21

Mr_Roboto

総合スコア2208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyy

2016/08/03 01:36

回答ありがとうございます。 情報追加いたしました。 修正のしやすさを考え、VB.NET上でNULL置換処理をしてしまいたいと考えています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問