ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 3066|回复: 5

[原创] INI 文件读写!

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-2-23 12:40 | 显示全部楼层 |阅读模式
本帖最后由 山中老人 于 2018-2-23 13:00 编辑

INI 文件 作为标准的配置文本文件,很多时候都需要用到。
比如:要在本地保存一些环境变量。

下面是一个完全使用VBA写的INI文件操作类模块

第一部分:

Option Explicit
Private Const ClassName_ As String = "M_IniFile", ClassVer_ As String = "0.01", ClassInfo_ As String = "Ini文件操作 类" '#类基本常量
Public Name As String '类 实例名
Public ErrVisible As Boolean '是否显示 ERR提示,默认=显示

'--专用变量--
Public PathFile As String 'INI文件
Public IniDic As Scripting.Dictionary 'INI文件内容 词典
Public IsChange As Boolean '词典内容被修改过(Set_Item)

'--专用变量--End

'类 基本属性
Public Property Get ClassName() As String '类型名
    ClassName = ClassName_
End Property

Public Property Get ClassVer() As String '类版本
    ClassVer = ClassVer_
End Property

Public Property Get ClassInfo() As String '类注释
    ClassInfo = ClassInfo_
End Property

'类初始化
Private Sub Class_Initialize()
    Set Me.IniDic = New Scripting.Dictionary
    Me.IniDic.CompareMode = TextCompare
    Me.IsChange = False
End Sub
'类结束
Private Sub Class_Terminate()

End Sub

'通用错误提示。ErrObj =错误对象, SubName=过程名,Visible=是否显示提示,Txt=附加提示内容;返回=提示文本
Private Function ErrMsBox(ErrObj As ErrObject, SubName As String, Optional Txt As String = "", Optional Visible As Boolean = True) As String
    ErrMsBox = "位置:" & ClassName_ & "/" & Me.Name & "/" & SubName
    ErrMsBox = ErrMsBox & Chr(13) & "说明:" & Txt
    ErrMsBox = ErrMsBox & Chr(13) & "ERR:" & ErrObj.Description
    If Me.ErrVisible And Visible Then Call MsgBox(ErrMsBox, vbExclamation, SubName & "错误")
End Function

'--读写项目--
Public Function Set_Item(Section As String, Key As String, Value As String) As Boolean
    'Section=节点名称
    'Key=键
    'Value=值

    Set_Item = False
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "Set_Item"
    SubTxt = "设置项目:[" & Section & "]" & Key

    Me.IsChange = True '修改标记
    '获取节点
    Dim SectionD As Scripting.Dictionary
    If Me.IniDic.Exists(Section) Then
        Set SectionD = Me.IniDic(Section)
    Else
        Set SectionD = ADD_Section(Section, Nothing)
    End If
    '获取项目词典
    Dim KeySD As Scripting.Dictionary, ItemD As Scripting.Dictionary
    Set KeySD = SectionD("KeySD")
    '获取项目
    If KeySD.Exists(Key) Then
        Set ItemD = KeySD(Key)
    Else
        Set ItemD = New Scripting.Dictionary '新建项目
        ItemD.CompareMode = TextCompare
        Set ItemD("NotesD") = New Scripting.Dictionary
        KeySD.Add Key, ItemD
    End If
    '写入项目
    ItemD("Key") = Key
    ItemD("Value") = Value

    Set_Item = True
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

Public Function Get_Item(Section As String, Key As String) As String
    'Section=节点名称
    'Key=键

    Get_Item = ""
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "Get_Item"
    SubTxt = "读取项目:[" & Section & "]" & Key

    '获取节点
    Dim SectionD As Scripting.Dictionary
    If Me.IniDic.Exists(Section) Then
        Set SectionD = Me.IniDic(Section)
    Else
        Exit Function
    End If
    '获取项目词典
    Dim KeySD As Scripting.Dictionary, ItemD As Scripting.Dictionary
    Set KeySD = SectionD("KeySD")
    '获取项目
    If KeySD.Exists(Key) Then
        Set ItemD = KeySD(Key)
    Else
        Exit Function
    End If
    Get_Item = ItemD("Value")
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

'--读取INI文件
Public Function IniRead(Optional PathFile As String = "") As Boolean
    IniRead = False
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "IniRead"
    SubTxt = "读取INI文件:" & Me.PathFile

    If Trim(PathFile) = "" Then PathFile = Me.PathFile
    If Trim(PathFile) = "" Then GoTo err1

    Dim fso As New Scripting.FileSystemObject
    If Not fso.FileExists(Me.PathFile) Then GoTo err1 '文件不存在
    Set fso = Nothing
    Me.PathFile = PathFile
    '清空词典
    Set Me.IniDic = New Scripting.Dictionary
    Me.IniDic.CompareMode = TextCompare
    Me.IsChange = False '取消修改标记

    IniRead = Me.ADD_IniRead(PathFile)
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

Public Function ADD_IniRead(PathFile As String) As Boolean
    ADD_IniRead = False
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "ADD_IniRead"
    SubTxt = "追加读取INI文件:" & PathFile

    Dim fso As New Scripting.FileSystemObject, TF As Scripting.TextStream
    If Trim(PathFile) = "" Then GoTo err1
    If Not fso.FileExists(PathFile) Then GoTo err1 '文件不存在
    Set TF = fso.OpenTextFile(PathFile, ForReading, False, TristateMixed)   '打开文件

    Dim i As Long, Txt As String, Txt2 As String, Section As String
    Dim e As Long, Key As String, Value As String

    Dim NotesD As New Scripting.Dictionary '注释词典
    '遍历文件
    Do Until TF.AtEndOfStream
        i = TF.Line
        Txt = TF.ReadLine
        Txt2 = Trim(Txt)
        If Left(Txt2, 1) = ";" Or Txt2 = "" Then '注释、空行
            NotesD.Add i, Txt
        ElseIf Left(Txt2, 1) = "[" And Right(Txt2, 1) = "]" Then '节标题
            Section = Mid(Txt2, 2, Len(Txt2) - 2)
            Call ADD_Section(Section, NotesD)
            Set NotesD = New Scripting.Dictionary '新注释 词典
        ElseIf InStr(1, Txt2, "=") > 0 Then '项目
            e = InStr(1, Txt2, "=")
            Key = Left(Txt2, e - 1)
            Value = Mid(Txt2, e + 1)
            Call ADD_Item(Section, Key, Value, NotesD)
            Set NotesD = New Scripting.Dictionary '新注释 词典
        Else '注释、空行
            NotesD.Add i, Txt
        End If
    Loop
    TF.Close '关闭文件
    Set TF = Nothing
    Set fso = Nothing

    ADD_IniRead = True
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

Private Function ADD_Section(Section As String, Optional NotesD As Scripting.Dictionary = Nothing) As Scripting.Dictionary
    'Section=节点名称
    'NotesD=注释

    Set ADD_Section = Nothing
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "ADD_Section"
    SubTxt = "添加节点:" & Section

    '获取节点
    Dim SectionD As Scripting.Dictionary
    Dim NotesD1 As Scripting.Dictionary, KeySD1 As Scripting.Dictionary
    If Me.IniDic.Exists(Section) Then
        Set SectionD = Me.IniDic(Section)
        Set NotesD1 = SectionD("NotesD")
        Set KeySD1 = SectionD("KeySD")
    Else '新建节点
        Set SectionD = New Scripting.Dictionary
        SectionD.CompareMode = TextCompare
        Set NotesD1 = New Scripting.Dictionary
        Set KeySD1 = New Scripting.Dictionary
        KeySD1.CompareMode = TextCompare
        SectionD.Add "NotesD", NotesD1
        SectionD.Add "KeySD", KeySD1
        Me.IniDic.Add Section, SectionD
    End If

    Dim i As Long, Line As Long, Value As String
    If Not NotesD Is Nothing Then '添加注释
        For i = 0 To NotesD.Count - 1
            Line = NotesD.Keys(i)
            Value = NotesD.Items(i)
            NotesD1(Line) = Value
        Next
    End If

    Set ADD_Section = SectionD
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

Private Function ADD_Item(Section As String, Key As String, Value As String, Optional NotesD As Scripting.Dictionary = Nothing) As Scripting.Dictionary
    'Section=节点名称
    'NotesD=注释

    Set ADD_Item = Nothing
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "ADD_Item"
    SubTxt = "添加项目:" & Section

    '获取节点
    Dim SectionD As Scripting.Dictionary
    If Me.IniDic.Exists(Section) Then
        Set SectionD = Me.IniDic(Section)
    Else
        Set SectionD = ADD_Section(Section, Nothing)
    End If
    '获取项目词典
    Dim KeySD As Scripting.Dictionary, ItemD As Scripting.Dictionary
    Set KeySD = SectionD("KeySD")
    '获取项目
    If KeySD.Exists(Key) Then
        Set ItemD = KeySD(Key)
    Else
        Set ItemD = New Scripting.Dictionary
        ItemD.CompareMode = TextCompare
        KeySD.Add Key, ItemD
    End If
    '写入项目
    If NotesD Is Nothing Then
        Set ItemD("NotesD") = New Scripting.Dictionary
    Else
        Set ItemD("NotesD") = NotesD
    End If
    ItemD("Key") = Key
    ItemD("Value") = Value

    Set ADD_Item = ItemD
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function


评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-2-23 12:40 | 显示全部楼层
本帖最后由 山中老人 于 2018-2-23 12:51 编辑

第二部分:

'--写入INI文件
Public Function IniWrite(Optional PathFile As String = "", Optional Sort As Boolean = True) As Boolean
    IniWrite = False
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "IniWrite"
    SubTxt = "写入INI文件:" & Me.PathFile
   
    Dim fso As New Scripting.FileSystemObject, TF As Scripting.TextStream
    If Trim(PathFile) = "" Then PathFile = Me.PathFile
    If Trim(PathFile) = "" Then GoTo err1
    Set TF = fso.CreateTextFile(PathFile, True)  '新建文件
    If TF Is Nothing Then GoTo err1
   
    Dim Dic As Scripting.Dictionary
    If Sort Then
        Set Dic = DicSort(Me.IniDic) '排序
    Else
        Set Dic = Me.IniDic
    End If
   
    Dim SectionD As Scripting.Dictionary '节点
    Dim NotesD As Scripting.Dictionary  '注释
    Dim KeySD As Scripting.Dictionary '项目词典
    Dim i As Long, Section As String
    For i = 0 To Dic.Count - 1
        Section = Dic.Keys(i)
        Set SectionD = Dic.Items(i)
        '写注释
        If SectionD.Exists("NotesD") Then '
            Set NotesD = SectionD("NotesD")
            Call Write_NotesD(TF, NotesD)
        End If
        '写节点名
        TF.WriteLine "[" & Section & "]"
        '写项目词典
        If SectionD.Exists("KeySD") Then '
            Set KeySD = SectionD("KeySD")
            Call Write_KeySD(TF, KeySD)
        End If
    Next
   
    TF.Close '关闭文件
    Set TF = Nothing
    Set fso = Nothing
   
    Me.IsChange = False '取消修改标记
    IniWrite = True
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

Private Function Write_NotesD(TF As Scripting.TextStream, NotesD As Scripting.Dictionary) As Boolean
    'NotesD=注释
    Write_NotesD = False
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "Write_NotesD"
    SubTxt = "写注释词典"
   
    If TF Is Nothing Then GoTo err1
    If NotesD Is Nothing Then Exit Function
   
    Dim i As Long
    For i = 0 To NotesD.Count - 1
        TF.WriteLine NotesD.Items(i)
    Next
    Write_NotesD = True
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

Private Function Write_KeySD(TF As Scripting.TextStream, KeySD As Scripting.Dictionary) As Boolean
    'KeySD=项目词典
    Write_KeySD = False
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "Write_KeySD"
    SubTxt = "写项目词典"
   
    If TF Is Nothing Then GoTo err1
    If KeySD Is Nothing Then Exit Function
   
    Dim i As Long, ItemD As Scripting.Dictionary, NotesD As Scripting.Dictionary, Txt As String
    For i = 0 To KeySD.Count - 1
        Set ItemD = KeySD.Items(i)
        '写注释
        If ItemD.Exists("NotesD") Then '
            Set NotesD = ItemD("NotesD")
            Call Write_NotesD(TF, NotesD)
        End If
        Txt = ItemD("Key") & "=" & ItemD("Value")
        TF.WriteLine Txt
    Next
    Write_KeySD = True
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

'--支持函数--
Private Function DicSort(Dic As Scripting.Dictionary, Optional KeySort As Boolean = True, Optional DESC As Boolean = False) As Scripting.Dictionary
    'KeySort=True 按Key排序;KeySort=False 按Item排序
    'DESC=True 从大到小排序;DESC=False 从小到大排序
    Set DicSort = Nothing
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "DicSort"
    SubTxt = "词典按Key排序" '
   
    '参数处理
    If Dic Is Nothing Then Exit Function
    Dim Dic0 As Scripting.Dictionary
    Set Dic0 = DicCopy(Dic)
    If Dic0.Count <= 0 Then
        Set DicSort = Dic0
        Exit Function
    End If
    '排序
    Dim i As Long, Index As Long
    Dim Dic1 As New Scripting.Dictionary
    Do While Dic0.Count > 0
        '取Index
        Index = 0
        For i = 1 To Dic0.Count - 1 '遍历
            If DESC Then '从大到小排序
                If KeySort Then
                    If Dic0.Keys(Index) < Dic0.Keys(i) Then Index = i '取大Key
                Else
                    If Dic0.Item(Index) < Dic0.Item(i) Then Index = i '取大Item
                End If
            Else '从小到大排序
                If KeySort Then
                    If Dic0.Keys(Index) > Dic0.Keys(i) Then Index = i '取小Key
                Else
                    If Dic0.Item(Index) > Dic0.Item(i) Then Index = i '取小Item
                End If
            End If
        Next
        '转移词典 项目
        Dic1.Add Dic0.Keys(Index), Dic0.Items(Index)
        Call Dic0.Remove(Dic0.Keys(Index))
    Loop
    Set DicSort = Dic1
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

Private Function DicCopy(Dic As Scripting.Dictionary) As Scripting.Dictionary
    Set DicCopy = Nothing
    On Error GoTo err1
    Dim SubName As String, SubTxt As String
    SubName = "DicCopy"
    SubTxt = "复制词典"
   
    If Dic Is Nothing Then Exit Function
    Dim OutDic As New Scripting.Dictionary
    OutDic.CompareMode = Dic.CompareMode
    Dim i As Long, Obj As Object
    For i = 0 To Dic.Count - 1
        OutDic.Add Dic.Keys(i), Dic.Items(i)
    Next
    Set DicCopy = OutDic
    Exit Function
err1:
    Call ErrMsBox(Err, SubName, SubTxt & " 失败!")
End Function

TA的精华主题

TA的得分主题

发表于 2019-1-21 14:49 | 显示全部楼层
非常好,只是需要学习,能再附一个实例使用就更好了。

TA的精华主题

TA的得分主题

发表于 2019-2-22 20:52 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2020-1-3 22:37 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-7-13 13:37 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-20 01:51 , Processed in 0.034394 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表