質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

1回答

3200閲覧

<VB>1ソリューション複数プロジェクトでのプロジェクト間での遷移

urozero

総合スコア21

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VB

VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2020/03/30 02:24

編集2020/04/03 04:41

前提・実現したいこと

Visual BasicでWindowsフォームアプリケーションを作成しています。
Windowsフォームアプリケーションからクラスライブラリに遷移した後、ボタンクリックでWindowsフォームアプリケーションに戻る方法が知りたいです。
構成は下記のように、1ソリューション内の複数プロジェクトになっています。

以上、よろしくお願いいたします。

構成

メインプロジェクト(Windowsフォームアプリケーション)
-Login.vb
-Menu.vb
-LoginInfo.vb(コードのみ)
サブプロジェクト1(クラスライブラリ)1画面
サブプロジェクト2(クラスライブラリ)1画面
サブプロジェクト3(クラスライブラリ)3画面 以下同様
-Form1.vb
-Form2.vb
-Form3.vb
サブプロジェクト4(クラスライブラリ)2画面
サブプロジェクト5(クラスライブラリ)4画面

詳細説明(システム概要、遷移詳細)

メインプロジェクトのLogin.vbでログイン(社員ID、パスワード)後、社員情報を取得してMenu.vbに遷移(Login.vbはvisible=falseにしているのみ)。Menu.vbのボタンクリックでそれぞれのサブプロジェクトに遷移する。
ログインは形だけなので、メインプロジェクトのLogin.vbに遷移できれば解決できると考えています。

該当のソースコード

VB

1'<<<コード⓵:サブプロジェクトへの遷移時、サブプロジェクトForm1のLabelに社員情報表示>>> 2'サブプロジェクトのフォームインスタンスを格納するフィールド 3Private SubProjectInstance1 As SubProject.Form1 4 5Private Sub Button1 click …以下略 6  'サブプロジェクト3の初期フォームインスタンスを生成 7  Me.SubProjectInstance1 = New SubProject.Form1 8  '画面に表示 9  Me.SubProjectInstance1.show() 10  'ログイン情報を設定 11  Me.SubProjectInstance1.部署名.Text = Login.Syain.Dname 12  Me.SubProjectInstance1.氏名.Text = Login.Syain.Name 13End Sub

補足情報(FW/ツールのバージョンなど)

開発環境:Windows10、Visual Studio Community 2019

前回の質問の続きになりますが、実現したいことと関係性はあまりないです。
https://teratail.com/questions/249014

追記①

ライブラリ側終了時にイベント発生、メイン側で受け取り処理をするというアドバイスをいただいて修正した後のソースコードです。
サブプロジェクト5のソースコードになります。(DB環境的に一番デバックしやすいため)

メインプロジェクト Menu.vb

VB

1Public Class Menu 2  '各システムのフォームインスタンスを格納するフィールド 3  Private SubProjectInstance1 As SubProject5.Form1 4  Private SubProjectInstance2 As SubProject5.Form2 5  Private SubProjectInstance3 As SubProject5.Form3 6  Private SubProjectInstance4 As SubProject5.Form4 7 8  Private Sub SubProject5_StartBTN_Click 9    'インスタンス生成 10    Me.SubProjectInstance1 = New SubProject5.Form1 11    Me.SubProjectInstance2 = New SubProject5.Form2 12    Me.SubProjectInstance3 = New SubProject5.Form3 13    Me.SubProjectInstance4 = New SubProject5.Form4 14     15    'イベントハンドラを設定 16    AddHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd 17    AddHandler SubProjectInstance2.SubProjectEnd, AddressOf SubProject_SubProjectEnd 18    AddHandler SubProjectInstance3.SubProjectEnd, AddressOf SubProject_SubProjectEnd   19    AddHandler SubProjectInstance4.SubProjectEnd, AddressOf SubProject_SubProjectEnd 20  Ens Sub 21 22  Private Sub SubProject_SubProjectEnd(sender As Object, e As EventArgs) 23    'イベントハンドラを削除 24   RemoveHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd 25    'メニュー画面を閉じて、ログイン画面を表示 26    Me.close() 27    Login.Show() 28  End Sub 29 30End Class 31

サブプロジェクト Form2.vb

VB

1Public Class Form2 2  Public Event SubProjectEnd(sender As Object, e As EventArgs) 3 4  Private Sub CloseButton_Click(sender As Object, e As EventArgs) Handles CloseButton.Click 5  'Form2を閉じて、Endイベント発生 6 Me.Close() 7 RaiseEvent SubProjectEnd(Me, EventArgs.Empty) 8End Sub 9 10 11End Class

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2020/04/03 04:50

追記に関してですが、どのような操作をしてどうなるのでしょうか? 提示されたソースですと、サブプロジェクト側のどれかの画面を閉じた場合、Menu画面を閉じていますので、他の画面のイベントを受け取るMenu画面がなくなっているのではないですか?
urozero

2020/04/03 05:13

サブプロジェクトのForm2のCloseボタンをクリックすると、Menu画面に遷移したままで、Login画面が表示されないです。メイン側のイベントメソッドに処理が移っていませんでした。 サブプロジェクトのForm2のRaiseEventにブレイクポイントをあてて確認しましたが、Menu画面はなくなっておらずタスクバー上にも残っていました。
guest

回答1

0

ベストアンサー

各ライブラリで終わる時にイベントを発生させて、メイン側でそれを処理すればいいのではないでしょうか。

追記

微妙に違います。

DLL側で適切なところで下記のようにイベントを定義して

VBNET

1Public Event SubProjectEnd(sender As Object, e As EventArgs)

終了する時に下記のようにイベントを発生させます。

VBNET

1Private Sub CloseButton_Click(sender As Object, e As EventArgs) Handles CloseButton.Click 2 Me.Close() 3 RaiseEvent SubProjectEnd(Me, EventArgs.Empty) 4End Sub

メイン側では

VBNET

1Private SubProjectInstance1 As SubProject.Form1 2 3Private Sub Button1 click …以下略 4  'サブプロジェクト3の初期フォームインスタンスを生成 5  Me.SubProjectInstance1 = New SubProject.Form1 6 'イベントハンドラを設定 7 AddHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd 8 9  '画面に表示 10  Me.SubProjectInstance1.show() 11  'ログイン情報を設定 12  Me.SubProjectInstance1.部署名.Text = Login.Syain.Dname 13  Me.SubProjectInstance1.氏名.Text = Login.Syain.Name 14End Sub 15 16Private Sub SubProject_SubProjectEnd(sender As Object, e As EventArgs) 17 'イベントハンドラを削除 18 RemoveHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd 19 20 '処理が終わったのでLoginフォームを表示 21End Sub

といった感じで各ライブラリからの終了イベントを受け取って、希望の処理を行うようにするということです。


P.S.
各ライブラリのインターフェースを考え直したほうが良さそうに思えます。
質問に提示された部分ですと
ライブラリ側を

VBNET

1Public Class SubProject 2 Public Property 部署名 As String 3 Public Property 氏名 As String 4 5 Public Event SubProjectEnd(sender As Object, e As EventArgs) 6 7 Public Sub ShowForm() 8 Form1.部署名.Text = 部署名 9 Form1.氏名.Text = 氏名 10 Form1.Show() 11 End Sub 12 13 ' 処理が終わったら、このメソッドを呼び出して終了を通知する 14 Friend Sub ProjectEnd() 15 RaiseEvent SubProjectEnd(Me, EventArgs.Empty) 16 End Sub 17End Class

メイン側を

VBNET

1Private SubProjectInstance1 As SubProject 2 3Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 4  'サブプロジェクト1のインスタンスを生成 5  Me.SubProjectInstance1 = New SubProject 6 7 'イベントハンドラを設定 8 AddHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd 9 10  'ログイン情報を設定 11  Me.SubProjectInstance1.部署名 = Login.Syain.Dname 12  Me.SubProjectInstance1.氏名 = Login.Syain.Name 13 14  '画面を表示 15  Me.SubProjectInstance1.ShowForm() 16End Sub 17 18Private Sub SubProject_SubProjectEnd(sender As Object, e As EventArgs) 19 'イベントハンドラを削除 20 RemoveHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd 21 22 '処理が終わったのでLoginフォームを表示 23End Sub

といった感じでメイン側に公開すべき情報、公開しない情報を整理し適切なプロパティ、メソッドを作成するようにしたほうがよろしいかと思います。
上記の例ですと、メイン側はサブロジェクト側へは「部署名」というテキストデータを設定する必要がありますが、このテキストデータの設定先がTextBoxでありそのTextプロパティに設定するということは知らなくてよいこととなります。
ですので、Form1.部署名とアクセスさせるのではなくプロパティを作成し、そこに情報をセットさせるという具合になります。

投稿2020/03/30 02:38

編集2020/03/30 08:34
YAmaGNZ

総合スコア10489

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

urozero

2020/03/30 07:46

回答ありがとうございます。 おっしゃっていることはわかりました。 下記のような処理で、大方は合っているでしょうか。 メインプロジェクト Menu.vb  サブプロジェクト Form1 ボタン1のクリックイベント時   Login.visible = true サブプロジェクト Form1  ボタン1クリックイベント   me.visible = false
urozero

2020/03/31 00:46

ご丁寧にありがとうございます。 試してみます。 インターフェースも時間作って再検討できればと思います!
urozero

2020/03/31 08:15

インターフェースは直せてませんが、上手くいきました。 大変助かりました。 ありがとうございました(#^^#)
urozero

2020/04/02 07:53

YAmaGNZさん こんにちは。改めて、大雑把ですが質問があります。 全フォームに処理を追加しましたが、現在サブプロジェクトのForm1のみしか正常に動かないです (メイン側にあるEndイベントのメソッドに処理が移らない) 初めはEndイベントを全フォーム文用意していました。しかし、各サブプロジェクトのEndイベントを一つを使いまわす形にしてもうまくいきませんでした。 何か原因は考えられるでしょうか。 PSでおっしゃっていたこととも関係があったりするでしょうか? 試したこと クラスライブラリ側でアプリケーションを終了し、メインプロジェクトのReleaseフォルダのexeを立ち上げようとしました。 Private ExeStart Sub LogoutBTN_Cllick Application.Exit() Dim As System.Diagnostics.Process = System.Diagnostics.Process.Start("???.exe") ExeStarat.WaitForExit() End Sub 新しく立ち上げられてはいますが、前実行フォームが残っています。 アプリケーションの終了の仕方が悪いのでしょうか。 以上、よろしくお願いいたします。
YAmaGNZ

2020/04/02 08:17

イベントハンドラの登録に問題があるのではないでしょうか? AddHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd のSubProjectInstance1にはイベントが発生するインスタンスを設定しなくてはなりません。 もし Private SubProjectInstance1 As SubProject.Form1 Private SubProjectInstance2 As SubProject.Form2 みたいな感じで各フォームを別々に定義して、それぞれのフォームからイベントが発生するのであれば AddHandler SubProjectInstance1.SubProjectEnd, AddressOf SubProject_SubProjectEnd AddHandler SubProjectInstance2.SubProjectEnd, AddressOf SubProject_SubProjectEnd みたいな感じで各インスタンスに対してイベントハンドラを設定する必要があります。
urozero

2020/04/02 09:56

ありがとうございます。 そのように記述しております。
YAmaGNZ

2020/04/02 10:30

そうなのであれば、実際にイベントを起こしているか、イベントハンドラが動いているのかなどデバッガで動作確認を行ったりしてみてください。
urozero

2020/04/03 01:01 編集

なるほど。 確認した結果は、イベントは起こせていて、イベントハンドラが動いてないと考えます。 ライブラリ側のRaiseEventにおいて EventArgs.Emptyに、値「System.EventArgs」 Meに、値「サブプロジェクト名前空間?.Form2, Text」 が入っております。 これはうまくいっているForm1も同じ感じでした。 その後のブレイクポイントはメイン側のMenu.vbに、SubProject_SubProjectEndメソッドに置いてます。しかしそこには行かず、メインのMenu.vbが画面に出てきて途切れてしまいます。 異なっているのは、Form1のMeの値が赤字で表示されていることでした。(デバック画面の表のところ) 以上になります。
YAmaGNZ

2020/04/03 02:04

そうなると、現状の言葉だけの説明では正直分かりません。 呼び出し側、呼び出される側のコードを見ないとなんとも言えません。
urozero

2020/04/03 04:54 編集

失礼しました。追記①を書きました。 実際のコードはかけないので、連番などを用いてのアドバイスいただいたものと同じものになってしまっていますが。 改めて見返しても、エラーではないが間違えているという点も見当たりませんでした、、、m(__)m
YAmaGNZ

2020/04/03 05:15

質問への修正依頼部分にも書きましたが、どう操作して、どのような画面遷移となり、どうなるのでしょうか? 記載されたソースを見ると、画面の表示部分がありませんが、メニューのあるボタンを押すとform1~4が表示されるのでしょうか? また、form1~4のどれかを閉じた時、メニュー画面が閉じると思いますが、その後に他の画面を閉じた時の動作が期待している動作 (どのような動作か分かりませんが)をしないということですか?
YAmaGNZ

2020/04/03 05:28

実際に作成されているものではなく、最小限のコードを作成し全てを提示してもらえませんか? 現状ですと、貴方が必要ないだろうと記載していない部分に問題があり期待通りの動作をしていない可能性が高いのではないかと思います。
urozero

2020/04/03 05:33

すみません。機能としては簡易ログアウト機能になります。 メイン側のLoginフォームでログインして、Menuフォームに遷移します。 その後、ボタンクリックでサブプロジェクトのそれぞれのForm1に遷移します。 メイン側から、サブプロジェクトのForm2に直接遷移することはありません。 全画面のログアウトボタンを押したとき、ログイン画面を表示したいです。 しかし、メイン側のMenu画面が開いたままになります。
urozero

2020/04/03 05:41

かしこまりました。 追記①を編集するのでお待ちください。 よろしくお願いいたします。
YAmaGNZ

2020/04/03 05:41

メイン側からForm2に遷移しないのであれば、もしかしてメイン側で作成しているForm2のインスタンスと、ライブラリ内で作成しているForm2のインスタンスが別ということになりませんか? そうなのであれば、そもそもメイン側でライブラリのサブフォームのインスタンスを作成しても意味がありません。 ますます、直接フォームのインスタンスを作成するのではなく管理用のクラスを用意して、そこを介してのやりとりを行ったほうがいいように思えます。
urozero

2020/04/03 05:57

インスタンスは別になります、、、 説明不足でお手間取らせてしましました、、、、、、 そうなんですね。ありがとうございます。 SEとしては失格だとは思うんですが、アプリを終了させてソリューションのexeをたたくという処理をしようと思います。 別のプロセスとしてデータが引き継がれないようなアプリ終了の記述などありますでしょうか。
urozero

2020/04/03 07:42 編集

何度もすみません。 Form1はうまくいってることを踏まえた別の方法として、 サブプロジェクト内で使われているインスタンスを用いて、Form2以降のEndイベントハンドラの設定やEndイベントメソッドなどをForm1に記述する。 Form1では、Form2以降のEndイベントを受け取ったらForm1のEndイベントを実行するというのは可能なんでしょうか。 つまりForm2以降のログアウト時はForm1に処理が移り、Form1のEndイベントとして実行するということです。 また、管理用のクラスの役割は、以下のようで合ってますでしょうか。 ・共有するログイン情報を格納 →各Formからアクセスして取得・表示 ・ログアウト主処理(Endイベントハンドラの設定とメソッドの記述)
YAmaGNZ

2020/04/03 07:47

Form2のイベントをForm1で受け取ることは可能です。 ただ、画面遷移時に Form2.Show() Me.Close() といった感じでForm2を表示しForm1を閉じているというようなやり方をしている場合は Form2.Show() Me.Hide() といった感じで、非表示にすると変更する必要があるかと思います。 もしくは、サブプロジェクト内でモジュールにForm1のインスタンスを格納する変数を用意し、Form1にLogoutメソッドを作って他のフォームから呼び出すというのも手としてはありかと思います。
urozero

2020/04/03 08:18

そうですか! そうですね。基本的にフォームのcloseとshow、またはvisibleのtrueとfalseだと思います。 そのくらいならできそうなので、やってみようと思います。 非常に助かりました。 作業は来週になってしまうと思いますが、うまくできたら報告します。 ありがとうございますm(__)mm(__)m
YAmaGNZ

2020/04/03 08:32

画面の遷移にCloseを使っているのであれば、インスタンスの変化に注意してください。 VBですとフォーム名でアクセスできてしまうのでインスタンスの意識が薄くなってしまいます。 例えば Form1.Show() Form1.Close() Form1.Show() とした場合、1回目のShowのインスタンスと2回目のShowのインスタンスは異なります。
urozero

2020/04/06 00:24

ありがとうございます。 試してみます!
urozero

2020/04/06 06:48

完成しました。 ログイン画面がShowされたとき、IDとパスワード(ログインに必要)はそのまま入力された状態でした。 テキストボックスの値を初期化してから、Showしました。 今のところ、インスタンス関連の問題はなさそうです。 明日以降PT着手予定です。 大変助かりましたm(__)m ありがとうございました(*^^*)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問