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

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

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Visual Studio

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

VB.NET

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

Q&A

解決済

1回答

4239閲覧

VB.netでクラスで宣言したオブジェクトの中にさらにArrayListでオブジェクトを代入してXMLシリアル化保存したい

ot2os

総合スコア23

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Visual Studio

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

VB.NET

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

0グッド

0クリップ

投稿2018/02/23 02:47

●やりたいこと
クラスでSettingsという名前のオブジェクトを宣言し、中にArrayListでさらに複数のオブジェクトを代入し、それをファイルに保存しようとしています。
XMLシリアル化が一番簡単そうなので、この方法を使っています。

今回はSettingsの中にArrayListでMailsという名前のオブジェクトを代入しようとしています。

●質問
そのまま実行すると、後述のButton1_Clickの時点で変数の作成はできるのですが、Button2_ClickでXML保存の際、serializer.Serialize(sw, SettingList)のところで「型 'System.InvalidOperationException' のハンドルされていない例外が System.Xml.dll で発生しました」エラーが出ます。

一応、Settingsの中にInherits Mailsを宣言すればエラーが出ずに動作はするのですが、下記のようにSettings直下に余計な値もできてしまいます。(Mail下の値が本来保存したい値。)
また、Inheritsは1回しか宣言できないので、新たに他のオブジェクトを実装できません。

lang

1<?xml version="1.0" encoding="utf-8"?> 2<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 3 <name /> 4 <mode>0</mode> 5 <adjust>0</adjust> 6 <Enable>false</Enable> 7 <Honbun /> 8 <MailTo /> 9 <CC /> 10 <BCC /> 11 <Group /> 12 <Member /> 13 <Mail> 14 <anyType xsi:type="Mails"> 15 <name>hogehoge</name> 16 <mode>0</mode> 17 <adjust>0</adjust> 18 <Enable>false</Enable> 19 <Honbun /> 20 <MailTo /> 21 <CC /> 22 <BCC /> 23 </anyType> 24 </Mail> 25</Settings>

ソースコードを以下に記載いたします。

・クラスでSettingsとMailsを作る

lang

1Option Explicit On 2 3'設定ファイル 4Public Class Settings 5 'Inherits Mails '←★これを入れると一応動作はする 6 Public Group As ArrayList '部署リスト(未実装) 7 Public Member As ArrayList '社員リスト(未実装) 8 Public Mail As ArrayList 'メールアドレスリスト 9 10 Public Sub New() 11 Group = New ArrayList 12 Member = New ArrayList 13 Mail = New ArrayList 14 End Sub 15 Public Sub New(ByVal isGroup As ArrayList, ByVal isMember As ArrayList, ByVal isMail As ArrayList) 16 Group = isGroup 17 Member = isMember 18 Mail = isMail 19 End Sub 20End Class 21 22 23'設定通知メール詳細 24Public Class Mails 25 Public name As String 26 Public mode As Long 27 Public adjust As Long 28 Public Enable As Boolean 29 Public Honbun As String 30 Public MailTo As String 31 Public CC As String 32 Public BCC As String 33 34 Public Sub New() 35 name = "" 36 mode = 0 37 adjust = 0 38 Enable = False 39 Honbun = "" 40 MailTo = "" 41 CC = "" 42 BCC = "" 43 End Sub 44 Public Sub New(ByVal isname As String, ByVal ismode As Long, 45 ByVal isadjust As Long, ByVal isEnable As Boolean, ByVal isHonbun As String, 46 ByVal isMailTo As String, ByVal isCC As String, ByVal isBCC As String) 47 name = isname 48 mode = ismode 49 adjust = isadjust 50 Enable = isEnable 51 Honbun = isHonbun 52 MailTo = isMailTo 53 CC = isCC 54 BCC = isBCC 55 End Sub 56End Class

・実際のファイルの保存とロード

lang

1Option Explicit On 2 3Module Module1 4 Public SettingList As New Settings 5 Private XML_dir As String = "C:\Windows\Temp" 6 7 '設定情報をロード 8 Public Sub LoadSettingsXML() 9 Dim serializer As New System.Xml.Serialization.XmlSerializer( 10 GetType(Settings)) 11 '読み込むファイルを開く 12 If System.IO.File.Exists(XML_dir & "\setting.xml") Then 13 Dim sr As New System.IO.StreamReader( 14 XML_dir & "\Settings\setting.xml", New System.Text.UTF8Encoding(False)) 15 'XMLファイルから読み込み、逆シリアル化する 16 SettingList = DirectCast(serializer.Deserialize(sr), Settings) 17 'ファイルを閉じる 18 sr.Close() 19 End If 20 End Sub 21 '設定情報を保存 22 Public Sub SaveSettingsXML() 23 Dim serializer As New System.Xml.Serialization.XmlSerializer( 24 GetType(Settings)) ' 25 'ファイルが解放されるまでTryにする 26 Dim result As DialogResult = System.Windows.Forms.DialogResult.Retry 27 While result = DialogResult.Retry 28 Try 29 Dim sw As New System.IO.StreamWriter( 30 XML_dir & "\setting.xml", False, New System.Text.UTF8Encoding(False)) 31 serializer.Serialize(sw, SettingList) '←★ここで「型 'System.InvalidOperationException' のハンドルされていない例外が System.Xml.dll で発生しました」エラー 32 sw.Close() 33 Exit While 34 Catch ex As System.IO.IOException 35 result = MessageBox.Show("ファイル書き込みができません。下記ファイルが使用中です。" & 36 vbCrLf & vbCrLf & XML_dir & "\setting.xml", 37 "ファイル使用中エラー", MessageBoxButtons.RetryCancel) 38 End Try 39 End While 40 End Sub 41 42End Module 43

・操作用のウィンドウ

lang

1Option Explicit On 2 3Public Class Form1 4 5 Dim SansyouWatashi_Mails As ArrayList 6 7 'フォーム起動時に実施 8 Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown 9 SansyouWatashi_Mails = SettingList.Mail 'SettingList.Mailの内容を参照渡しして編集する用 10 End Sub 11 12 '新規作成 13 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 14 Dim New_Name As String, New_Mail As Mails 15 New_Name = InputBox("名前を入力してください", "新しい設定") 16 New_Mail = New Mails() 17 New_Mail.name = New_Name 18 SansyouWatashi_Mails.Add(New_Mail) 19 End Sub 20 21 Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 22 Call SaveSettingsXML() 23 End Sub 24 25 Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click 26 Call LoadSettingsXML() 27 End Sub 28 29End Class

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

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

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

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

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

guest

回答1

0

ベストアンサー

ArrayList は任意の型を格納できるためどの型としてシリアライズすればいいのかが分かりません。そのため例外が発生しています。

Settings.Mail プロパティには Mails 型のオブジェクトしか格納しない前提なら、Mail プロパティに XmlArrayItem 属性を指定すればシリアライズできます。
他にもシリアライザのコンストラクタの extraTypes で Mails の型情報を渡す方法などもあります。

VB.net

1 2Public Class Settings 3 'Inherits Mails '←★これを入れると一応動作はする 4 Public Group As ArrayList '部署リスト(未実装) 5 Public Member As ArrayList '社員リスト(未実装) 6 7 <System.Xml.Serialization.XmlArrayItem(GetType(Mails))> Public Mail As ArrayList 'メールアドレスリスト 8 9 Public Sub New() 10 Group = New ArrayList 11 Member = New ArrayList 12 Mail = New ArrayList 13 End Sub 14 Public Sub New(ByVal isGroup As ArrayList, ByVal isMember As ArrayList, ByVal isMail As ArrayList) 15 Group = isGroup 16 Member = isMember 17 Mail = isMail 18 End Sub 19End Class 20 21コード

投稿2018/02/23 03:58

編集2018/02/23 04:01
masa_n

総合スコア110

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

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

ot2os

2018/02/23 05:14

ありがとうございます! いただいた方法で狙い通りの動作になりました! ちなみに、ご提案いただいた`extraTypes`の方法は、実際のファイルの保存を行うモジュールの下記行を書き換えることによって実現しました。 ●書き換え前 ```lang-VB.net Dim serializer As New System.Xml.Serialization.XmlSerializer( GetType(Settings)) ' ``` ●書き換え後 ```lang-VB.net Dim et As Type() = New Type() {GetType(Mails)} '複数型ある場合はここにコンマ区切りで列挙 Dim serializer As New System.Xml.Serialization.XmlSerializer( GetType(Settings), et) ' ``` こちらは実は同じ方法を試そうとして失敗していたのですが、serializerの`GetType(Settings)`の部分を`GetType(System.Collections.ArrayList)`を指定してしまいうまくいっていませんでした。 上記のコードでうまくいきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問