- - PR -
存在しないデータを読み取ろうとしました。
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-11-29 22:47
始めまして。
初めての書き込みです。 今自分はVB.NETでExcelに帳票出力を目的としたプログラムを作成しています。 ソース ------------------------------------------------------------------------ 'コネクション定義 Dim hConnection As System.Data.SqlClient.SqlConnection Dim uConnection As System.Data.SqlClient.SqlConnection 'ファイル名 Dim FnameS As String FnameS = ("C:\test_Excel\test" & dtNow.ToString("yyyyMMddHHmmss") & ".xls") 'ファイルコピー System.IO.File.Copy("C:\test_Excel\test.xls", FnameS) 'ファイルオープン Dim xlBook As Excel.Workbook xlBook = xlApp.Workbooks.Open(FnameS) '書き込むシート選択 Dim xlSheet As Excel.Worksheet xlSheet = xlBook.Worksheets(1) 'Excel表示 Dim xlApp As Excel.Application xlApp.Visible = False 'DB接続 uConnection = SQLConnect() 'DB切断 lvBlnRet = SQLDisConnect() If (lvBlnRet = False) Then lvBlnRet = SQLDisConnect() End If '定義 Dim lvStrHakkoDT2 As String Dim lvStrBlockCD2 As String 'WHERE句条件 lvStrHakkoDT2 = "20061124" lvStrBlockCD2 = "L" 'SQL Dim hCommand As New System.Data.SqlClient.SqlCommand hCommand = uConnection.CreateCommand() hCommand.CommandText = "SELECT TANTOSYA_CD,KOUKOKU_NM,TANTOSYA_NM FROM V_WAKU_JUCHU" hCommand.CommandText = hCommand.CommandText & " WHERE " hCommand.CommandText = hCommand.CommandText & "BLOCK_CD = '" & lvStrBlockCD2 & "'" hCommand.CommandText = hCommand.CommandText & " AND " hCommand.CommandText = hCommand.CommandText & "HAKKO_DT = '" & lvStrHakkoDT2 & "'" hCommand.CommandTimeout = 30 Dim hReader As System.Data.SqlClient.SqlDataReader hReader = hCommand.ExecuteReader hCommand.Dispose() Dim stPrompt As String 'ループ回数を数える count = 0 Dim o3 As Integer Dim lvIntClmNo As Integer lvIntClmNo = 3 Dim s As Integer Dim i As Integer For i = 0 To 2 'カラム数 o3 = 13 hReader.GetString(i) s = hReader.FieldCount Dim j As Integer For j = 0 To s - 1 '行数 stPrompt = hReader(i).ToString() xlSheet.Cells(o3, lvIntClmNo).Formula = stPrompt stPrompt = System.Environment.NewLine o3 = o3 + 1 count = count + 1 'lvIntClmNo = lvIntClmNo + 1 Next lvIntClmNo = lvIntClmNo + 1 Next hReader.Close() Public Function SQLConnect() Dim stConnectionString As String = String.Empty stConnectionString &= "Data Source = ****;" stConnectionString &= "Initial Catalog = ****;" stConnectionString &= "Integrated Security = False;" stConnectionString &= "User ID = ****;" stConnectionString &= "Password = ****;" ' SqlConnection の新しいインスタンスを生成する (接続文字列を指定) Dim hConnection As New System.Data.SqlClient.SqlConnection(stConnectionString) Try ' データベース接続を開く hConnection.Open() SQLConnect = hConnection Catch ex As Exception psErrLoging(ex.Message) ''切断を確立する hConnection.Close() hConnection.Dispose() 'cnn.Close() End Try End Function ------------------------------------------------------------------------ >hReader.GetString(i) 上記の部分で"存在しないデータを読み取ろうとしました。"のエラーが出てしまいます。 しかも出るときと出ないときがあるというランダムか感じでエラーになってしまうのですが、どなたか問題点等ございましたらご教授下さい。 宜しくお願い致します。 | ||||||||||||
|
投稿日時: 2006-11-29 23:48
んとですね。ここをはじめ、ほぼすべての掲示板は、「サポートセンター」ではありません。
なので、質問をしても、その質問に答えがあるかどうかは、読んだ人の好意にかかっています。 そして、読む人は、読みやすいものを選んで読みます。 ということは。読みにくいものは、読んでもらえない。従って、答えも得られない。ということです。 回答者に対してへりくだる必要はありませんが、読む人が読みやすい投稿をしてくださるように、お願いします。 そして。コードをいきなり書かれてもですね、とっても読みにくいのです。 コードをとばして読んで、一番下に「上記部分」と書かれると、また上に戻って読み直さなければなりません。 それよりも、次のように書いてある方が、読みやすいと思いませんか?
_________________ | ||||||||||||
|
投稿日時: 2006-11-30 00:00
その前に、Read メソッドおよび、その戻り値をチェックする箇所がないのがおかしいですよね。 # ところで、どこかで見覚えのある変数名のセットですね。 # (hConnection、hCommand、hReader、stPrompt、stConnectionString) _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||
|
投稿日時: 2006-11-30 00:06
そして、一度投稿して、自分で訂正した方を読み直してみたのですが。。。
Excel の呼び出し方については、じゃんぬさんに譲ろうっと。 エラーの発生箇所ですが、「ここ」ってつけているところで、あってます? あっているとしたら。 ここって、何をしているんです? 読み出しておいて、読み出したものを受け取るものがないのなら、要らないですよね? で、ランダムだということですが、同じ条件を指定しても、エラーになるときとならないときがあるということでしょうか? また、「エラー」と書いてありますが、本当にエラーですか?例外ではないですか?例外であるなら、例外の型も教えてください。 それから、内側の j ループですが。。。 う〜ん。これ、どういう思想で書いています?何をしているか、自分で把握出来ていますか?
追加: DataReader は一方通行なので、行の内側で列を回してください。i と j のループを反対にしてください。ただし、j が本当に行ならば。 そして、どうも、行の読み取りを勧める箇所が、ループの中に無いように思います。コードの写し間違いがないか、確認してください。 [ メッセージ編集済み 編集者: Jitta 編集日時 2006-11-30 00:11 ] [ メッセージ編集済み 編集者: Jitta 編集日時 2006-11-30 00:12 ] | ||||||||||||
|
投稿日時: 2006-11-30 12:02
度々すみません。
写し間違いや漏れがあったので一度まとめて載せます。 hReader.GetString(i)に関しては エラーになるときとならないときがあるという意味のランダムです。 間違えた使い方や問題点の指摘を こちらのコードでご教授下さい。 宜しくお願い致します。 コード: -------------------------------------------------------------------------------- '********************************************** 'FunctionName:Main 'OutLine :起動時処理 '********************************************** Sub Main(ByVal prmStrArrArgs() As String) Dim hConnection As System.Data.SqlClient.SqlConnection Dim uConnection As System.Data.SqlClient.SqlConnection Dim lvStrHakkoDT As String Dim lvStrBlockCD As String Dim lvBlnRet As Boolean Dim dtNow As DateTime = DateTime.Now Dim count As Integer Dim CancelSave As Boolean = True xlApp.DisplayAlerts = False '**************************Excel系定義************************** Dim xlRange As Excel.Range Dim xlBorders As Excel.Borders Dim xlBorder As Excel.Border Dim xlSheet As Excel.Worksheet Dim xlApp As Excel.Application xlApp = New Excel.Application Dim xlBook As Excel.Workbook Dim Range As Excel.Borders '*************************************************************** '**************************罫線系定義************************** Dim Selection As Excel.Border Dim xlNone As Excel.Borders Dim xlDiagonalDown As Excel.Borders Dim xlDiagonalUp As Excel.Borders Dim xlEdgeLeft As Excel.Borders Dim xlEdgeTop As Excel.Borders Dim xlEdgeRight As Excel.Borders Dim xlEdgeBottom As Excel.Borders Dim xlContinuous As Excel.Borders Dim xlThin As Excel.Borders Dim xlAutomatic As Excel.Borders '************************************************************** '**************************ファイル名************************** Dim FnameS As String FnameS = ("C:\test_Excel\test" & dtNow.ToString("yyyyMMddHHmmss") & ".xls") '************************************************************** Try '**************************ファイルをコピーする************************** System.IO.File.Copy("C:\test_Excel\test.xls", FnameS) '************************************************************************ '**************************オープンするファイル名************************** xlBook = xlApp.Workbooks.Open(FnameS) '************************************************************************** '**************************最初のシートに書き込み************************** 'sheet1に書き込み xlSheet = xlBook.Worksheets(1) '************************************************************************** '**************************Excelを表示************************** xlApp.Visible = False '*************************************************************** '**************************DB接続をする************************** uConnection = SQLConnect() '**************************************************************** '**************************SQL発行定義************************** Dim lvStrSQL1 As String Dim lvStrWhere1 As String Dim lvStrHanCD1 As String Dim lvStrHakkoDT1 As String Dim lvStrBlockCD1 As String Dim lvStrAreaCD1 As String lvStrHakkoDT2 = "20061124" lvStrBlockCD2 = "L" '*************************************************************** '**************************SQL発行********************************************* Dim hCommand As New System.Data.SqlClient.SqlCommand hCommand = uConnection.CreateCommand() hCommand.CommandText = "SELECT TANTOSYA_CD,KOUKOKU_NM,TANTOSYA_NM FROM V_WAKU_JUCHU" hCommand.CommandText = hCommand.CommandText & " WHERE " hCommand.CommandText = hCommand.CommandText & "BLOCK_CD = '" & lvStrBlockCD2 & "'" hCommand.CommandText = hCommand.CommandText & " AND " hCommand.CommandText = hCommand.CommandText & "HAKKO_DT = '" & lvStrHakkoDT2 & "'" hCommand.CommandTimeout = 30 Dim hReader As System.Data.SqlClient.SqlDataReader hReader = hCommand.ExecuteReader hCommand.Dispose() Dim stPrompt As String 'ループ回数を数える count = 0 Dim o3 As Integer Dim lvIntClmNo As Integer lvIntClmNo = 3 Dim s As Integer Dim i As Integer For i = 0 To 2 'カラム数 o3 = 13 hReader.GetString(i) '←ここ s = hReader.FieldCount Dim j As Integer For j = 0 To s - 1 '行数 stPrompt = hReader(i).ToString() xlSheet.Cells(o3, lvIntClmNo).Formula = stPrompt stPrompt = System.Environment.NewLine o3 = o3 + 1 count = count + 1 Next lvIntClmNo = lvIntClmNo + 1 Next hReader.Close() '****************************************************************************** '**************************DB接続を切る************************** lvBlnRet = SQLDisConnect() If (lvBlnRet = False) Then lvBlnRet = SQLDisConnect() End If '**************************************************************** '**************************エリア数分結合************************** Dim ST As Integer ST = 12 xlSheet.Range(xlSheet.Cells(3, 12), xlSheet.Cells(3, 13)).MergeCells = True xlSheet.Range(xlSheet.Cells(11, 12), xlSheet.Cells(11, 13)).MergeCells = True xlSheet.Cells(3, ST).Formula = lvStrBlockCD xlSheet.Cells(11, ST).Formula = lvStrBlockCD '****************************************************************** '*******************行生成帳票************************************************* Dim x As Integer x = 13 Dim C As Integer C = 1 For C = 1 To count If (0 = C Mod 2) Then xlRange = xlSheet.Range(xlSheet.Cells(x, 2), xlSheet.Cells(x, 34)) xlRange.Interior.ColorIndex = 19 xlBorders = xlRange.Borders xlBorders.LineStyle = Excel.XlLineStyle.xlContinuous '左側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeLeft) '左側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium '右側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeRight) '右側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium '結合 xlSheet.Range(xlSheet.Cells(x, 4), xlSheet.Cells(x, 6)).MergeCells = True xlSheet.Range(xlSheet.Cells(x, 27), xlSheet.Cells(x, 29)).MergeCells = True xlRange = xlSheet.Range(xlSheet.Cells(x, 26), xlSheet.Cells(x, 26)) xlBorders = xlRange.Borders '右側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeRight) '右側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium xlSheet.Range(xlSheet.Cells(x, 30), xlSheet.Cells(x, 32)).MergeCells = True xlSheet.Range(xlSheet.Cells(x, 33), xlSheet.Cells(x, 34)).MergeCells = True '縦太罫線 xlRange = xlSheet.Range(xlSheet.Cells(x, 11), xlSheet.Cells(x, 11)) xlBorders = xlRange.Borders '右側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeRight) '右側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium '左側の線を指定() xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeLeft) '左側の線をプラム色で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.ColorIndex = 54 'Noカウント xlSheet.Cells(x, 2).Formula = C x = x + 1 Else xlRange = xlSheet.Range(xlSheet.Cells(x, 2), xlSheet.Cells(x, 34)) xlRange.Interior.ColorIndex = xlNone xlBorders = xlRange.Borders xlBorders.LineStyle = Excel.XlLineStyle.xlContinuous '左側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeLeft) '左側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium '右側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeRight) '右側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium '結合 xlSheet.Range(xlSheet.Cells(x, 4), xlSheet.Cells(x, 6)).MergeCells = True xlSheet.Range(xlSheet.Cells(x, 27), xlSheet.Cells(x, 29)).MergeCells = True xlRange = xlSheet.Range(xlSheet.Cells(x, 26), xlSheet.Cells(x, 26)) xlBorders = xlRange.Borders '右側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeRight) '右側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium xlSheet.Range(xlSheet.Cells(x, 30), xlSheet.Cells(x, 32)).MergeCells = True xlSheet.Range(xlSheet.Cells(x, 33), xlSheet.Cells(x, 34)).MergeCells = True '縦太罫線 xlRange = xlSheet.Range(xlSheet.Cells(x, 11), xlSheet.Cells(x, 11)) xlBorders = xlRange.Borders '右側の線を指定 xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeRight) '右側の線を太線で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium '左側の線を指定() xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeLeft) '左側の線をプラム色で表示 xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.ColorIndex = 54 'Noカウント xlSheet.Cells(x, 2).Formula = C x = x + 1 End If Next C '下部の太線 Dim sx As Integer sx = x - 1 xlRange = xlSheet.Range(xlSheet.Cells(sx, 2), xlSheet.Cells(sx, 34)) xlBorders = xlRange.Borders xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeBottom) xlBorder.LineStyle = Excel.XlLineStyle.xlContinuous xlBorder.Weight = Excel.XlBorderWeight.xlMedium '****************************************************************************** '**************************保存時の問合せのダイアログを非表示に設定************************** '上書きしますけどOK?的な面倒なポップアップを無くす If CancelSave Then xlSheet.SaveAs(FnameS) 'ファイルに保存 End If '******************************************************************************************** '**************************終了処理************************** xlApp.Quit() xlSheet = Nothing xlBook = Nothing xlApp = Nothing '************************************************************ '********************************************** 'FunctionName:SQLConnect 'OutLine B接続処理 'CreateDate :2006.11.02 H.TAKEI(MC)s 'LastUpdate : '********************************************** Public Function SQLConnect() Dim stConnectionString As String = String.Empty stConnectionString &= "Data Source = ****;" stConnectionString &= "Initial Catalog = ****;" stConnectionString &= "Integrated Security = False;" stConnectionString &= "User ID = ****;" stConnectionString &= "Password = ****;" ' SqlConnection の新しいインスタンスを生成する (接続文字列を指定) Dim hConnection As New System.Data.SqlClient.SqlConnection(stConnectionString) Try ' データベース接続を開く hConnection.Open() SQLConnect = hConnection Catch ex As Exception psErrLoging(ex.Message) '切断を確立する hConnection.Close() hConnection.Dispose() End Try End Function '********************************************** 'FunctionName:SQLDisConnect 'OutLine B切断処理 '********************************************** Public Function SQLDisConnect() Dim stConnectionString As String = String.Empty stConnectionString &= "Data Source = ****;" stConnectionString &= "Initial Catalog = ****;" stConnectionString &= "Integrated Security = False;" stConnectionString &= "User ID = ****;" stConnectionString &= "Password = ****;" Dim hConnection As New System.Data.SqlClient.SqlConnection(stConnectionString) Try If (cnn.State = 0) Then SQLDisConnect = True Else '切断を確立する cnn.Close() hConnection.Close() hConnection.Dispose() If (cnn.State = 0) Then SQLDisConnect = True Else SQLDisConnect = False End If End If Catch ex As Exception psErrLoging(ex.Message) ''切断を確立する cnn.Close() hConnection.Close() hConnection.Dispose() End Try End Function '----------------------------------------------- 'SubName sErrLoging 'OutLine :指定ディレクトリにエラーを記述する 'ArgMent rmStrErrCd :エラーコード ' rmStrErrDtl:エラー詳細 '----------------------------------------------- Private Sub psErrLoging(ByVal prmStrErrMsg As String) 'ファイルオープン Dim lvStrFilePath As String = "" '書込先フォルダフルパス Dim lvStrWriteString As String = "" '書込文字列 Dim lvIntLogLevel As Integer = 0 'ログレベル Dim lvStrLogPath As String = "" 'ログフォルダ Dim lvBlnRet As Boolean = False 'Dim lvReg As New FRegKeyEx Dim lvStrTmpVal As String = "" Dim lvStrFileNm As String = "" Dim lvFS As System.IO.FileStream 'ファイルストリーム Dim lvSW As System.IO.StreamWriter 'ファイルライタ Try lvStrLogPath = "C:\test_Excel\" lvStrFileNm = Format(Date.Now, "yyyyMMdd") & "_PRT.log" lvStrFilePath = lvStrLogPath & "\" & lvStrFileNm 'ファイルオープン lvFS = New System.IO.FileStream(lvStrFilePath, System.IO.FileMode.Append) 'ファイルライタを生成 lvSW = New System.IO.StreamWriter(lvFS) '時刻,ErrCD,ErrMsgの順に書き込み lvStrWriteString = "[" & Format(Date.Now, "yyyy/MM/dd hh:mm:ss") & "] " & prmStrErrMsg & vbCrLf 'ファイル書込 lvSW.Write(lvStrWriteString) 'ファイルクローズ lvSW.Close() Exit Sub Catch ex As Exception 'psErrLoging("ex:" & ex.Message) Exit Sub End Try End Sub End Module -------------------------------------------------------------------------------- | ||||||||||||
|
投稿日時: 2006-11-30 13:07
ひとつ前にも書きましたが、
DataReader.Read メソッドおよび、その戻り値をチェックする箇所がないですよね。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||
|
投稿日時: 2006-11-30 13:28
そう書いてしまうと、他の方が答えにくくなったりしないでしょうか? とりあえず、リンクを貼っておきます。ついでに、該当箇所を書いておきます。
というより、参照カウントを解放しているところが皆無ですね。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||
|
投稿日時: 2006-11-30 14:39
エラーメッセージから大体わかると思いますが…… 「データが無い」のに読みにいくからエラーなんです。 本当にランダムですか? SQLの条件を変えたりしていませんか? 全く同じ条件で実行してそうなるのならそうだと思いますが、 コードを見た限りでは毎回同じ結果が返ってくるようにみえます。
えっと…… 半分ぐらいしか眺めてないのですが、間違えている点が相当あると思います。 というよりこれそのままだと動かないですよね? #End SubやらEnd Tryやらがないですし。 とりあえずはjittaさん、じゃんぬさんに指摘されたところをよく調べてください。 [ メッセージ編集済み 編集者: eternia 編集日時 2006-11-30 14:40 ] |