这两天被老婆骂花钱多,于是算账,可怎么怎么也算不明白了。。。哈哈。。。。平时没有记账的习惯,于是写一个小程序……实际上画蛇添足了,打开EXCEL就行了…………说说程序吧
序列化和反序列化有时也称为串行化和并行化,在VS.NET中基于对XML的支持,我们可以方便的将一个对象序列化或反序列化,这提供了很多方便。可惜,MS的示例上只有一些简单的对象的示例,对于复杂的很多朋友不知道怎么做,网上有一些C#的示例,没有VB的。
下面就来个分步讲解(别想直接看结果,嘿嘿,最终的代码没有写在这里):
构思,构思,所谓策划策划的过程,据我想啊,记账,这东西,就是不断的添加添加再添加,然后求个和了之类的事情,保存到硬盘上再读回来再……用数据库不错,可惜,从8年前学VB到现在从来不爱用,也没会用过,幸亏出现个XML,那这工作由序列化完成吧。接下来选择一个比较简单的,容易操作的,速度也不用那么快的东西ArrayList来存储信息~开工:
引入名空间:
Imports System.Xml.Serialization
Imports System.IO
构造一个记账的东西,可以构造成类,也可以用其他的东西,我就是用了下面的东西,应该说是结构,结构:
Public Structure m_Info
''' <summary>
''' 数值
''' </summary>
''' <remarks></remarks>
Public Value As Single
''' <summary>
''' 时间
''' </summary>
''' <remarks></remarks>
Public Time As Date '时间
''' <summary>
''' 原因
''' </summary>
''' <remarks></remarks>
Public Purpose As Purpose '原因
''' <summary>
''' 人员
''' </summary>
''' <remarks></remarks>
Public Who As Who '人员
''' <summary>
''' 备注
''' </summary>
''' <remarks></remarks>
Public Reason As String '备注
Sub Initialization()
Me.Time = Date.Now
Me.Value = 0
Me.Purpose = 0
Me.Reason = ""
Me.Who = 0
End Sub
End Structure
这里你构造一个类还是实用结构,对最终的序列化没有影响,甚至都不用改序列化的代码。
其中枚举如下:
Public Enum Who
老公 = 1
老婆 = 2
共同 = 0
End Enum
Public Enum Purpose
in_其他收入 = 1
in_股票 = 2
in_基金 = 3
in_奖金 = 4
in_工资 = 5
out_衣服 = -1
out_吃饭 = -2
out_路费 = -3
out_礼品 = -4
out_其他支出 = -5
End Enum
Public Enum InOrOut
收入 = 1
支出 = -1
End Enum
这样,就成了(如果你看Purpose枚举别扭,那就先别扭着,想不别扭好办,看完教程自己改,对别人写的代码实行“搬来主义”永远不会让你学到技术)。
开头说,使用ARRAYLIST,这里又有一个岔路口,你可以Inherits arrarlist并overloads来实现添加、删除、查询、求和等功能,也可以dim info as new arraylist,应该是随便了,据我觉得,你认为这些帐目“就是一个”还是“应该是一个”还是“可以是一个”还是“能能够是一个”都没啥区别,当然了,我对继承的理解可能肤浅的多。我使用了这种方式:Public _Info As New ArrayList
接下来的代码中,实现了ADD,REMOVE,GETSUB函数的多个重载版本。没什么大意思的,不贴了,占地方,本文的主旨不是乱七八糟的。下面看SAVE和LOAD方法:
''' <summary>
''' 保存
''' </summary>
''' <remarks></remarks>
Public Function Save(Optional ByRef ErrStr As String = "") As Boolean
Dim Ret As Boolean = True
Try
Dim t() As Type = {GetType(m_Info)}
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)
Dim myWriter As StreamWriter = New StreamWriter("帐目.xml")
mySerializer.Serialize(myWriter, _Info)
myWriter.Close()
Catch ex As Exception
ErrStr = ex.ToString
Ret = False
End Try
Return Ret
End Function
''' <summary>
''' 读取
''' </summary>
''' <remarks></remarks>
Public Function Load(Optional ByRef ErrStr As String = "") As Boolean
Dim Ret As Boolean = True
Try
Dim t() As Type = {GetType(m_Info)}
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)
Dim myFileStream As FileStream = New FileStream("帐目.xml", FileMode.Open)
_Info = CType(mySerializer.Deserialize(myFileStream), ArrayList)
myFileStream.Close()
Catch ex As Exception
ErrStr = ex.ToString
Ret = False
End Try
Return Ret
End Function
这两个方法里面唯一需要注意的地方就是黑体部分:
Dim t() As Type = {GetType(m_Info)}
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)
往常序列化和反序列化一个简单的对象,都这样:
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList))
这里多了一个T实际上可能很多开始就学.NET的同志习惯于dim t as type()={……}这种形式的定义,不过学VB6多年了,习惯难改,实际上这两种方式是相同的解释方法。
关键问题就在于这个T的定义,如果没有这个T,你可以测试一下,将会得到类似于“生成XML文件出错”的错误,这个TYPE()参数就是告诉XmlSerializer如何去处理_Info这个对象,以什么作为参照,换句话说, Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList))的形式,只是让人家按照SYSTEM.TYPE存在的一些基本类型去解释对象(当然,这只是不准确的通俗的说法),而后面的TYPE数组将新的、自定义的类型加入,这里可以定义一个类,一个类型,一个枚举……或者它们之间任意个数个组合。
完事了,就说这么多。再回到前面:Purpose 枚举的定义比较让人恶心啊,么办法,想了好久才改到这么恶心的,这个Purpose 实际上是一个结构,里面含有两个枚举:OUT和INT。但是如果那样声明,这个文章恐怕就很晦涩了。到最后了,该讲的都讲了,你自己去改吧:Purpose 换成含有两个枚举值的结构,这样m_info结构将变成一个结构的嵌套,似乎更符合“复杂对象”这个标题,对SAVE和LOAD方法稍加修改,代码就可以正常运行。
说个题外话:游戏修改器以后不写了,这个方向做的已经很没意思了,以后开始专注SOCKET,今天就当休闲了,最近封装这个SOCKET又多线程又回调的,弄得斤数距半出栏更近了,打一会CS,之后ZZZZZzzzzzzzzz.....
最后祝大家在这个竞争激烈的软件业都有所成,至少都有大把的钞票赚。
把可测试的代码贴到这里:
类:
Imports System.Xml.Serialization
Imports System.IO
Public Class cls_Test
Public Structure m_Info
''' <summary>
''' 数值
''' </summary>
''' <remarks></remarks>
Public Value As Single
''' <summary>
''' 时间
''' </summary>
''' <remarks></remarks>
Public Time As Date '时间
''' <summary>
''' 原因
''' </summary>
''' <remarks></remarks>
Public Purpose As Purpose '原因
''' <summary>
''' 人员
''' </summary>
''' <remarks></remarks>
Public Who As Who '人员
''' <summary>
''' 备注
''' </summary>
''' <remarks></remarks>
Public Reason As String '备注
Sub Initialization()
Me.Time = Date.Now
Me.Value = 0
Me.Purpose = 0
Me.Reason = ""
Me.Who = 0
End Sub
End Structure
Public Enum Who
老公 = 1
老婆 = 2
共同 = 0
End Enum
Public Enum Purpose
in_其他收入 = 1
in_股票 = 2
in_基金 = 3
in_奖金 = 4
in_工资 = 5
out_衣服 = -1
out_吃饭 = -2
out_路费 = -3
out_礼品 = -4
out_其他支出 = -5
End Enum
Public Enum InOrOut
收入 = 1
支出 = -1
End Enum
Public _Info As New ArrayList
''' <summary>
''' 添加
''' </summary>
''' <param name="info"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Add(ByVal info As m_Info) As Boolean
_Info.Add(info)
End Function
''' <summary>
''' 保存
''' </summary>
''' <remarks></remarks>
Public Function Save(Optional ByRef ErrStr As String = "") As Boolean
Dim Ret As Boolean = True
Try
Dim t() As Type = {GetType(m_Info)}
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)
Dim myWriter As StreamWriter = New StreamWriter("帐目.xml")
mySerializer.Serialize(myWriter, _Info)
myWriter.Close()
Catch ex As Exception
ErrStr = ex.ToString
Ret = False
End Try
Return Ret
End Function
''' <summary>
''' 读取
''' </summary>
''' <remarks></remarks>
Public Function Load(Optional ByRef ErrStr As String = "") As Boolean
Dim Ret As Boolean = True
Try
Dim t() As Type = {GetType(m_Info)}
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)
Dim myFileStream As FileStream = New FileStream("帐目.xml", FileMode.Open)
_Info = CType(mySerializer.Deserialize(myFileStream), ArrayList)
myFileStream.Close()
Catch ex As Exception
ErrStr = ex.ToString
Ret = False
End Try
Return Ret
End Function
End Class
窗体:
Private Test As New cls_Test
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim test As New cls_Test.m_Info
stest.Initialization()
Test.Add(stest)
Test.Save()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Test.Load()
Debug.Print(CType(Test._Info(0), cls_Test.m_Info).Time)
End Sub