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

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

新規登録して質問してみよう
ただいま回答率
85.50%
VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

4回答

1404閲覧

別プロジェクトの設定を参照する際のベストプラクティス

heart_crimson

総合スコア15

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2019/06/26 05:50

編集2022/01/12 10:55

前提・実現したいこと

以下のような構成でプログラムを開発しています。

フォルダ構成(拡張子無しはフォルダ名) Solution ├ Solution.sln ├ Window1 │ ├ frmMain.vb │ ├ frmMain.Designer.vb │ ├ frmMain.resx │ ├ Config.vb │ └ Window1.vbproj │ etc. └ Window2 ├ frmMain.vb ├ frmMain.Designer.vb ├ frmMain.resx ├ Config.vb └ Window2.vbproj etc.

1つのソリューションの中に複数のVBプロジェクトが入っています。
1プロジェクトごとに「帳票をプリントする際のプリンターを選択する」などの設定ができるようにしてあります。
設定はConfig.vbで実装し、.configファイル(中身はXML)で保存しています。

VB

1' Window1\Config.vb 2Public Module Config 3 4#Region "プロパティ" 5 6 ''' <summary>プリンタ名称</summary> 7 Public ReadOnly Property PrinterName As String 8 Get 9 Return _settingVo.PrinterName 10 End Get 11 End Property 12 13#End Region 14 15#Region "Private変数" 16 17 ''' <summary>設定情報</summary> 18 Private _settingVo As New ConfigData 19 20 ''' <summary>設定ファイルのフォルダ</summary> 21 Private Const _settingFolder As String = "設定\個別" 22 23 ''' <summary>設定ファイルのフォルダ</summary> 24 Public ReadOnly Property SettingFolder As String 25 Get 26 Return _settingFolder 27 End Get 28 End Property 29 30 ''' <summary>設定ファイルの名称</summary> 31 Private Const _settingFileName As String = "Window1.config" 32 33 ''' <summary>設定ファイルの名称</summary> 34 Public ReadOnly Property SettingFileName As String 35 Get 36 Return _settingFileName 37 End Get 38 End Property 39 40#End Region 41 42#Region "Friendメソッド" 43 44 ''' <summary> 45 ''' 設定ファイルの取得 46 ''' </summary> 47 ''' <remarks></remarks> 48 Friend Sub getSettingData() 49 Try 50 '設定ファイルからデータを取得 51 MyProject.Utils.FileUtils.ReadXmlToObject(_settingVo, System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), _settingFolder, _settingFileName)) 52 Catch ex As Exception 53 Throw New Exception("設定ファイル取得に失敗しました。" & " : " & ex.Message, ex) 54 End Try 55 End Sub 56 57 ''' <summary> 58 ''' 設定ファイルの保存 59 ''' </summary> 60 ''' <remarks></remarks> 61 Friend Sub saveSettingData() 62 Try 63 '設定ファイルからデータを保存 64 MyProject.Utils.FileUtils.WriteXmlFromObject(_settingVo, System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), _settingFolder, _settingFileName)) 65 Catch ex As Exception 66 Throw New Exception("設定ファイル書き込みに失敗しました。" & " : " & ex.Message, ex) 67 End Try 68 End Sub 69 70#End Region 71 72#Region "設定情報クラス" 73 74 ''' <summary> 設定情報 </summary> 75 Public Class ConfigData 76 77 ''' <summary>プリンタ名称</summary> 78 Public Property PrinterName As String = "" 79 80 End Class 81 82#End Region 83 84End Module 85

VB

1 2Imports System.Diagnostics 3Imports System.IO 4Imports System.Text 5Imports System.Xml.Serialization 6 7Namespace Utils 8 9 Public Class FileUtils 10 11 ''' <summary> 12 ''' XMLファイルの読み込み 13 ''' </summary> 14 ''' <param name="obj">読み込みデータ格納先</param> 15 ''' <param name="xmlPath">XMLファイルのパス</param> 16 Public Shared Sub ReadXmlToObject(ByRef obj As Object, ByVal xmlPath As String) 17 If Not File.Exists(xmlPath) Then Return 18 19 Dim serializer As New XmlSerializer(obj.GetType) 20 Try 21 Using fs = New FileStream(xmlPath, FileMode.Open) 22 obj = serializer.Deserialize(fs) 23 End Using 24 Catch ex As Exception 25 Throw New Exception("XML読み込みに失敗しました。" & " : " & ex.Message & " ⇒ " & xmlPath, ex) 26 End Try 27 End Sub 28 29 ''' <summary> 30 ''' XMLファイルの書き込み 31 ''' </summary> 32 ''' <param name="obj">書き込み対象データ</param> 33 ''' <param name="xmlPath">XMLファイルのパス</param> 34 Public Shared Sub WriteXmlFromObject(ByRef obj As Object, ByVal xmlPath As String) 35 Dim serializer As New XmlSerializer(obj.GetType) 36 Try 37 If Not Directory.Exists(Path.GetDirectoryName(xmlPath)) Then Directory.CreateDirectory(Path.GetDirectoryName(xmlPath)) 38 39 Using fs = New FileStream(xmlPath, FileMode.Create) 40 serializer.Serialize(fs, obj) 41 End Using 42 Catch ex As Exception 43 Throw New Exception("XML書き込みに失敗しました。" & " : " & ex.Message & " ⇒ " & xmlPath, ex) 44 End Try 45 End Sub 46 47End Namespace 48

XML

1こんなXMLファイルを出力します。 2<?xml version="1.0"?> 3<ConfigData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 4 <PrinterName>Microsoft Print to PDF</PrinterName> 5</ConfigData>

発生している問題・エラーメッセージ

Window1とWindow2で設定を共有したい状況が出てきました。
詳細に申し上げますと「設定がONの場合Window1の画面でボタンを表示・Window2の画面でボタンを非表示、設定がOFFの場合はその逆」を実装したいです。
現在Window1だけの設定はできますが、getSettingDataをFriendにしているため、Window2からWindow1の設定を見ることができません。

上記の場合どう対応するのがベストか、お知恵をお貸しいただければと思います。

  1. 全画面共通のコンフィグを作成する?

 →「A設定は1と2の画面で使うが、B画面は1と3でしか使わない」といった場合、煩雑にならないか?

  1. Window1のgetSettingDataをPublicにする?

 →修正時に影響範囲が広くなってテストしづらくならないか?
2. Window1の設定を変更したらWindow2の設定も変更されるプロパティ(画面上には表示させない)をWindow2\Config.vbに作成する?
→設定の変更画面は同じ場所なのでできなくもない?(プログラムのイメージは湧きませんが)

「自分なら〇番の方法をとる」というご意見でもありがたいです。
他にも方法がございましたらご教授ください。
また、情報が足りないようでしたらお手数ではございますがコメントください。

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

Visual Basic 2012
Visual Studio 2017
Windows Form
.NET Framework 4 Client Profile

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

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

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

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

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

guest

回答4

0

ライブラリ用のプロジェクトを追加して設定に関連するクラスを移動してWindow1,Window2から参照が普通かと。

投稿2019/06/26 08:03

編集2019/06/26 08:03
gentaro

総合スコア8949

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

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

0

私ならもう一つ設定用のプロジェクトを作ります。

投稿2019/06/26 06:54

Zuishin

総合スコア28656

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

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

0

Window1 を実行中に Window2 も実行する。
Window1 で設定を変更すると、Window2 の設定をリアルタイムで変更したい。

の様な感じですか?
であるなら、「設定配信サーバー」を立てて、Window1,2 は、サーバーにプロセス間通信で「設定変更」を通知、サーバーは接続している Window1,2 に「設定変更」を通知、ですね。
という事で、設定用のプロジェクト以外に、サーバー用のプロジェクトも要りますね。通信は、Window1,2 で共通して使えるから、これもプロジェクトを分けておけばいいですね。

投稿2019/06/27 01:38

Q71

総合スコア995

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

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

heart_crimson

2019/06/27 04:59

回答ありがとうございます。 同時起動している場合はありますが、リアルタイムである必要はないです。画面を再起動した時に反映されればOKです。
guest

0

  1. 全画面共通のコンフィグを作成する?

その選択肢の中であれば、「1」にすると思います。

  1. Window1のgetSettingDataをPublicにする?
  2. Window1の設定を変更したらWindow2の設定も変更されるプロパティ(画面上には表示させない)をWindow2\Config.vbに作成する?

「2」「3」のように、他のプロジェクトを参照するのはプロジェクト間の依存関係が複雑になってしまうので良くありません。
Window3、Window4、・・・と増えていったときに収拾がつかなくなります。

また、根本的なことを言えば、Window1 と Window2 は別々のプロジェクトにしておく必要はあるのでしょうか?
中身が分からないので何とも言えませんが、特に理由なければ一つのプロジェクトにまとめてしまった方が早いかもしれません。

投稿2019/06/27 00:51

編集2019/06/27 01:24
nskydiving

総合スコア6500

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

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

Zuishin

2019/06/27 01:17

複雑になどなりません。読み込んだ設定を保持するためのクラスを定義するために全プロジェクトから参照されるアセンブリが必要ですが、それを実装するためのプロジェクトです。これは依存関係を単純にするために作るものです。
nskydiving

2019/06/27 01:28

話がかみ合っているかわからなかったので、文章を少し修正しました。 「複雑になってしまう」と書いたのは「2」「3」のパターンです。 現在のプロジェクト構成を維持しないといけないなら、私も設定用のプロジェクトを一つ追加すると思います。
Zuishin

2019/06/27 01:36

コンフィグを複数プロジェクトで共有するのは賛成できません。それぞれに読み込むコードが必要になり、データ形式を変更したら複数箇所の変更が必要になります。また読み書きの排他性を保つのが比較的困難になります。API を通して読み書きする方が良いと思います。
heart_crimson

2019/06/27 05:13

回答ありがとうございます。 それぞれの画面は別exeにしたかったためプロジェクトを分けています(プロジェクトを分けなくても別exeにできる方法があったらすみません)。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問