VBA是我正式学习的第一门计算机语言,也是一门我感情很深的计算机语言。它带我领略了编程的乐趣,让我相信一切皆有可能,一切皆可实现。它也给我带来的很多乐趣,很多工作机会。让我给你介绍一下它。
Visual Basic for Applications(VBA)是Visual
Basic的一种宏语言,是微软开发出来在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展Windows的应用程式功能,特别是Microsoft
Office软件。也可说是一种应用程式视觉化的Basic
脚本。该语言于1993年由微软公司开发的的应用程序共享一种通用的自动化语言——–Visual Basic For
Application(VBA),实际上VBA是寄生于VB应用程序的版本。微软在1994年发行的Excel5.0版本中,即具备了VBA的宏功能。
由于微软Office软件的普及,人们常见的办公软件Office软件中的Word、Excel、Access、Powerpoint都可以利用VBA使这些软件的应用更高效率,例如:通过一段VBA代码,可以实现画面的切换;可以实现复杂逻辑的统计(比如从多个表中,自动生成按合同号来跟踪生产量、入库量、销售量、库存量的统计清单)等。掌握了VBA,可以发挥以下作用:
- 规范用户的操作,控制用户的操作行为;
- 操作界面人性化,方便用户的操作;
- 多个步骤的手工操作通过执行VBA代码可以迅速的实现;
- 实现一些VB无法实现的功能。[1]
- 用VBA制做EXCEL登录系统。[2]
- 利用VBA可以Excel内轻松开发出功能强大的自动化程序。
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="itab" label="自动化工具">
<group id="igrp1" label="数据源管理">
<button
id="isource_clear"
label="清空数据源"
imageMso="_3DMaterialMetal"
size="large"
supertip="可用于清空所有订单表和招聘表中的信息"
onAction="isource_clear"/>
<button
id="isource_input"
label="导入数据源"
imageMso="_3DMaterialPlastic"
size="large"
supertip="将选中文件《招聘订单信息一览表》和《招聘在途及外招信息一览表》中的信息导入到本工具对应的数据源中,累计添加."
onAction="isource_input"/>
group>
tab>
tabs>
ribbon>
customUI>
Sub eMailMergeWithAttchments(t As Worksheet)
Dim myDatarange As Range
Dim i As Long, j As Long, k As Long, l As Long
Dim ISectionsCount As Long
Dim bStarted As Boolean
Dim oOutlookApp As Outlook.Application
Dim wWordApp As Object
Dim SrcDoc As Object
Dim oItem As Outlook.MailItem
Dim oAccount As Outlook.Account
Dim sMySubject As String, sMessage As String, sTitle As String
Dim RowNum As Long, ColNum As Integer
Dim TmpBody As String
Dim m As Integer, n As Integer, m1 As Integer, n1 As Integer
Dim VarName As String, RepName As String
Dim VarCol As Integer
Dim IsRight As Boolean
Dim MyPath As String
Dim StartVarCol As Integer
Dim PrePath As String
Dim StartText As String
Dim EndText As String
Dim Myrange01 As Object, Myrange02 As Object, Myrange03 As Object, FoundRange As Object
Dim isFind As Boolean
Dim RepStr As String, OldStr As String
Dim TmpFileName As String
Dim MyFile As New FileSystemObject
Dim SavePath As String
'
'Dim TestWRange As Word.Range
StartText = "<-|"
EndText = "|->"
'
'StartVarCol = 11
TmpFileName = "TmpHtmlDoc.htm"
'Set docSource = ActiveDocument
RowNum = t.Cells(12, 1).CurrentRegion.Rows.Count - 1
ColNum = t.Cells(12, 1).CurrentRegion.Columns.Count
If RowNum = 0 Then
MsgBox "无待发送邮件"
Exit Sub
End If
PrePath = ThisWorkbook.Path & "\邮件模板"
On Error Resume Next
'检测是否打开Outlook
Set oOutlookApp = GetObject(, "Outlook.Application")
'没打开则打开
If Err <> 0 Then
Set oOutlookApp = CreateObject("Outlook.Application")
bStarted = True
End If
'打开word
Set wWordApp = CreateObject("Word.Application")
'显示发送情况
UserForm1.Show 0
With UserForm1.ProgressBar1
.Min = 1
.Max = RowNum + 1
.Scrolling = 0
End With
For i = 13 To RowNum + 12
t.Cells(i, 1) = "发送中"
IsRight = True
Set oAccount = oOutlookApp.Session.Accounts.Item(t.Cells(6, "H").Value) '设定发送邮箱
'获取正文
MyPath = t.Cells(i, 5)
If Left(MyPath, 1) = "." Then
MyPath = PrePath & Right(MyPath, Len(MyPath) - 1)
Debug.Print MyPath
End If
MyPath = VBA.Replace(MyPath, ",", "")
Debug.Print MyPath
Set SrcDoc = wWordApp.Documents.Open(MyPath)
'持续替换变量
Do
Set Myrange01 = SrcDoc.Range
Set Myrange02 = SrcDoc.Range
Set Myrange03 = SrcDoc.Range
'查找第一个开始符
Myrange01.Find.ClearFormatting
With Myrange01.Find
'查找第一个字符并替换掉
.Text = StartText
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Myrange01.Find.Execute
isFind = Myrange01.Find.Found
'若找到替换符
If isFind = True Then
'查找第一个结束符
Myrange02.Find.ClearFormatting
With Myrange02.Find
.Text = EndText
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Myrange02.Find.Execute
m = Myrange01.Start
n = Myrange02.Start
m1 = Myrange01.End
n1 = Myrange02.End
'找到变量名称
Set FoundRange = SrcDoc.Range(m, n1)
OldStr = FoundRange.Text
VarName = Mid(OldStr, Len(StartText) + 1, Len(OldStr) - 6)
Debug.Print VarName
'找到数据源列
For k = 1 To ColNum
If t.Cells(12, k) = VarName Then
VarCol = k
Exit For
End If
Next k
If VarCol = 0 Then
t.Cells(i, 1) = "失败:变量名称有误。"
IsRight = False
GoTo Prev
End If
RepStr = t.Cells(i, VarCol)
'替换所有此变量
Myrange03.Find.ClearFormatting
With Myrange03.Find
.Text = OldStr
.Replacement.Text = RepStr
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Myrange03.Find.Execute Replace:=wdReplaceAll
End If
Loop While isFind = True
' TmpBody = SrcDoc.Range.Text
SavePath = PrePath & "\" & TmpFileName
Debug.Print SavePath
SrcDoc.SaveAs Filename:=SavePath, FileFormat:=wdFormatHTML, _
LockComments:=False, Password:="", AddToRecentFiles:=True, WritePassword _
:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _
SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _
False
SrcDoc.Close savechanges:=False
TmpBody = GetHtmlText(PrePath & "\" & TmpFileName)
MyFile.DeleteFile (PrePath & "\" & TmpFileName)
'生成收件人和抄送人
Dim a As String, b As String
a = t.Cells(i, 2).Value
b = t.Cells(i, 3).Value
'新建邮件
If IsRight = True Then
'对于收件人、抄送人,增加后缀@pingan.com.cn 确保如邮箱错误等情况可以看出来
If t.Cells(5, "H").Value <> "是" Then
a = Replace(a, ";", """@pingan.com.cn;""")
b = Replace(b, ";", """@pingan.com.cn;""")
a = a & """@pingan.com.cn"""
If b <> "" Then b = b & """@pingan.com.cn"""
End If
Set oItem = oOutlookApp.CreateItem(olMailItem)
With oItem
.SendUsingAccount = oAccount '设定发送邮箱
.Subject = t.Cells(i, 4)
.HTMLBody = TmpBody
'去除"号
.To = VBA.Replace(a, """", "")
.CC = VBA.Replace(b, """", "")
Debug.Print VBA.Replace(a, """", "")
Debug.Print VBA.Replace(b, """", "")
If t.Cells(i, 6) <> "" Then
.Attachments.Add ThisWorkbook.Path & "\附件\" & t.Cells(i, 6).Value
End If
.Send
End With
Set oItem = Nothing
t.Cells(i, 1) = "成功"
'显示发送到第几份
On Error Resume Next
UserForm1.ProgressBar1.Value = i - 12
On Error GoTo 0
UserForm1.Caption = "共有" & RowNum - 1 & " 封邮件待发送,正进行第" & i - 12 & "发送,请稍候!"
End If
Prev:
Next i
'卸载窗口
Unload UserForm1
Set MyFile = Nothing
wWordApp.Quit
Set wWordApp = Nothing
If bStarted = True Then
oOutlookApp.Quit
End If
Set oOutlookApp = Nothing
Private Sub CommandButton1_Click() '上传文件
Dim iarray, flname As String, a
Dim ipath As String
Dim folderexist As Boolean, FileExist As Boolean
Dim imsg As Integer, ioption As String
ipath = "\\dqsh-d8403\share\招聘"
If ListBox1.Value <> "" And TextBox1.Value <> "" Then
iarray = VBA.Split(TextBox1.Value, "\")
flname = iarray(UBound(iarray, 1))
If OptionButton1.Value = True Then
ioption = OptionButton1.Caption
ElseIf OptionButton2.Value = True Then
ioption = OptionButton2.Caption
ElseIf OptionButton5.Value = True Then
ioption = OptionButton5.Caption
ElseIf OptionButton6.Value = True Then
ioption = OptionButton6.Caption
ElseIf OptionButton7.Value = True Then
ioption = OptionButton7.Caption
ElseIf OptionButton8.Value = True Then
ioption = OptionButton8.Caption
Else
MsgBox "请选择上传类型"
Exit Sub
End If
Debug.Print ipath & "\" & iChannel & "\" & ListBox1.Value & "\" & ioption & "\*"
FileExist = (Dir(ipath & "\" & iChannel & "\" & ListBox1.Value & "\" & ioption & "\*", vbNormal + vbReadOnly + vbHidden) <> "")
If FileExist = False Then
mkfile ipath & "\" & iChannel & "\" & ListBox1.Value & "\" & ioption
FileCopy TextBox1.Value, ipath & "\" & iChannel & "\" & ListBox1.Value & "\" & ioption & "\" & flname
Else
imsg = MsgBox("已存在" & ioption & ",是否替换?", 4 + 32)
If imsg = 6 Then '替换
Kill ipath & "\" & iChannel & "\" & ListBox1.Value & "\" & ioption & "\*"
FileCopy TextBox1.Value, ipath & "\" & iChannel & "\" & ListBox1.Value & "\" & ioption & "\" & flname
Else
FileCopy TextBox1.Value, ipath & "\" & iChannel & "\" & ListBox1.Value & "\" & ioption & "\" & flname
End If
End If
Else
MsgBox "请选择员工和上传文件"
Exit Sub
End If
MsgBox "已上传"
End Sub
Private Sub CommandButton2_Click() '下载文件
Dim flpath As String, ipath As String
Dim ioption As String
Dim FileExist As Boolean
Dim i As Integer
Dim iarray, flname As String
Dim myfile As String
ipath = "\\dqsh-d8403\share\招聘"
If ListBox2.Value = "" Then
MsgBox "请选择员工"
Exit Sub
End If
If OptionButton3.Value = True Then
ioption = OptionButton3.Caption
ElseIf OptionButton4.Value = True Then
ioption = OptionButton4.Caption
ElseIf OptionButton9.Value = True Then
ioption = OptionButton9.Caption
ElseIf OptionButton10.Value = True Then
ioption = OptionButton10.Caption
ElseIf OptionButton11.Value = True Then
ioption = OptionButton11.Caption
ElseIf OptionButton12.Value = True Then
ioption = OptionButton12.Caption
Else
MsgBox "请选择下载类型"
Exit Sub
End If
myfile = Dir(ipath & "\" & iChannel & "\" & ListBox2.Value & "\" & ioption & "\*")
Debug.Print ipath & "\" & iChannel & "\" & ListBox2.Value & "\" & ioption & "\*"
If myfile <> "" Then
flpath = Application.GetSaveAsFilename(Title:="选择下载到", InitialFileName:="根据实际文件名决定-无需填写")
iarray = VBA.Split(flpath, "\")
flname = iarray(0)
For i = 1 To UBound(iarray) - 1
flname = flname & "\" & iarray(i)
Next
FileCopy ipath & "\" & iChannel & "\" & ListBox2.Value & "\" & ioption & "\" & myfile, flname & "\" & myfile
myfile = Dir
Do While myfile <> ""
FileCopy ipath & "\" & iChannel & "\" & ListBox2.Value & "\" & ioption & "\" & myfile, flname & "\" & myfile
myfile = Dir
Loop
Else
MsgBox "缺少相关附件"
Exit Sub
End If
MsgBox "已下载"
End Sub
Private Function mkfile(flpath As String)
Dim iarray, folderexist As Boolean
Dim i As Integer, tmppath As String
iarray = VBA.Split(flpath, "\")
tmppath = iarray(0)
For i = 1 To UBound(iarray, 1)
tmppath = tmppath & "\" & iarray(i)
If i > 3 Then
folderexist = (Dir(tmppath, vbDirectory + vbHidden) <> "")
If folderexist = False Then
MkDir tmppath
End If
End If
Next
End Function
实现查、删、改、增等基础sql操作,以及事件调用、数据表创建等复杂操作。
Sub Test()
Dim Conn As Object, Rst As Object
Dim strConn As String, strSQL As String
Dim i As Integer, PathStr As String
Set Conn = CreateObject("ADODB.Connection")
Set Rst = CreateObject("ADODB.Recordset")
PathStr = ThisWorkbook.FullName '设置工作簿的完整路径和名称
Select Case Application.Version * 1 '设置连接字符串,根据版本创建连接
Case Is <= 11
strConn = "Provider=Microsoft.Jet.Oledb.4.0;ExtendedProperties=excel8.0;Datasource=" & PathStr
Case Is >= 12
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;DataSource=" & PathStr & ";ExtendedProperties=""Excel12.0;HDR=YES"";"""
End Select '设置SQL查询语句
strSQL = "请写入SQL语句"
Conn.Open strConn '打开数据库链接
Set Rst = Conn.Execute(strSQL) '执行查询,并将结果输出到记录集对象
With Sheet3.Cells.Clear
For i = 0 To Rst.Fields.Count - 1 '填写标题
.Cells(1, i + 1) = Rst.Fields(i).Name
Next i
.Range("A2").CopyFromRecordset Rst
.Cells.EntireColumn.AutoFit '自动调整列宽
End With
Rst.Close '关闭数据库连接
Conn.Close
Set Con = Nothing
End Sub
'此类用于所有与sql数据库的主连接及相关的数据操作
Dim MainCnn As ADODB.Connection
Dim MainPath As String
Dim MyRs As ADODB.Recordset
Property Get MyCon() As ADODB.Connection
Set MyCon = MainCnn
End Property
Public Function GetConState() As Boolean
If MainCnn Is Nothing Then
GetConState = False
ElseIf MainCnn.State = adStateClosed Then
GetConState = False
Else
GetConState = True
End If
End Function
Public Sub Ini(Path As String)
MainPath = Trim(Path)
End Sub
Public Function ConOpen()
Set MainCnn = New ADODB.Connection
Set MyRs = New ADODB.Recordset
ConOpen = True
On Error GoTo errDo:
With MainCnn
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & MainPath & "; Jet OLEDB:Database Password=" & MaxPwdCell
' .ConnectionString = "DBQ=" & ThisWorkbook.Path & "\归集表数据库.mdb;" & _
' "Driver={Microsoft Access Driver (*.mdb)};" & _
' "uid=admin;Password=seudit;"
'此处代码用于和access数据库连接
'Debug.Print .ConnectionString
.Open
End With
On Error GoTo 0
ConOpen = "Fine"
Exit Function
errDo:
' Debug.Print MainPath
ConOpen = "数据源尚未连接或有误,请配置正确的数据源地址。"
End Function
Public Function ConOpenByStr()
Set MainCnn = New ADODB.Connection
Set MyRs = New ADODB.Recordset
ConOpenByStr = True
On Error GoTo errDo:
With MainCnn
.ConnectionString = MainPath
.CommandTimeout = 180
.ConnectionTimeout = 180
.Open
.CursorLocation = adUseClient
End With
On Error GoTo 0
ConOpenByStr = "Fine"
Exit Function
errDo:
ConOpenByStr = "数据源尚未连接或有误,请配置正确的数据源地址。"
End Function
'传入Sql的select
Public Function GetRs(sql As String, Optional IsReadOnly As Boolean = True) As ADODB.Recordset
If IsReadOnly = True Then
MyRs.Open sql, MainCnn, adOpenKeyset, adLockReadOnly
Else
MyRs.Open sql, MainCnn, adOpenKeyset, adLockOptimistic
End If
Set GetRs = MyRs
End Function
Public Function CloseRs() As String
MyRs.Close
End Function
Public Function ConClose() As String
MainCnn.Close
End Function
'传入Sql的Delete
Public Function DelRs(sql As String) As String
MainCnn.Execute (sql)
End Function
'传入Sql的Insert
Public Function InsertRsBySql(sql As String) As String
MainCnn.Execute (sql)
End Function
'传入数据区域的的Insert,必须保证数据库表结构与导入区域结构一致
Public Function InsertRsByRange(UseRange As Range, InsertTName As String, NeedID As Boolean) As String
Dim sql As String
Dim RNum As Integer, CNum As Integer
RNum = UseRange.Rows.Count
CNum = UseRange.Columns.Count
For i = 1 To RNum
If NeedID = True Then
sql = "insert into " & InsertTName & " values(" & i & ",'"
Else
sql = "insert into " & InsertTName & " values('"
End If
For j = 1 To CNum
sql = sql & Trim(UseRange.Cells(i, j)) & "','"
Next j
sql = Left(sql, Len(sql) - 2) & ")"
Debug.Print sql
MainCnn.Execute (sql)
Next i
End Function
Sub 主程序()
Dim ie As InternetExplorer, id As String, i As Integer, r As Integer
Set ie = CreateObject("internetExplorer.application") '创建一个空的ie
ie.Visible = True '让ie可见
ie.Navigate "http://xxxxxxxxx"
Do While ie.ReadyState <> 4 Or ie.Busy '等待ie完毕加载
DoEvents
Loop
r = Me.Cells(1, 1).CurrentRegion.Rows.Count
For i = 2 To r '滚动维护数据
If Me.Cells(i, 2).Value = "是" Then
Else
id = Me.Cells(i, 1).Value
zdtx2015 ie, id '维护主模块
Me.Cells(i, 2).Value = "是"
End If
Next
End Sub
Function zdtx2015(ie As InternetExplorer, id As String)
Dim ie2, i As Integer, ie3, ie4, ie5, ie7, ie6, ie8, ie9
Set ie2 = ie.Document.frames(0).Document.getElementById("EMPLMT_SRCH_COR_EMPLID")
Do Until Not ie2 Is Nothing
DoEvents
Set ie2 = ie.Document.frames(0).Document.getElementById("EMPLMT_SRCH_COR_EMPLID")
Loop
ie2.Value = id '输入员工ID"
Set ie4 = ie.Document.frames(0).Document.getElementsByTagName("INPUT")(33)
ie4.Click '点击搜索
Set ie5 = ie.Document.frames(0).Document.getElementsByTagName("INPUT")(26)
Do Until ie5.Value = "职位数据覆盖"
DoEvents
Set ie5 = ie.Document.frames(0).Document.getElementsByTagName("INPUT")(26)
Loop
ie5.Click '职务数据覆盖点一下\
Set ie8 = ie.Document.frames(0).Document.getElementById("#ICList")
ie8.Click '返回
'SendKeys "%1"
End Function
Dim tree, itree, iColCount As Integer
'Set tree = CreateObject("scripting.dictionary") '创建树
'已1开始的数组中,节点i的n个子节点的下标为ni和ni+1;而其父节点的下标为int(i,n)
Sub 决策树()
Dim arr, arr0, dichx, tree, dic, loc As Long, brr, crr
arr = Me.Cells(1, 1).CurrentRegion '数据源
arr0 = Me.Cells(2, 1).Resize(UBound(arr, 1) - 1, UBound(arr, 2)) '训练元组
Set dichx = CreateObject("scripting.dictionary") '候选属性的集合
For i = 2 To UBound(arr, 2) - 1
dichx(arr(1, i)) = i
Next
Set dic = CreateObject("scripting.dictionary") '有多少结果值
For i = 1 To UBound(arr0, 1)
If dic.exists(arr0(i, UBound(arr0, 2))) Then
dic(arr0(i, UBound(arr0, 2))) = dic(arr0(i, UBound(arr0, 2))) + 1
Else
dic(arr0(i, UBound(arr0, 2))) = 1
End If
Next
Set tree = CreateObject("scripting.dictionary") '创建类树
Set itree = CreateObject("scripting.dictionary") '创建分叉树
loc = 1: iColCount = UBound(arr, 2) - 2 '属性量
generate_decision_tree arr0, dichx, loc, dic, tree, itree
crr = tree.keys
Me.Cells(1, 9).Resize(1, UBound(crr) + 1) = crr
crr = tree.items
Me.Cells(2, 9).Resize(1, UBound(crr) + 1) = crr
crr = itree.keys
Me.Cells(3, 9).Resize(1, UBound(crr) + 1) = crr
crr = itree.items
For i = 0 To UBound(crr)
For j = 0 To UBound(crr(i))
Me.Cells(4, 9).Offset(j, i) = crr(i)(j)
Next
Next
If Not tree.exists(1) Then Exit Sub
tree_print tree, itree, 1, Me.Cells(9, 9), iColCount
End Sub
Function tree_print(tree, itree, x As Long, ByRef rg As Range, iColCount As Integer)
If tree.exists(x) Then
If itree.exists(x) Then
rg.Value = tree(x) & "#" & x
If IsArray(itree(x)) Then
arr = itree(x)
rg.Offset(1, 0).Resize(1, UBound(arr, 1) + 1) = arr
For i = 0 To UBound(arr, 1)
rg.Offset(2, i) = tree(x * iColCount + i) & "#" & x * iColCount + i
Next
Set rg = rg.Offset(4, 0)
For i = 0 To UBound(arr, 1)
tree_print tree, itree, x * iColCount + i, rg, iColCount
Next
End If
End If
End If
End Function
Function generate_decision_tree(arr0, dichx, loc, dic0, tree, itree) '建立决策树
Dim brr0(), split_list(), brr(1 To 20, 1 To 100, 1 To 10)
'Set generate_decision_tree = CreateObject("scripting.dictionary")
If dichx.Count = 0 Then Exit Function
ikey = attri_selection_method(arr0, dichx, dic0) '找到一个最好的划分元祖为个体的属性
iitem = dichx(ikey)
dichx.Remove ikey
tree(loc) = ikey
Set dic = CreateObject("scripting.dictionary") '创建一个包含所有该属性分类的字典
For i = 1 To UBound(arr0, 1)
If arr0(i, 1) = "" Then Exit For
If dic.exists(arr0(i, iitem)) Then '维护组信息
dic(arr0(i, iitem)) = dic(arr0(i, iitem)) + 1
For j = 1 To dic.Count
If arr0(i, iitem) = split_list(j - 1) Then
For x = 1 To UBound(arr0, 2)
brr(j, dic(arr0(i, iitem)), x) = arr0(i, x)
Next
End If
Next
Else
'ReDim Preserve split_list(1 To dic.Count + 1) '创建组类记录表
'split_list(dic.Count + 1) = arr0(i, iitem) '保存组名称
dic(arr0(i, iitem)) = 1 '记录组数量
split_list = dic.keys
'ReDim Preserve brr(1 To dic.Count, 1 To UBound(arr0, 1), 1 To UBound(arr0, 2)) '维护组信息
For j = 1 To dic.Count
If arr0(i, iitem) = split_list(j - 1) Then
For x = 1 To UBound(arr0, 2)
brr(j, dic(arr0(i, iitem)), x) = arr0(i, x)
Next
End If
Next
End If
Next
iDicCount = dic.Count
For i = 1 To iDicCount
ReDim brr0(1 To UBound(arr0, 1), 1 To UBound(arr0, 2)) '创建分组表
Set dic = CreateObject("scripting.dictionary")
For x = 1 To UBound(brr0, 1)
If brr(i, x, 1) = "" Then
Exit For
Else
For y = 1 To UBound(brr0, 2)
brr0(x, y) = brr(i, x, y)
If dic.exists(brr(i, x, UBound(brr0, 2))) Then
dic(brr(i, x, UBound(brr0, 2))) = dic(brr(i, x, UBound(brr0, 2))) + 1
Else
dic(brr(i, x, UBound(brr0, 2))) = 1
End If
Next
End If
Next
If dic.Count = 1 Then '如果这个分组都是一个ans
itree(loc) = split_list
tree(iColCount * loc + i - 1) = brr0(1, UBound(brr0, 2))
'Set itree = tree
'itree(split_list(i)) = dic.keys(0)
Else
'ReDim Preserve brr0(1 To x - 1, 1 To UBound(brr0, 2))
'Set itree(split_list(i)) = CreateObject("scripting.dictionary")
'Set iitree = itree(split_list(i))
itree(loc) = split_list
generate_decision_tree brr0, dichx, iColCount * loc + i - 1, dic, tree, itree
End If
Set dic = Nothing
Next
End Function
Function attri_selection_method(arr0, dichx, dic_ans) '最优信息度提升模型
Dim icomput
ReDim icomput(1 To dichx.Count)
endcol = UBound(arr0, 2)
arr_key = dichx.keys
ordcomput = 0 '获取初始信息度
For Each Item In dic_ans.items
ordcomput = ordcomput - Item / UBound(arr0, 1) * Log(Item / UBound(arr0, 1)) / Log(2)
Next
k = 0
For Each Item In dichx.keys '对每个条件列
Set dic_comput = CreateObject("scripting.dictionary")
irow = dichx(Item)
For j = 1 To UBound(arr0, 1) '获取每个子条件的结果分布
If dic_comput.exists(arr0(j, irow)) Then
If dic_comput(arr0(j, irow)).exists(arr0(j, endcol)) Then
dic_comput(arr0(j, irow))(arr0(j, endcol)) = dic_comput(arr0(j, irow))(arr0(j, endcol)) + 1
Else
dic_comput(arr0(j, irow))(arr0(j, endcol)) = 1
End If
Else
Set dic_comput(arr0(j, irow)) = CreateObject("scripting.dictionary")
End If
Next
allans = 0
For Each ikey In dic_comput.keys '对每个子条件
ans = 0
totalans = 0
For Each supikey In dic_comput(ikey).keys
totalans = totalans + dic_comput(ikey)(supikey)
Next
For Each supikey In dic_comput(ikey).keys '求和子条件信息度
Debug.Print totalans
Debug.Print dic_comput(ikey)(supikey)
ans = ans - dic_comput(ikey)(supikey) / totalans * Log(dic_comput(ikey)(supikey) / totalans) / Log(2)
Next
allans = allans + totalans / UBound(arr0, 1) * ans
Next
k = k + 1
icomput(k) = allans '获取最终的信息度
Next
Min = 2
For i = 1 To UBound(icomput, 1)
If icomput(i) < Min Then
Min = icomput(i)
attri_selection_method = arr_key(i - 1)
End If
Next
End Function