论文部分内容阅读
上期讲到:VBS脚本中,过程(procedure)/函数(function)是构成语句(sentence)的重要部分。VBScript内部函数大致分为:数组处理函数、换算函数、日期/时间函数、格式化字符串函数、输入/输出函数、数学函数、杂项函数、对象函数、舍入函数、脚本引擎 ID 函数、字符串函数和变量(variant)函数等十二类,目前约有89个函数。可以使用Function语句和Sub语句自定义一个过程(函数)来完成各种任务,甚至可以递归(recursive),即该过程调用自身完成给定的任务。Function语句与Sub语句自定义的过程不同之处在于当要使用函数返回值时,可以在表达式的右边使用Function过程,这跟使用内部函数一样,而不能使用Sub过程。无论调用内部函数还是自定义过程,当不使用函数返回值时,可以使用关键字Call用括号把参数列表括起来,否则应当省略参数列表两边的括号。下面介绍For Each...Next循环语句和用法。
一、搜索指定文件给定关键词的文件并将结果输出到文件
Windows的“搜索”功能虽然十分强大,但美中不足有:1.除了一次可以搜索本地硬盘所有分区外无法搜索多个任意指定的文件夹;2.只能在“搜索结果”中对搜索到的文件/文件夹进行查看、编辑、复制、删除或移动操作,无法将搜索到的结果直接输出到文本文档供用户重复使用。本期范例可一次搜索多个任意指定的文件夹(包括分区),提供三个高级选项,并将搜索结果输出到文本文档。由于篇幅有限,本期脚本不支持“?*”通配符(算法要复杂许多),下期脚本范例介绍使用“?*”通配符搜索。
Const WINDOW_HANDLE = 0, OPTIONS = 16, MY_COMPUTER = 17
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const Sub_Folder = 0, Folder_Name = 1, Match_Case = 2
On Error Resume Next
arrOptions = Array(0, 0, 0)
arrOptionMsg = Array("您希望搜索子文件夹吗?", "您希望搜索文件夹名吗?", _
"您希望区分大小写搜索吗?")
For I = 0 To 2
intValue = MsgBox(arrOptionMsg(I), vbYesNo + vbQuestion, "高级选项")
If intValue = vbYes Then arrOptions(I) = 1
Next
strMsg = "请输入全部或部分文件名,不支持*?通配符,然后单击“确定”。"
strFindKeyWord = InputBox(strMsg, "要搜索的文件名")
strMsg = "输入要搜索的文件名无效,程序结束。"
If strFindKeyWord = "" Then ErrorAndQuit(strMsg)
strMsg = "请选择要搜索的文件夹,然后单击“确定”。单击“取消”或按"&_
"“Esc”键结束选择。"
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Do
Set objFolder = objShell.BrowseForFolder _
(WINDOW_HANDLE, strMsg, OPTIONS, MY_COMPUTER)
If objFolder Is Nothing Then Exit Do
Set objFolderItem = objFolder.Self
strPath = objFolderItem.Path
If Not objFso.FolderExists(strPath) Then
strMsg1 = "无法搜索文件夹“" & objFolderItem & "”,请另选一个。"
Msgbox strMsg1, vbCritical, "错误" : intMyErr = 1
End If
If 0 <> InStr(StrFolders, strPath & vbCrLf) Then
strMsg1 = "已选择了文件夹“" & strPath & "”,请另选一个。"
Msgbox strMsg1, vbCritical, "错误" : intMyErr = 1
ElseIf arrOptions(Sub_Folder) = 1 And intMyErr <> 1 Then
Set objFolder = objFso.GetFolder(strPath)
Do Until objFolder.IsRootFolder
Set objFolder = objFolder.ParentFolder
If 0 <> InStr(StrFolders, objFolder.Path) Then
strMsg1 = "所选择文件夹已包含“" & strPath & "”,请另选一个。"
Msgbox strMsg1, vbCritical, "错误" : intMyErr = 1 : Exit Do
End If
Loop
End If
If intMyErr = 0 Then StrFolders = StrFolders & strPath & vbCrLf
intMyErr = 0
Loop
strMsg = "没有选择任何可搜索的文件夹,程序结束。"
If StrFolders = "" Then ErrorAndQuit(strMsg)
arrFolders = Split(strFolders, vbCrLf)
ReDim Preserve arrFolders(UBound(arrFolders) - 1)
strFoundFile = ""
For Each strFolder In arrFolders
SearchTheName objFso.GetFolder(strFolder)
Next
strSearchFile = "C:\Search.txt"' 搜索结果输出文件可设置为自己的文件
Set objFile = objFso.OpenTextFile(strSearchFile, ForWriting, True)
objFile.Write strFoundFile
objFile.Close
MsgBox "所选文件夹搜索完毕,请查看记录文件。", vbInformation, "消息"
Sub SearchTheName(objFolder)
If arrOptions(Folder_Name) = 1 Then
For Each objSubFolder In objFolder.SubFolders
strName = objSubFolder.Name
If FindInName(strName, strFindKeyWord) Then
strFoundFile = strFoundFile & objSubFolder.Path & vbCrLf
End If
Next
End If
For Each objFile In objFolder.Files
strName = objFile.Name
If FindInName(strName, strFindKeyWord) Then
strFoundFile = strFoundFile & objFile.Path & vbCrLf
End If
Next
If arrOptions(Sub_Folder) <> 1 Then Exit Sub
For Each objSubfolder In objFolder.SubFolders
SearchTheName objSubfolder
Next
End Sub
Function FindInName(strName, strFindWord)
FindInName = InStr(1, strName, strFindWord, _
arrOptions(Match_Case) Xor 1)
End Function
Function ErrorAndQuit(strErrMsg)
Msgbox strErrMsg, vbCritical, "错误"
Wscript.Quit
End Function
二、通透理解For Each...Next循环语句
1.For Each...Next循环语句
For Each...Next语句也是最常用的语句之一,用于对数组(array)或集合(collection)中的每个元素重复执行一组语句从而获得预期的计算结果。可以通俗地这样理解:假定一个筐中有未知的n个编号(索引号)的彩球,每次从筐中按编号顺序(起始号为0)拿出一个球,根据球的颜色要执行一系列不同的任务,或者对球执行一系列相同的任务,一直到球拿完为止。这里的球称作“元素”,用来枚举集合或数组中所有元素的变量,可能是Variant变量、通用Object变量或者指定的Automation对象变量。筐称作“组”,对象集合或数组的名称。
2.For Each...Next语句的用法
For Each 元素 In 组
[语句]
[Exit For]
[语句]
Next [元素]
当“组”中至少有一个元素时,For Each...Next才会启动。当循环启动时,首先对“组”中的第一个元素执行循环中的所有语句,只要“组”中还有其他元素,就会对每个元素执行循环中的语句,一直到“组”中没有其他元素时结束循环。其中当遇到经常由If...Then语句判断结果为真值执行Exit For语句即退出循环。同样,For Each...Next循环语句可以多重嵌套循环,但是每个循环的“元素”必须是唯一的。
3.下期预告:介绍Do...Loop和While...Wend语句和用法。
一、搜索指定文件给定关键词的文件并将结果输出到文件
Windows的“搜索”功能虽然十分强大,但美中不足有:1.除了一次可以搜索本地硬盘所有分区外无法搜索多个任意指定的文件夹;2.只能在“搜索结果”中对搜索到的文件/文件夹进行查看、编辑、复制、删除或移动操作,无法将搜索到的结果直接输出到文本文档供用户重复使用。本期范例可一次搜索多个任意指定的文件夹(包括分区),提供三个高级选项,并将搜索结果输出到文本文档。由于篇幅有限,本期脚本不支持“?*”通配符(算法要复杂许多),下期脚本范例介绍使用“?*”通配符搜索。
Const WINDOW_HANDLE = 0, OPTIONS = 16, MY_COMPUTER = 17
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const Sub_Folder = 0, Folder_Name = 1, Match_Case = 2
On Error Resume Next
arrOptions = Array(0, 0, 0)
arrOptionMsg = Array("您希望搜索子文件夹吗?", "您希望搜索文件夹名吗?", _
"您希望区分大小写搜索吗?")
For I = 0 To 2
intValue = MsgBox(arrOptionMsg(I), vbYesNo + vbQuestion, "高级选项")
If intValue = vbYes Then arrOptions(I) = 1
Next
strMsg = "请输入全部或部分文件名,不支持*?通配符,然后单击“确定”。"
strFindKeyWord = InputBox(strMsg, "要搜索的文件名")
strMsg = "输入要搜索的文件名无效,程序结束。"
If strFindKeyWord = "" Then ErrorAndQuit(strMsg)
strMsg = "请选择要搜索的文件夹,然后单击“确定”。单击“取消”或按"&_
"“Esc”键结束选择。"
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Do
Set objFolder = objShell.BrowseForFolder _
(WINDOW_HANDLE, strMsg, OPTIONS, MY_COMPUTER)
If objFolder Is Nothing Then Exit Do
Set objFolderItem = objFolder.Self
strPath = objFolderItem.Path
If Not objFso.FolderExists(strPath) Then
strMsg1 = "无法搜索文件夹“" & objFolderItem & "”,请另选一个。"
Msgbox strMsg1, vbCritical, "错误" : intMyErr = 1
End If
If 0 <> InStr(StrFolders, strPath & vbCrLf) Then
strMsg1 = "已选择了文件夹“" & strPath & "”,请另选一个。"
Msgbox strMsg1, vbCritical, "错误" : intMyErr = 1
ElseIf arrOptions(Sub_Folder) = 1 And intMyErr <> 1 Then
Set objFolder = objFso.GetFolder(strPath)
Do Until objFolder.IsRootFolder
Set objFolder = objFolder.ParentFolder
If 0 <> InStr(StrFolders, objFolder.Path) Then
strMsg1 = "所选择文件夹已包含“" & strPath & "”,请另选一个。"
Msgbox strMsg1, vbCritical, "错误" : intMyErr = 1 : Exit Do
End If
Loop
End If
If intMyErr = 0 Then StrFolders = StrFolders & strPath & vbCrLf
intMyErr = 0
Loop
strMsg = "没有选择任何可搜索的文件夹,程序结束。"
If StrFolders = "" Then ErrorAndQuit(strMsg)
arrFolders = Split(strFolders, vbCrLf)
ReDim Preserve arrFolders(UBound(arrFolders) - 1)
strFoundFile = ""
For Each strFolder In arrFolders
SearchTheName objFso.GetFolder(strFolder)
Next
strSearchFile = "C:\Search.txt"' 搜索结果输出文件可设置为自己的文件
Set objFile = objFso.OpenTextFile(strSearchFile, ForWriting, True)
objFile.Write strFoundFile
objFile.Close
MsgBox "所选文件夹搜索完毕,请查看记录文件。", vbInformation, "消息"
Sub SearchTheName(objFolder)
If arrOptions(Folder_Name) = 1 Then
For Each objSubFolder In objFolder.SubFolders
strName = objSubFolder.Name
If FindInName(strName, strFindKeyWord) Then
strFoundFile = strFoundFile & objSubFolder.Path & vbCrLf
End If
Next
End If
For Each objFile In objFolder.Files
strName = objFile.Name
If FindInName(strName, strFindKeyWord) Then
strFoundFile = strFoundFile & objFile.Path & vbCrLf
End If
Next
If arrOptions(Sub_Folder) <> 1 Then Exit Sub
For Each objSubfolder In objFolder.SubFolders
SearchTheName objSubfolder
Next
End Sub
Function FindInName(strName, strFindWord)
FindInName = InStr(1, strName, strFindWord, _
arrOptions(Match_Case) Xor 1)
End Function
Function ErrorAndQuit(strErrMsg)
Msgbox strErrMsg, vbCritical, "错误"
Wscript.Quit
End Function
二、通透理解For Each...Next循环语句
1.For Each...Next循环语句
For Each...Next语句也是最常用的语句之一,用于对数组(array)或集合(collection)中的每个元素重复执行一组语句从而获得预期的计算结果。可以通俗地这样理解:假定一个筐中有未知的n个编号(索引号)的彩球,每次从筐中按编号顺序(起始号为0)拿出一个球,根据球的颜色要执行一系列不同的任务,或者对球执行一系列相同的任务,一直到球拿完为止。这里的球称作“元素”,用来枚举集合或数组中所有元素的变量,可能是Variant变量、通用Object变量或者指定的Automation对象变量。筐称作“组”,对象集合或数组的名称。
2.For Each...Next语句的用法
For Each 元素 In 组
[语句]
[Exit For]
[语句]
Next [元素]
当“组”中至少有一个元素时,For Each...Next才会启动。当循环启动时,首先对“组”中的第一个元素执行循环中的所有语句,只要“组”中还有其他元素,就会对每个元素执行循环中的语句,一直到“组”中没有其他元素时结束循环。其中当遇到经常由If...Then语句判断结果为真值执行Exit For语句即退出循环。同样,For Each...Next循环语句可以多重嵌套循环,但是每个循环的“元素”必须是唯一的。
3.下期预告:介绍Do...Loop和While...Wend语句和用法。