いくつか提案があります。
まず、使用しないでくださいUBound
。これは、下位互換性のためにのみ提供されている古い VB6 関数です。代わりに を使用する必要がありますSubjects.Length
。
次に、i
変数をインクリメントするときは、言う必要はありませんi = i + 1
。+=
そのために演算子を使用できます(例: i += 1
)。
ただし、とにかく、ループi
内で明示的にインクリメントするべきではありません。For
ループは、ループを反復するたびに変数を自動的にインクリメントします。そのように、ループ内で明示的に自分で行うと、他のすべての項目がスキップされます。
次に、この場合、For Each
イテレータではなくループを使用する必要があります。
For Each subject As String in Subjects
'...
Next
次に、実際にはループ内でアイテムを連結していません。あなたはこのようなことをしているはずです:
For Each subject As String in Subjects
txtComputer.Text += subject
Next
StringBuilder
ただし、その場合、効率のために、次のように a を使用する必要があります。
Dim builder As New StringBuilder()
For Each subject As String in Subjects
builder.Append(subject)
Next
txtComputer.Text = builder.ToString()
しかし、本当に必要なのは を呼び出すだけなので、これはすべて意味がありませんString.Join
。
txtComputer.Text = String.Join(", ", Subject)
モジュールからテキスト ボックスにアクセスできない理由については、モジュールが別のオブジェクトであるため、テキスト ボックスは完全に範囲外です。たとえば、フォームの 2 つのインスタンスを同時に表示した場合はどうなるでしょうか。このモジュールは、どのフォームのテキスト ボックスを参照しているかをどのように知るのでしょうか? これを修正する最も簡単な方法は、次のように、フォームへの参照をモジュールのメソッドに渡すことです。
Module Module1
Sub AddCourse(f As MyFormName)
f.txtComputer.Text = "Hello world"
End Sub
End Module
そして、次のようにフォームから呼び出すことができます。
AddCourse(Me)
ただし、それは非常に悪い習慣です。理想的には、フォームのコードの外側にあるものは、フォーム上のコントロールを直接処理するべきではありません。したがって、それを行うためのはるかに良い方法は、単にメソッドにデータを返させてから、返されるデータに独自のコントロールをフォームに設定させることです。たとえば、次のようになります。
Module Module1
Function GetCourse() As String
Return "Hello world"
End Function
End Module
そして、次のようなフォームから呼び出します。
txtComputer.Text = GetCourse()