構造体への入力をサブルーチンでするエラー発生する対処は無いでしょうか。

タグの編集
投稿者 中本  (社会人) 投稿日時 2013/4/10 17:41:38
VB2010 を使用しています。
構造体にデータ入力でつまづいています。
よろしくお願いします。

Public Class MainStart

'宣言
Public JUd(150) As JUD変数

Structure JUD変数
        Dim N As String
        Dim Hi As Double

Public Sub New(ByRef N As String,  ByRef Hi As Double)
            Me.N = N    
            Me.Hi = Hi     

End Structure
  
'クリック
Private Sub ButOpenFile_Click(sender As System.Object, e As System.EventArgs) Handles ButOpenFile.Click
  Dim i As Integer
  for i= 1 to 10 step 2
          JUd(i).N = Ary(i)      '名前
          JUd(i).Hi = Ary(i+1)     '番号
  next i

end class

以上の方法だと、構造体のJUd()に変数の受け渡しができます。
しかし、都合上サブルーチン内でデータを取り込もうとしましたが
エラーとなります。単純にはいかないのでしょうか。

'クリック
Private Sub ButOpenFile_Click(sender As System.Object, e As System.EventArgs) Handles ButOpenFile.Click

  Call testsub(JUd,Ary)   

end sub


Sub testsub(byref JUd, byref Ary)
  Dim i As Integer
  for i= 1 to 10 step 2
          JUd(i).N = Ary(i)      '名前
          JUd(i).Hi = Ary(i+1)     '番号
  next i

end sub

end class

とましたた。エラーメッセージは、次の通りです。
Exceptionはハンドルされませんでした。
'JUd変数' が遅延バインディングの結果である場合、'LY変数' 型の値のフィールドへの遅延バインディングの割り当ては無効です。
投稿者 るきお  (社会人) 投稿日時 2013/4/10 21:06:41
掲示板で表現するのがなかなか難しいですが、書いてみます。

投稿されたプログラムにはいろいろとおかしな点、望ましくない点があります。
中本さんの直面しているエラーを出さなくする方法は私は3つ思いつきました。
しかし、そのどれもおすすめではありません。全体的に問題があるように感じます。
かといって全体を書きなおそうにもやりたいことがわからないのでできません。

そこで、違和感はありますがひとまず3つの解決方法を紹介します。

■解決方法1.JUD変数をクラスにしてください。
このためにはプログラムのいくつかの部分を変更する必要があります。具体例は割愛します。

■解決方法2.testsubの引数に型を指定してください。
Sub testsub(byref JUd As JUD変数(), byref Ary As Object())


■解決方法3.testsub内でJUd(i)のフィールド(NとHiのこと)を変更するのではなく、JUd(i)自体を変更してください。
Sub testsub(byref JUd, byref Ary)
     Dim i As Integer
     For i = 1 To 10 Step 2
         Dim temp As JUD変数
         temp.N = Ary(i)
         temp.Hi = Ary(i + 1)
         JUd(i) = temp
     Next i

End Sub


さて、中本さんが今回どのような立場でプログラムを作成されているのかわかりませんが、
私の会社の後輩で入社1年目の新人だったら私はこう言います。
・配列を使うわないで、List(Of T)を使ってください。
・構造体を使わないで、クラスを使ってください。
・構造体をクラスに入れ子にする必要があるかよく検討してください。
・ByRefは使わないでください。
・下記のループでJUd側は奇数のものだけ値がセットされますが、仕様上正しいか確認してください。
for i= 1 to 10 step 2
    JUd(i).N = Ary(i)      '名前 
    JUd(i).Hi = Ary(i+1)     '番号 
next i

・HiがDouble型なので、誤差が生じる可能性があります。仕様上正しいか確認してください。
また、投稿いただいたプログラムではAryの出所がよくわかりませんが、ここも何か指摘すると思います。

もっと細かいことをいう場合もありますが、とりあえずこのようなところです。
(※念のため補足すると、配列や構造体を使う場合もありえます。)

このような点を踏まえるとそもそもこのエラーは発生しないものなのです。


なお、中本さんのプログラムを貼り付けるといくつかエラーになります。
また、Call testsub(JUd,Ary)  の Ary が何かもよくわかりません。

今回のようなケースでは実行するとエラーになるという話ですので、
そのまま実行できるプログラムを貼り付けてもらえるのが一番よいです。
中本さんが疑問に思っていることを考えるより前に、このプログラムのエラーを修正し、Aryが何か推理して適切なものに置き換えるという作業が必要になってしまいます。
投稿者 中本  (社会人) 投稿日時 2013/4/11 06:58:29
ありがとうございます。
構造体を使用した理由としては、計算の段階で JUd(i) データが重複して入るものですから
一旦全部データをJUd(i)に取り込んで、そのあと内容の同一なものを削除や並べ替え
等に便利だからしようとしました。
これまでは、JUdname(i)  JUdHi(i) とかに分けて使用していました。また、ここでは
.N  .Hi の2項目しか表示していませんが、全部で6個のものがありまして大変でした。

.Hiの値は別ボタンで計算処理した値が入るものです。
だから、どうしても別サブルーチンになってどうしようかと悩んでいました。
Ary(i)は、別計算で使用した変数です。

List(Of T)は使用したことがないので、またにします。
解決方法2,3を試してみます。

そのまま実行できるプログラムを貼り付につきましては、すみませんでした。
結果につきましては、後日投稿します。
投稿者 中本  (社会人) 投稿日時 2013/4/17 06:39:18
解決方法3でやりたいこと十分できました。ありがとうございました。