none
オブジェクト参照がオブジェクト インスタンスに設定されていません。への対応 in vb.net RRS feed

  • 質問

  • vb.netで自作のトレインビジョンを作成しています。1つのCSVファイルから統合した2つのプロジェクトを動かすプログラムを作成しているのですが、下から193行目のg.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom)で「オブジェクト参照がオブジェクト インスタンスに設定されていません。」というエラーが出てしまい困っています。どう対処すればいいのかを教えてください。(エラーが出た部分は太字で表示させてあります)急いでいますのでコードを提示しつつお願いします。

    問題のvb.netのコード

    Imports System.Drawing '図形や線を描画できる基本的なグラフィックス機能を追加
    Imports System.Drawing.Drawing2D '上記コードの2 次元高度な機能

    Public Class Form1
        Private con()() As Control
        Private change As Integer
        Dim canvas As Bitmap 'canvas を画像とその属性のピクセルデータを扱うクラスBitmapで宣言する
        Dim g As Graphics 'g を描画クラスGraphicsで宣言する
        Dim colower As Brush = Brushes.Red 'colowerを四角形、楕円、扇形、多角形を塗りつぶすクラスBrushで宣言して同時に塗りつぶしておく最初の色を赤に設定する
        Dim fnt As Font 'fntをテキストの特定の書式を定義するクラスFontで宣言する。
        Dim line As Integer = 4 'cを整数型Integerで宣言してそれと同時に4を代入する
        Public ix1 As Long = 0 'ローカル変数ixをintの倍の8バイトに当たるlong型で宣言をしてそれと同時に0を代入する。
        Public ix2 As Long = 0
        Public ix3 As Long = 0
        Public msg1() As String = {"다음 것", "次は", "つぎは", "Next", "下一个"} 'ローカル変数msgを文字列型の配列入りで宣言をしてそれと同時に表示させたい文字列を代入する。
        Public msg2() As String = {"에대한", "行き", "ゆき", "for", "为"}
        Public msg3() As String = {"자동차", "号車", "Cars", "汽车"}
        Dim scloltext As String
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            con = New Control()() {
            New Control() {TextBox5},
            New Control() {PictureBox1}}
            change = 0
            For m As Integer = 0 To con.Length - 1
                con(m).ToList().ForEach(Sub(x) x.Visible = False)
                If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)

            Next


        End Sub
        Private Sub Button1_Click(ByVal sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim objFile1 As New System.IO.StreamReader("Z:\traindata\東海道・山陽新幹線.csv", System.Text.Encoding.GetEncoding("shift_jis"))
            'ファイルを指定して読み込むためのオブジェクト
            Dim strLine1 As String  'ファイルから読み取った全駅名の文字列を格納する
            Dim strTemp1() As String 'strLine1からデータを受け取り、配列にする
            Dim strData1 As String  'strTemp1の配列したデータを受け取る
            Dim Lineno1 As Integer  'CSVファイルから読み込みたい列の値を格納する
            Dim linesta As Integer  'aを整数型で宣言をしてそれと同時にstrTempの配列を指定して、文字の最大値を返す。
            Dim objFile2 As New System.IO.StreamReader("Z:\traindata\種別等.csv", System.Text.Encoding.GetEncoding("shift_jis"))
            'ファイルを指定して読み込むためのオブジェクト
            Dim strLine2 As String  'ファイルから読み取った全駅名の文字列を格納する
            Dim strTemp2() As String 'strLine2からデータを受け取り、配列にする
            Dim strData2 As String  'strTemp2の配列したデータを受け取る
            Dim Lineno2 As Integer  'CSVファイルから読み込みたい列の値を格納する
            Dim station1 As Integer  'CSVファイルから読み込みたい複数の行の値を格納する
            Dim stationlist As String 'strTemp2とstationのファイルから読み込んだ文字列を受け取
            Lineno1 = 1 'CSVファイルから読み込みたい列を指定する
            strLine1 = objFile1.ReadLine() 'objFile1に1行分の文字を読み込んで配列にして、strLine1に格納する
            While (strLine1 <> "") 'strlineが空白""と等しくない限り処理を続ける
                strTemp1 = Split(strLine1, ",") 'strLine1とカンマで区切られたファイルの文字列から配列を作成してstrtemp1に格納する
                For intCnt = 0 To UBound(strTemp1) 'カウンタintcatが0からstrtemp1の添字の最大値以下(csvファイルに入力された終着駅の行番号)である間,処理を繰り返し行う
                    strData1 = strData1 + strTemp1(intCnt) 'strData1にstrTemp1の配列カウンタintcatとstrData1を足して代入する
                Next
                If Lineno1 = 2 Then 'Lineno1に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
                    TextBox1.Text = strTemp1(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(種別を示すTextBox1の内容)
                    TextBox2.Text = strTemp1(2) '(行き先を示すTextBox2の内容)
                    Label1.Text = strTemp1(1) '(列車番号を示すLabel1の内容)
                ElseIf Lineno1 = 1 Then 'Lineno1に1行目の列を指定して読み込む
                    TextBox3.Text = strTemp1(8) '(次駅を示すTextBox3の内容)
                ElseIf Lineno1 = 65 Then 'Lineno1にCSVファイル上の65行目(この場合、のぞみ2号東京行きの6:08分)の列を指定して読み込む。
                    Label5.Text = strTemp1(8) '(時刻を示すLabel5の内容)

                End If
                ' csvファイルを閉じる
                strLine1 = objFile1.ReadLine() 'objFileを読み込んで配列にしてstrLineに格納する
                Lineno1 = Lineno1 + 1 ' Lineno と 1を足してLinenoに代入する

            End While


            strLine2 = objFile2.ReadLine() 'objFile2に1行分の文字を読み込んで、strLine2に格納する
            While (strLine2 <> "") 'strline2が空白""と等しくない限り処理を続ける
                strTemp2 = Split(strLine2, ",") 'strLine2とカンマで区切られたファイルの文字列から配列を作成してstrtemp2に格納する
                For intCnt = 0 To UBound(strTemp2) 'カウンタintcatが0からstrtemp2の添字の最大値以下である間,処理を繰り返し行う
                    strData2 = strData2 + strTemp2(intCnt) 'strData2にstrTemp1の配列カウンタintcatとstrData2を足して代入する
                Next
                If Lineno2 = 2 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
                    TextBox4.Text = strTemp2(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(号車を示すTextBox4の内容)

                ElseIf Lineno2 = 1 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から1列目を指定して読み込む
                    stationlist = "" ' stationlistの文字列をリセットして空欄にする
                    For station1 = 4 To 38 '複数の駅名の行を指定してstationに格納する
                        stationlist = stationlist + strTemp2(station1) 'stationに格納されている指定された駅名の文字列をstationlistで呼び出す。
                    Next

                    stationlist = "停車駅は" + stationlist + "です" '呼び出された駅名の文字列を文章にして表示させる。
                    TextBox5.Text = stationlist  'TextBox5にstationlistを代入する

                End If
                If Lineno2 = 4 Then 'Linenoに4を代入する

                    Exit While

                End If
                strLine2 = objFile2.ReadLine() 'strLine2にobjFile2の配列を読み込む
                Lineno2 = Lineno2 + 1 'Lineno2にLineno2と1を足して代入する
            End While

            linesta = UBound(strTemp2)
                fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
                station2(strTemp2(line), -110) 'stationに配列strTempに配列c, と座標-110を配列にして挿入する
                If line + 1 <= linesta Then 'aはc+1より大きければ上記と同じ配列strTempに配列c+1, と座標0をstationに挿入して1つ目の駅名を出す。以降iに足す数字を1増やしながら処理をする。
                    station2(strTemp2(line + 1), 0) '2つ目の駅名を出す。
                End If
                If line + 2 <= linesta Then
                    station2(strTemp2(line + 2), 100) '3つ目の駅名を出す。
                End If
                If line + 3 <= linesta Then
                    station2(strTemp2(line + 3), 200) '4つ目の駅名を出す。
                End If
                If line + 4 <= linesta Then
                    station2(strTemp2(line + 4), 300) '5つ目の駅名を出す。
                End If
                If line + 5 <= linesta Then
                    station2(strTemp2(line + 5), 400) '6つ目の駅名を出す。
                End If
                If line < linesta Then 'aはc以上に大きければcと1を足してcに代入して駅名をボタンを押すごとにずらす
                    line = line + 1
                End If

                ix1 = ix1 + 1
            If ix1 > UBound(msg1) Then
                ix1 = 0
            End If
            Label2.Text = msg1(ix1)

            ix2 = ix2 + 1
            If ix2 > UBound(msg2) Then
                ix2 = 0
            End If
            Label4.Text = msg2(ix2)

            ix3 = ix3 + 1
            If ix3 > UBound(msg3) Then
                ix3 = 0
            End If
            Label3.Text = msg3(ix3)

            change += 1
            change = IIf(change = con.Length, 0, change)
            For m As Integer = 0 To con.Length - 1

                con(m).ToList().ForEach(Sub(x) x.Visible = False)
                If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)
            Next

            objFile1.Close() 'ファイルを閉じる
            objFile2.Close() 'ファイルを閉じる
            Timer1.Interval = 5 'タイマーの時間を設定する
            Timer1.Start() 'タイマーを開始する

        End Sub
        Private Sub station2(stationname As String, pointer As Integer) 'stationイベントを作成して、横の括弧の中にstationnameは文字列型で、pointerは整数型で宣言をして文字を書くところとそれを表示する場所を作る。

            Dim n As Integer = stationname.Length 'n を整数型で宣言をしてそれと同時に文字数属性のstationnameを代入する。
            Dim m As String = "" 'm を文字列型で宣言をしてそれと同時に空白を代入する。
            For i = 0 To n - 1 'i が 0 からn – 1の間で繰り返し処理を行う
                m = m & stationname.Substring(i, 1) 'mにmと駅名とi文字目を追加する。
            Next
            Dim stfom As New StringFormat() 'stfomを文字列の書式を設定する方法を指定できるオブジェクトStringFormatで宣言をして配列を初期化する
            stfom.FormatFlags = StringFormatFlags.DirectionVertical 'テキスト文字列を縦方向位置合わせして、stfomに書式情報を格納する
            fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
            g.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom) 'g に宣言しておいたmとfnt、 pointer、 stfomそして 、描画する色を黒にして座標を110に設定して文字列を描画する

        End Sub

        Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
            'ファイルを指定して読み込むためのオブジェクト
            canvas = New Bitmap(PictureBox1.Width, PictureBox1.Height) 'canvas に初期化して高さと幅を設定したピクチャーボックスを格納する。
            g = Graphics.FromImage(canvas) 'canvas配列化して、クラスのGraphicsに画像や図形を指定してgに格納する。
            g.FillRectangle(Brushes.Orange, 10, 20, 700, 80) '座標を決めて塗りつぶしたオレンジ色の長方形を描画する(塗りたい色,x座標,y座標,幅,高さ)
            g.FillEllipse(Brushes.White, 70, 25, 70, 70) '座標をそれぞれ決めて塗りつぶした白い円を6個描画する
            g.FillEllipse(Brushes.White, 170, 25, 70, 70)
            g.FillEllipse(Brushes.White, 270, 25, 70, 70)
            g.FillEllipse(Brushes.White, 370, 25, 70, 70)
            g.FillEllipse(Brushes.White, 470, 25, 70, 70)
            g.FillEllipse(Brushes.White, 570, 25, 70, 70)
            Dim points As Point() = {New Point(710, 100), '三角形を描画する座標を決める
                         New Point(710, 20),
                         New Point(790, 60)}
            '多角形を描画する
            g.FillPolygon(Brushes.Orange, points, FillMode.Alternate) '塗りつぶす色をオレンジに設定する
            g.TranslateTransform(190, 0) 'gに座標を 190, 0に指定してオブジェクトを変換する。
            ' Dim point As Point() = {New Point(-180, 100),
            ' New Point(-180, 20),
            'New Point(-130, 60)}
            '多角形を描画する


            PictureBox1.Image = canvas 'ピクチャーボックスにcanvasを代入する。
            Timer2.Interval = 500 'タイマーの時間を設定する
            Timer2.Start() 'タイマーを開始する
        End Sub

        Private Sub Timer1_Tick(ByVal sender As Object, e As EventArgs) Handles Timer1.Tick

            Dim objG As Graphics '描画した文字列を格納する

            objG = TextBox5.CreateGraphics() 'textbox5に画像を挿入する
            objG.Clear(TextBox5.BackColor) 'objGの描画サーフェイス全体をリセットしてtextbox5の背景色で塗りつぶす
            objG.DrawString(TextBox5.Text, TextBox5.Font, New SolidBrush(TextBox5.ForeColor), scloltext, 0) 'textbox5に描画する文字列やフォントや色えお設定する
            scloltext -= 1 '文字列が移動する方向を決める
            If scloltext > TextBox5.Width Then 'scloltextがtextboxの幅よりも大きい場合以下の処理を実行する
                scloltext = 0 'scloltextに0を代入する
            End If
            objG.Dispose() 'objGを開放する
        End Sub
        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            g.TranslateTransform(0, 0) 'gに0, 0を座標にオブジェクトを変換する
            Dim points As Point() = {New Point(-180, 100), '三角形を描画する
            New Point(-180, 20),
           New Point(-130, 60)}
            g.FillPolygon(colower, points, FillMode.Alternate) 'gにcolowerを挿入して、閉じたパスの内部を塗りつぶす方法を指定できる列挙型FillModeとそのメンバーで代替の塗りつぶしモードを指定できるAlternateをそれぞれ挿入する。
            If colower.Equals(Brushes.Red) Then '今の色が指定した色と等しい場合は違う色に変えるという処理を行う
                colower = Brushes.Yellow '等しい場合に塗りつぶす色を黄色に変更
            Else
                colower = Brushes.Red 'そうでない場合は塗りつぶす色を黄色に変更
            End If
            Me.Refresh() 'コードが実行されているクラスまたは構造体のクライアント領域を強制的に無効化し、直後にそのコントロール自体とその子コントロールを再描画するようにして配列にする.


        End Sub


    End Class


    • 編集済み dumbo1028 2017年12月1日 1:28
    2017年11月27日 5:23

すべての返信

  • C# のフォーラムに投稿されてますが、それは間違いで、VB.NET ですよね?

    例外の原因は g が null(VB.NET では Nothing)になっているからであろうと思いますが、長いコードをベタっと貼られてその中から g が null になる原因、対処方法を見つけてくれというのは、ちょっと期待しすぎかと。

    問題を再現できる必要最低限までコードをどんどん削っていくなどして、切り分けしていただけませんか。その過程で原因が分かって自己解決できるかもしれません。自己解決できなくても、必要最低限まで削ったコードをアップしてもらえれば、詳しく見てくれる人も増えて回答が得やすくなると思います。

    ところで、質問者さんが先に立てたスレッドが放置状態です。

    「インデックスが配列の境界外です。」の対処法
    https://social.msdn.microsoft.com/Forums/sqlserver/ja-JP/0a2cf69f-73cd-4d51-a1d3-441503e8c226?forum=vbgeneralja

    一つもレスが付かないということならともかく、レスをもらっているなら放置はマナー違反です。きちんと対応してください。


    • 編集済み SurferOnWww 2017年11月27日 6:08 追記
    2017年11月27日 5:45
  • SurferOnWwwさんが仰られている通り、gがnullになっていることが原因だと思います。

    > 「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
    上記メッセージからSystem.NullReferenceExceptionが発生していることがわかります。
    該当行でブレークし、各値を確認すれば原因についてはすぐにわかるかと思います。

    > どう対処すればよいか教えてください
    どのように呼ばれても意図したGraphicオブジェトを参照出来るように修正してください。

    以下、余計なお世話ですが。。。
    ご質問者様の二つの質問どちらも、エラーが発生して困っていますとなっていますが、
    単純なエラーですので、調べればすぐに原因は特定出来るものと思います。
    今後もプログラムをされていくのであれば、すぐにフォーラムで質問するのではなく、
    ご自身で解決する方法も学ばれたほうがよいと思います。

    • 編集済み uemu 2017年11月27日 6:24
    2017年11月27日 6:22
  • 自分の投稿に投票することはできません                    
    0
                

    vb.netで自作のトレインビジョンを作成しています。1つのCSVファイルから統合した2つのプロジェクトを動かすプログラムを作成しているのですが、下から193行目のg.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom)で「オブジェクト参照がオブジェクト インスタンスに設定されていません。」というエラーが出てしまい困っています。どう対処すればいいのかを教えてください。(エラーが出た部分は太字で表示させてあります)急いでいますのでコードを提示しつつお願いします。

    問題のvb.netのコード

    Imports System.Drawing '図形や線を描画できる基本的なグラフィックス機能を追加
    Imports System.Drawing.Drawing2D '上記コードの2 次元高度な機能

    Public Class Form1
        Private con()() As Control
        Private change As Integer
        Dim canvas As Bitmap 'canvas を画像とその属性のピクセルデータを扱うクラスBitmapで宣言する
        Dim g As Graphics 'g を描画クラスGraphicsで宣言する
        Dim colower As Brush = Brushes.Red 'colowerを四角形、楕円、扇形、多角形を塗りつぶすクラスBrushで宣言して同時に塗りつぶしておく最初の色を赤に設定する
        Dim fnt As Font 'fntをテキストの特定の書式を定義するクラスFontで宣言する。
        Dim line As Integer = 4 'cを整数型Integerで宣言してそれと同時に4を代入する
        Public ix1 As Long = 0 'ローカル変数ixをintの倍の8バイトに当たるlong型で宣言をしてそれと同時に0を代入する。
        Public ix2 As Long = 0
        Public ix3 As Long = 0
        Public msg1() As String = {"다음 것", "次は", "つぎは", "Next", "下一个"} 'ローカル変数msgを文字列型の配列入りで宣言をしてそれと同時に表示させたい文字列を代入する。
        Public msg2() As String = {"에대한", "行き", "ゆき", "for", "为"}
        Public msg3() As String = {"자동차", "号車", "Cars", "汽车"}
        Dim scloltext As String
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            con = New Control()() {
            New Control() {TextBox5},
            New Control() {PictureBox1}}
            change = 0
            For m As Integer = 0 To con.Length - 1
                con(m).ToList().ForEach(Sub(x) x.Visible = False)
                If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)

            Next


        End Sub
        Private Sub Button1_Click(ByVal sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim objFile1 As New System.IO.StreamReader("Z:\traindata\東海道・山陽新幹線.csv", System.Text.Encoding.GetEncoding("shift_jis"))
            'ファイルを指定して読み込むためのオブジェクト
            Dim strLine1 As String  'ファイルから読み取った全駅名の文字列を格納する
            Dim strTemp1() As String 'strLine1からデータを受け取り、配列にする
            Dim strData1 As String  'strTemp1の配列したデータを受け取る
            Dim Lineno1 As Integer  'CSVファイルから読み込みたい列の値を格納する
            Dim linesta As Integer  'aを整数型で宣言をしてそれと同時にstrTempの配列を指定して、文字の最大値を返す。
            Dim objFile2 As New System.IO.StreamReader("Z:\traindata\種別等.csv", System.Text.Encoding.GetEncoding("shift_jis"))
            'ファイルを指定して読み込むためのオブジェクト
            Dim strLine2 As String  'ファイルから読み取った全駅名の文字列を格納する
            Dim strTemp2() As String 'strLine2からデータを受け取り、配列にする
            Dim strData2 As String  'strTemp2の配列したデータを受け取る
            Dim Lineno2 As Integer  'CSVファイルから読み込みたい列の値を格納する
            Dim station1 As Integer  'CSVファイルから読み込みたい複数の行の値を格納する
            Dim stationlist As String 'strTemp2とstationのファイルから読み込んだ文字列を受け取
            Lineno1 = 1 'CSVファイルから読み込みたい列を指定する
            strLine1 = objFile1.ReadLine() 'objFile1に1行分の文字を読み込んで配列にして、strLine1に格納する
            While (strLine1 <> "") 'strlineが空白""と等しくない限り処理を続ける
                strTemp1 = Split(strLine1, ",") 'strLine1とカンマで区切られたファイルの文字列から配列を作成してstrtemp1に格納する
                For intCnt = 0 To UBound(strTemp1) 'カウンタintcatが0からstrtemp1の添字の最大値以下(csvファイルに入力された終着駅の行番号)である間,処理を繰り返し行う
                    strData1 = strData1 + strTemp1(intCnt) 'strData1にstrTemp1の配列カウンタintcatとstrData1を足して代入する
                Next
                If Lineno1 = 2 Then 'Lineno1に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
                    TextBox1.Text = strTemp1(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(種別を示すTextBox1の内容)
                    TextBox2.Text = strTemp1(2) '(行き先を示すTextBox2の内容)
                    Label1.Text = strTemp1(1) '(列車番号を示すLabel1の内容)
                ElseIf Lineno1 = 1 Then 'Lineno1に1行目の列を指定して読み込む
                    TextBox3.Text = strTemp1(8) '(次駅を示すTextBox3の内容)
                ElseIf Lineno1 = 65 Then 'Lineno1にCSVファイル上の65行目(この場合、のぞみ2号東京行きの6:08分)の列を指定して読み込む。
                    Label5.Text = strTemp1(8) '(時刻を示すLabel5の内容)

                End If
                ' csvファイルを閉じる
                strLine1 = objFile1.ReadLine() 'objFileを読み込んで配列にしてstrLineに格納する
                Lineno1 = Lineno1 + 1 ' Lineno と 1を足してLinenoに代入する

            End While


            strLine2 = objFile2.ReadLine() 'objFile2に1行分の文字を読み込んで、strLine2に格納する
            While (strLine2 <> "") 'strline2が空白""と等しくない限り処理を続ける
                strTemp2 = Split(strLine2, ",") 'strLine2とカンマで区切られたファイルの文字列から配列を作成してstrtemp2に格納する
                For intCnt = 0 To UBound(strTemp2) 'カウンタintcatが0からstrtemp2の添字の最大値以下である間,処理を繰り返し行う
                    strData2 = strData2 + strTemp2(intCnt) 'strData2にstrTemp1の配列カウンタintcatとstrData2を足して代入する
                Next
                If Lineno2 = 2 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
                    TextBox4.Text = strTemp2(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(号車を示すTextBox4の内容)

                ElseIf Lineno2 = 1 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から1列目を指定して読み込む
                    stationlist = "" ' stationlistの文字列をリセットして空欄にする
                    For station1 = 4 To 38 '複数の駅名の行を指定してstationに格納する
                        stationlist = stationlist + strTemp2(station1) 'stationに格納されている指定された駅名の文字列をstationlistで呼び出す。
                    Next

                    stationlist = "停車駅は" + stationlist + "です" '呼び出された駅名の文字列を文章にして表示させる。
                    TextBox5.Text = stationlist  'TextBox5にstationlistを代入する

                End If
                If Lineno2 = 4 Then 'Linenoに4を代入する

                    Exit While

                End If
                strLine2 = objFile2.ReadLine() 'strLine2にobjFile2の配列を読み込む
                Lineno2 = Lineno2 + 1 'Lineno2にLineno2と1を足して代入する
            End While

            linesta = UBound(strTemp2)
                fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
                station2(strTemp2(line), -110) 'stationに配列strTempに配列c, と座標-110を配列にして挿入する
                If line + 1 <= linesta Then 'aはc+1より大きければ上記と同じ配列strTempに配列c+1, と座標0をstationに挿入して1つ目の駅名を出す。以降iに足す数字を1増やしながら処理をする。
                    station2(strTemp2(line + 1), 0) '2つ目の駅名を出す。
                End If
                If line + 2 <= linesta Then
                    station2(strTemp2(line + 2), 100) '3つ目の駅名を出す。
                End If
                If line + 3 <= linesta Then
                    station2(strTemp2(line + 3), 200) '4つ目の駅名を出す。
                End If
                If line + 4 <= linesta Then
                    station2(strTemp2(line + 4), 300) '5つ目の駅名を出す。
                End If
                If line + 5 <= linesta Then
                    station2(strTemp2(line + 5), 400) '6つ目の駅名を出す。
                End If
                If line < linesta Then 'aはc以上に大きければcと1を足してcに代入して駅名をボタンを押すごとにずらす
                    line = line + 1
                End If

                ix1 = ix1 + 1
            If ix1 > UBound(msg1) Then
                ix1 = 0
            End If
            Label2.Text = msg1(ix1)

            ix2 = ix2 + 1
            If ix2 > UBound(msg2) Then
                ix2 = 0
            End If
            Label4.Text = msg2(ix2)

            ix3 = ix3 + 1
            If ix3 > UBound(msg3) Then
                ix3 = 0
            End If
            Label3.Text = msg3(ix3)

            change += 1
            change = IIf(change = con.Length, 0, change)
            For m As Integer = 0 To con.Length - 1

                con(m).ToList().ForEach(Sub(x) x.Visible = False)
                If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)
            Next

            objFile1.Close() 'ファイルを閉じる
            objFile2.Close() 'ファイルを閉じる
            Timer1.Interval = 5 'タイマーの時間を設定する
            Timer1.Start() 'タイマーを開始する

        End Sub
        Private Sub station2(stationname As String, pointer As Integer) 'stationイベントを作成して、横の括弧の中にstationnameは文字列型で、pointerは整数型で宣言をして文字を書くところとそれを表示する場所を作る。

            Dim n As Integer = stationname.Length 'n を整数型で宣言をしてそれと同時に文字数属性のstationnameを代入する。
            Dim m As String = "" 'm を文字列型で宣言をしてそれと同時に空白を代入する。
            For i = 0 To n - 1 'i が 0 からn – 1の間で繰り返し処理を行う
                m = m & stationname.Substring(i, 1) 'mにmと駅名とi文字目を追加する。
            Next
            Dim stfom As New StringFormat() 'stfomを文字列の書式を設定する方法を指定できるオブジェクトStringFormatで宣言をして配列を初期化する
            stfom.FormatFlags = StringFormatFlags.DirectionVertical 'テキスト文字列を縦方向位置合わせして、stfomに書式情報を格納する
            fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
            g.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom) 'g に宣言しておいたmとfnt、 pointer、 stfomそして 、描画する色を黒にして座標を110に設定して文字列を描画する

        End Sub

        Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
            'ファイルを指定して読み込むためのオブジェクト
            canvas = New Bitmap(PictureBox1.Width, PictureBox1.Height) 'canvas に初期化して高さと幅を設定したピクチャーボックスを格納する。
            g = Graphics.FromImage(canvas) 'canvas配列化して、クラスのGraphicsに画像や図形を指定してgに格納する。
            g.FillRectangle(Brushes.Orange, 10, 20, 700, 80) '座標を決めて塗りつぶしたオレンジ色の長方形を描画する(塗りたい色,x座標,y座標,幅,高さ)
            g.FillEllipse(Brushes.White, 70, 25, 70, 70) '座標をそれぞれ決めて塗りつぶした白い円を6個描画する
            g.FillEllipse(Brushes.White, 170, 25, 70, 70)
            g.FillEllipse(Brushes.White, 270, 25, 70, 70)
            g.FillEllipse(Brushes.White, 370, 25, 70, 70)
            g.FillEllipse(Brushes.White, 470, 25, 70, 70)
            g.FillEllipse(Brushes.White, 570, 25, 70, 70)
            Dim points As Point() = {New Point(710, 100), '三角形を描画する座標を決める
                         New Point(710, 20),
                         New Point(790, 60)}
            '多角形を描画する
            g.FillPolygon(Brushes.Orange, points, FillMode.Alternate) '塗りつぶす色をオレンジに設定する
            g.TranslateTransform(190, 0) 'gに座標を 190, 0に指定してオブジェクトを変換する。
            ' Dim point As Point() = {New Point(-180, 100),
            ' New Point(-180, 20),
            'New Point(-130, 60)}
            '多角形を描画する


            PictureBox1.Image = canvas 'ピクチャーボックスにcanvasを代入する。
            Timer2.Interval = 500 'タイマーの時間を設定する
            Timer2.Start() 'タイマーを開始する
        End Sub

        Private Sub Timer1_Tick(ByVal sender As Object, e As EventArgs) Handles Timer1.Tick

            Dim objG As Graphics '描画した文字列を格納する

            objG = TextBox5.CreateGraphics() 'textbox5に画像を挿入する
            objG.Clear(TextBox5.BackColor) 'objGの描画サーフェイス全体をリセットしてtextbox5の背景色で塗りつぶす
            objG.DrawString(TextBox5.Text, TextBox5.Font, New SolidBrush(TextBox5.ForeColor), scloltext, 0) 'textbox5に描画する文字列やフォントや色えお設定する
            scloltext -= 1 '文字列が移動する方向を決める
            If scloltext > TextBox5.Width Then 'scloltextがtextboxの幅よりも大きい場合以下の処理を実行する
                scloltext = 0 'scloltextに0を代入する
            End If
            objG.Dispose() 'objGを開放する
        End Sub
        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            g.TranslateTransform(0, 0) 'gに0, 0を座標にオブジェクトを変換する
            Dim points As Point() = {New Point(-180, 100), '三角形を描画する
            New Point(-180, 20),
           New Point(-130, 60)}
            g.FillPolygon(colower, points, FillMode.Alternate) 'gにcolowerを挿入して、閉じたパスの内部を塗りつぶす方法を指定できる列挙型FillModeとそのメンバーで代替の塗りつぶしモードを指定できるAlternateをそれぞれ挿入する。
            If colower.Equals(Brushes.Red) Then '今の色が指定した色と等しい場合は違う色に変えるという処理を行う
                colower = Brushes.Yellow '等しい場合に塗りつぶす色を黄色に変更
            Else
                colower = Brushes.Red 'そうでない場合は塗りつぶす色を黄色に変更
            End If
            Me.Refresh() 'コードが実行されているクラスまたは構造体のクライアント領域を強制的に無効化し、直後にそのコントロール自体とその子コントロールを再描画するようにして配列にする.


        End Sub


    End Class

    2017年12月1日 1:36
  • 「オブジェクト参照がオブジェクト インスタンスに設定されていません」のはどのインスタンスかを明らかにしてください。このエラーはラインの向こうの他人にコードを解析してもらうより、自分で解決する方が早いです。何がnothingなのか。それに設定すべきなのはなんなのか。コミュニティで聞くのはこの2つを明らかにした後です。

    Jitta@わんくま同盟

    2017年12月1日 2:00
  • > どのインスタンスかを明らかにしてください。

    元質問の
    >> エラーが出た部分は太字で表示させてあります
    >> g.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom)
    を見る限りでは、まず g がまずそうです。

    g = Graphics.FromImage(canvas)
    がセットされているのは、PictureBox1_Click にしかありません。


    (1) PictureBox1_Click を実行する前に Button1_Click が呼ばれた場合の動作が考慮されていない。
    (2) PictureBox1 をクリックした後で、再度クリックしなおした場合に、以前のインスタンスを Dispose することなく、変数 canvas や g をそのまま上書きしている。

    また、fnt も Dispose されていないようです。
    ローカル変数ならば、Using ブロックを用いて確実に即時処分されるようにしましょう。
    フィールド変数にするなら、Form が閉じられた後(たとえば FormClosed など)に Dispose を書きましょう。

    これがメインフォームであるというのなら、FormClosed 等に処分コードを書かずともアプリケーション終了によって回収されますが、その場合であっても、Button1 が再クリックされる際に、以前のインスタンスを Dispose するべきかどうかは検討しておいてください。

    なお、一般的には Brush や Pen なども処分対象です。ただし今回のケースで言うと、colower のインスタンスは共有ブラシ(Brushes.Red) を割り当てているので、こちらは Dispose してはいけません。

    2017年12月1日 3:43
  • 魔界の仮面弁士さん>

    全く同じ内容で以下の 3 つスレッドが立っています。

    https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/6a16f691-9221-433f-9aeb-f4104c318aa1/-in-vbnet?forum=vbgeneralja

    https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/2c5314a9-c5a5-45e9-9641-817b8a1d300f/-in-vbnet?forum=csharpgeneralja

    https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/c05bde52-b89e-4b47-8219-3b2e7ef740ec/-in-vbnet?forum=csharpgeneralja

    上の一番目がここなのですが、二番目のスレッドによると、一番目と二番目のスレッドは削除して三番目のスレッドのみ残すそうです。

    2017年12月1日 3:52