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

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

ただいまの
回答率

87.91%

NULLの処理

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 9,659

score 45

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
というようにしたいと考えています。

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

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

  1. データ取得時にSQL(データベース側)でNULLが混入しないようにする
    (Nz関数とかIIfとか利用すると良さ気ですよ。2013以降だとAccessでもCoalesce関数が使えるそう)

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

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

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/03 12:12 編集

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

    その場合はDataSourceに指定しているもの(DataTableなどの各項目値)に対して変換処理が必要となります。

    キャンセル

  • 2016/08/06 04:52

    ソース追記していただいてたのですね、すみません見落としてました。
    NULLの問題についてはもう解消しましたでしょうか?

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

    キャンセル

  • 2016/08/08 10:13 編集

    遅くなりまして申し訳ありません。
    コード追記後ご連絡ができないままになってしまいました。すみません・・。

    色々とお教えいただき、ありがとうございます。
    結局、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

    ありがとうございました。

    キャンセル

0

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/03 10:36

    回答ありがとうございます。

    情報追加いたしました。
    修正のしやすさを考え、VB.NET上でNULL置換処理をしてしまいたいと考えています。

    キャンセル

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

  • ただいまの回答率 87.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る