投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/1/13 12:27:38
DataReceived という名前から、System.IO.Ports.SerialPort クラスのように
別スレッドで動作するライブラリかと初見で想像してしまいました。

別スレッドの場合は、呼び出し方を変えなければなりませんが、
現在のコードを見る限りでは、そういった実装にはしておらず、
単純に、呼び出し元と同一スレッドで動作するクラスと思って良さそうですね。


> Dim frm2 = New Form2
> g_Data = frm2.TextBox1.Text

New するということは、そこで新たに Form2 画面をもう一枚生成するということを意味します。
しかも Visible = True や Show が無いので、非表示のフォームということになり、
ここで得られる Text の値は、デザイン時の初期値になってしまうでしょう。

一応確認しておきたいのですが、今回の g_Data というのは何でしょうか?
BarcodeReader のインスタンスフィールドなのか、Form2 の公開プロパティなのか、
あるいはそれらの Shared メンバーであるのか、それとも Module で定義されたグローバル変数なのか…。


> べつclassのSubでtextBox1.textを取得してG_Dataに代入したいです。
質問文中で大文字小文字の使い分けが混在しているのは、意図的なものでしょうか。

ひとまず、g_Data と G_Data は同じ物のことで、
TextBox1.Text と textBox1.text も同じものだと仮定して回答します。



> 'インスタンスの作成(ClsHuman型)
> Dim human1 As New BarcodeReader
コメントとコードが合っていないようですよ?
上記の場合、変数の型もインスタンスの型も BarcodeReader 型であり、
ClsHuman型にはなっていません。

コメントの通り ClsHuman 型だというのなら、
   Dim human1 As New BarcodeReader
ではなく、
   Dim human1 As New ClsHuman()
   Dim human1 As ClsHuman = New BarcodeReader()
   Dim human1 As BarcodeReader = New ClsHuman()
などであるべきでしょう。


で…BarcodeReader クラスに対して、メソッド呼び出し時点の固定値を
受け渡しできれば、String 型の引数を追加するだけで十分だと思います。
例えばこんな感じ。
Partial Public Class Form2
    Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim human1 As New BarcodeReader()
        human1.DataReceived(TextBox1.Text)
    End Sub
End Class

Public NotInheritable Class BarcodeReader
    Public Sub DataReceived(arg As String)
        Dim g_Data As String = arg
        MsgBox(g_Data)
    End Sub
End Class



あるいは「DataReceived を呼び出したときの TextBox1.Text の値」を受け渡したいのではなく、
BarcodeReader クラス内の任意のタイミングで、「その時点の TextBox1.Text の最新値」を
受け渡せるようにしたい場合には、上記のように String 値を渡すのではなく、
代わりに「Me」もしくは「Me.TextBox1」ないしは「TextBox1.Text の値を返すデリゲート」などを
受け渡してみてください。幾つか実装案を書いておきます。


(案1) BarcodeReader のコンストラクタで、対象のオブジェクトを渡す
Dim human1 As New BarcodeReader(TextBox1)
' Class BarcodeReader 
'     Public Sub New(txt As TextBox) 
''' g_Data = txt.Text 

Dim human1 As New BarcodeReader(New Func(Of String)(Function() TextBox1.Text))
' Public NotInheritable Class BarcodeReader 
'     Public Sub New(getText As Func(Of String)) 
''' g_Data = getText.Invoke() 



(案2) BarcodeReader にプロパティあるいはフィールドを用意し、そこに処理のためのデリゲートやラムダ式を渡す
human1.RequireText = Function() TextBox1.Text
' Public NotInheritable Class BarcodeReader 
'     Public Property RequireText As Func(Of String) 
''' g_Data = RequireText.Invoke() 



(案3) メソッドの引数としてコントロールを渡す
human1.DataReceived(Me.TextBox1)
' Public NotInheritable Class BarcodeReader 
'     Public Sub DataReceived(owner As Control) 
''' g_Data = owner.Text 

human1.DataReceived(Me)
' Class BarcodeReader 
'     ' この方法だと、TextBox1 の Modifiers プロパティを Private にできなくなるので 
'     ' 実際は Form2 ではなく、自作 Interface を渡した方が望ましいと思います 
'     Public Sub DataReceived(owner As Form2) 
''' g_Data = owner.TextBox1.Text 




(案4) BarcodeReader が Form2 に値を取りに行くのではなく、イベントかデリゲートを通じて
 Form2 側が「BarcodeReader からの値要求イベント」に応じる形にする(コールバック方式)
Partial Public Class Form2
    Private WithEvents human As BarcodeReader
    Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        human = New BarcodeReader()
        human.DataReceived()
    End Sub
    Private Sub human_Require(sender As Object, e As BarcodeReader.RequireEventArgs) Handles human.Require
        e.Data = TextBox1.Text
    End Sub
End Class

' Form2 以外からも呼び出せるようになるので、より汎用的な実装になる 
Public NotInheritable Class BarcodeReader
    Public Event Require As EventHandler(Of RequireEventArgs)

    Public Sub DataReceived()
        Dim arg As New RequireEventArgs()
        RaiseEvent Require(Me, arg)
        Dim g_Data As String = arg.Data
        MsgBox(g_Data)
    End Sub

    Public Class RequireEventArgs
        Inherits EventArgs
        Public Property Data As String
    End Class
End Class