C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: 『インデックスが配列の対象外』が出現有無がおきる件


(過去ログ 176 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■101331 / inTopicNo.1)  『インデックスが配列の対象外』が出現有無がおきる件
  
□投稿者/ ヨンパチ (1回)-(2023/02/06(Mon) 18:26:13)

分類:[VB.NET/VB2005 以降] 

visual Studio 2019を使用しております。

測定装置からデータを落とすために、以下のプロファイルを作成しました。
うまく落とせるときもあれば、なぜかタイトルのようにエラーが出てしまいます。
エラーは一番下のところで発生します。

開発初心者で申し訳ございませんが、私よりも詳しい方、ご教授いただければ幸いです。


Dim i_debugflg As Integer = 1 '確認をする場合 : 1- OFF 2- Check

Dim i As Integer
Dim j As Integer
Dim counter As Integer

Dim intDataDim As Integer
Dim dlCent As Double
Dim dlSpan As Double
Dim dlFreq As Double
Dim StrStimData1 As String

Dim delimiter() As Char = {","c}
Dim StrArrayData1() As String

Dim PathSavefile As String
Dim SavefileName As String

Dim StrBuf As String

Dim SwtimedataInit, SwtimedataNow, SwtimedataPast As Long


StrBuf = New String(Chr(&H0S), 30)

counter = Integer.Parse(txtMeasCounter.Text)
Txt_SaveFilename2.Text = "Average" & counter.ToString()
counter = counter + 1
txtMeasCounter.Text = counter.ToString()

If i_debugflg = 2 Then

U2GPIBAX.gpwrt(GpadrsBuf3, "SING")
SwtimedataInit = timeGetTime
Do
SwtimedataNow = timeGetTime

SwtimedataPast = (SwtimedataNow - SwtimedataInit) / 1000
Loop While SwtimedataPast < 30

End If

'/- 測定ポイント数の読み込み
U2GPIBAX.gpwrt(GpadrsBuf3, "POIN?")         ' 測定ポイント数
U2GPIBAX.gpred(GpadrsBuf3, StrBuf, Len(StrBuf))
intDataDim = Convert.ToInt32(StrBuf)
'intDataDim = Integer.Parse(StrBuf)

' intDataDim = Integer.Parse(201)
If i_debugflg = 2 Then MessageBox.Show("測定ポイント数:” & intDataDim.ToString())

'/- 中心周波数の読み込み
U2GPIBAX.gpwrt(GpadrsBuf3, "CENT?")         '  中心周波数
U2GPIBAX.gpred(GpadrsBuf3, StrBuf, Len(StrBuf))
dlCent = Convert.ToDouble(StrBuf)
'dlCent = Double.Parse(StrBuf)
If i_debugflg = 2 Then MessageBox.Show("中心周波数(Hz):” & dlCent.ToString())

'/- 中心周波数の読み込み
U2GPIBAX.gpwrt(GpadrsBuf3, "SPAN?")         ' 周波数幅
U2GPIBAX.gpred(GpadrsBuf3, StrBuf, Len(StrBuf))
dlSpan = Convert.ToDouble(StrBuf)
'dlSpan = Double.Parse(StrBuf)
If i_debugflg = 2 Then MessageBox.Show("周波数幅(Hz):” & dlSpan.ToString())


StrStimData1 = New String(Chr(&H0S), intDataDim * 30)


U2GPIBAX.gpwrt(GpadrsBuf3, "FORM4")   'ASCIIフォマットの指定
U2GPIBAX.gpwrt(GpadrsBuf3, "OUTPFORM?") 'Agilent E5100Aのデータトレースの問合せ
U2GPIBAX.gpred(GpadrsBuf3, StrStimData1, Len(StrStimData1))

If i_debugflg = 2 Then MessageBox.Show("測定終了")

' カンマ区切りで分割して配列に格納する
StrArrayData1 = StrStimData1.Split(delimiter)

PathSavefile = Txt_SavePoint.Text
SavefileName = Txt_SaveFilename2.Text & ".csv"

Dim sw As New System.IO.StreamWriter(PathSavefile & SavefileName, False)

sw.Write("Time")
sw.Write(",")
sw.Write(NowTime)
sw.Write(vbCrLf, ToString())
sw.Write("SetTemp")
sw.Write(",")
sw.Write(setTemp)
sw.Write(vbCrLf, ToString())
sw.Write("SetPower")
sw.Write(",")
sw.Write(setPower)
sw.Write(vbCrLf, ToString())
sw.Write("Temp")
sw.Write(",")
sw.Write(Tempdata)
sw.Write(vbCrLf, ToString())
sw.Write("Power")
sw.Write(",")
sw.Write(Powerdata)
sw.Write(vbCrLf, ToString()) ' 改行

For i = 0 To intDataDim - 1

j = 2 * i
dlFreq = (dlCent - dlSpan / 2 + (dlSpan / (intDataDim - 1)) * i) ' Frequency[Hz]
sw.Write(dlFreq / 1000000.0) ' Frequency[MHz]
sw.Write(",")

※エラーが出るポイント ここから
sw.Write(StrArrayData1(j).ToString())
sw.Write(",")
sw.Write(StrArrayData1(j + 1).ToString())

※エラーが出るポイント ここまで

sw.Write(vbCrLf, ToString()) ' 改行
Next i

sw.Close() '閉じる




お手数をおかけしますが、よろしくお願い致します。


引用返信 編集キー/
■101333 / inTopicNo.2)  Re[1]: 『インデックスが配列の対象外』が出現有無がおきる件
□投稿者/ WebSurfer (2623回)-(2023/02/06(Mon) 18:39:13)
No101331 (ヨンパチ さん) に返信

> ' カンマ区切りで分割して配列に格納する
> StrArrayData1 = StrStimData1.Split(delimiter)

上記で作成した配列の要素数を超えて以下のコードがアクセスするからだと思います。

> ※エラーが出るポイント ここから
> sw.Write(StrArrayData1(j).ToString())
> sw.Write(",")
> sw.Write(StrArrayData1(j + 1).ToString())
>
> ※エラーが出るポイント ここまで

デバッグしたらわかると思います。
引用返信 編集キー/
■101334 / inTopicNo.3)  Re[2]: 『インデックスが配列の対象外』が出現有無がおきる件
□投稿者/ 魔界の仮面弁士 (3559回)-(2023/02/06(Mon) 19:03:13)
掲示板投稿時の注意事項欄に、
『半角カナは使用しないでください。文字化けの原因になります。』
という記述があったかと思います。
次回以降、御留意ください。


No101331 (ヨンパチ さん) に返信
> Dim intDataDim As Integer
> Dim dlCent As Double
> Dim dlSpan As Double
> Dim dlFreq As Double
> Dim StrStimData1 As String
ローカル変数の宣言は、先頭にまとめて書くのではなく、
「実際に使う場所(使う直前)」で「初期値付き」で宣言した方が望ましいですよ。

https://thom.hateblo.jp/entry/2016/12/12/223708
https://atmarkit.itmedia.co.jp/bbs/phpBB/viewtopic.php?topic=30520&forum=7


> 開発初心者で申し訳ございませんが、
まず調べなければならないのは
・測定装置から、想定しない値が返ってきているのか?
・得られる値は正しいけれど、VB のコードに問題がある状態なのか?
のどちらであるのか、です。


> 『インデックスが配列の対象外』が出現有無がおきる件
> ※エラーが出るホ゜イント ここから
> sw.Write(StrArrayData1(j).ToString())

「デバッグ」してみてください。

(1) エラーが発生したとき、「j」の値が何になっていますか?
(2) エラーが発生した時、「StrArrayData1.Length」の値は何になっていますか?


j の値は 常に「0 以上、StrArrayData1.Length 未満」でなければなりません。
それ以外の値が渡されれば、IndexOutOfRangeException の例外になってしまいます。


エラーの要因となりえる StrArrayData1 配列の中身を決めているのは
> ' カンマ区切りで分割して配列に格納する
> StrArrayData1 = StrStimData1.Split(delimiter)
ですよね。

そしてこの StrStimData1 の値はおそらく、GPIB 機器から
> U2GPIBAX.gpred(GpadrsBuf3, StrStimData1, Len(StrStimData1))
によって取り込まれるのでしょう。(U2GPIBAX ライブラリの仕様を知らないので推測ですが)


ということは、もしも StrStimData1 の中身が "" という空文字列なら、
 StrArrayData1 = StrStimData1.Split(delimiter)
という処理が、
 StrArrayData1 = New String() { "" }
と同じ結果を返すわけで、その場合、StrArrayData1.Length は「1」という値になります。


一方、配列の添字となる j の値を決めているのは
> For i = 0 To intDataDim - 1
>   j = 2 * i
の箇所ですから、「0」「2」「4」…と増えていきますよね。


この元となる intDataDim の値は、
> U2GPIBAX.gpred(GpadrsBuf3, StrBuf, Len(StrBuf))
> intDataDim = Convert.ToInt32(StrBuf)
で決まるはずです。


ゆえに確認するべきは、
 「エラー発生時の StrBuf および StrStimData1 の中身がなんであるのか」
です。その内容に矛盾、あるいは想定外の情報であるのなら、
異常値を取り除く処理が必要になりますし、データそのものは正しいのなら、
ロジック(コードの記述)に何らかの不具合がある可能性があるわけで。
引用返信 編集キー/
■101336 / inTopicNo.4)  Re[3]: 『インデックスが配列の対象外』が出現有無がおきる件
□投稿者/ ヨンパチ (2回)-(2023/02/07(Tue) 08:05:19)
WebSurfer様
魔界の仮面弁士様

アドバイス誠にありがとうございます。対応し修正してみます。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -