Anda di halaman 1dari 38

Excel VBA 编程

- 文件操作

Winland
目录
• 文件、文件夹对话框
• 文件搜索
• 文件、文件夹操作
• 文本文件读写
• FSO 介绍
GetOpenFilename
Sub OpenFile()
Dim strFile As String
strFile = Application.GetOpenFilename("Excel 文件 (*.xls),*.xls", , " 请选择 Excel 文件 ", , False)
If strFile <> "False" Then
If MsgBox(" 你要打开以下 Excel 文件吗? " & vbCrLf & strFile, vbOKCancel) = vbOK Then
Workbooks.Open strFile
End If
End If
End Sub

• 运行结果
语法
GetOpenFilename(FileFilter, FilterIndex, Title, ButtonText, MultiSelect)

• 语法
• FileFilter 文件筛选条件,由一个文件筛选字符串和通配符表达的文件筛选规则
说明组成,以逗号分开
• “Excel 文件 (*.xls),*.xls” 表示只显示 Excel 文件;
• “Excel 文件 (*.xls),*.xls,Word 文件 (*.doc),*.doc” 表示在文件类型的
下拉框中出现 Excel 和 Word 两种文件类型;
• “Excel 和 Word 文件 (*.xls;*.doc),*.xls;*.doc” 表示同时显示 Excel
文件和 Word 文件;
• 省略这个参数的话表示所有文件类型。
• Title 表示显示在文件对话框标题栏的内容
• MultiSelect 表示是否可以多选, True 表示多选,默认是 False
• 选择“取消”按钮或关闭对话框,返回 False
• 选择“打开”按钮,返回选择文件的完整路径,但不打开文件。
• 两种表示方法
• GetOpenFilename("Excel 文件 (*.xls),*.xls", , " 请选择 Excel 文件 ", ,
False)
• GetOpenFilename(FileFilter:="Excel 文件 (*.xls),*.xls", Title:=" 请选
择 Excel 文件 ", MultiSelect:=False)
文件多选
Sub OpenFiles()
Dim vFile As Variant
Dim i As Integer
vFile = Application.GetOpenFilename(FileFilter:="Excel 文件 (*.xls),*.xls", Title:=" 请选择 Excel 文件 ", MultiSelect:=True)
If IsArray(vFile) Then
For i = 1 To UBound(vFile)
Workbooks.Open vFile(i)
Next i
End If
End Sub

• 文件多选
 返回一个包含所选(一个或多个)文件路径的数组。
 如关闭对话框或点击“取消”按钮,则返回 False 。

• 练习
 使用 GetSaveAsFilename 方法打开“另存为”窗口输入文件名以保
存活动工作簿
FileDialog 对象
Sub OpenFileDialog()
Dim fDialog As FileDialog
Set fDialog = Application.FileDialog(msoFileDialogOpen)
With fDialog
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "Excel 文件 ", "*.xls"
If .Show = -1 Then Workbooks.Open .SelectedItems(1)
End With
Set fDialog = Nothing
End Sub

• AllowMultiSelect 属性表示多选
• 需要先使用 Clear 方法清除文件筛选条件然后再
使用 Add 方法添加
• 使用 Show 方法打开文件对话框,如果单击“
打开”按钮则返回 -1 ,单击“取消”按钮返回
0 。返回的路径保存在
FileDialog.SelectedItems 集合中。
文件夹对话框

• FileDialog 的参数 msoFileDialogType 类型

• 练习
使用 FileDialog 对象获取所选择的文件夹路径
目录
• 文件、文件夹对话框
• 文件搜索
• 文件、文件夹操作
• 文本文件读写
• FSO 介绍
Dir 函数
• 语法 Dir[(pathname[,attributes])]
• pathname 可选参数,指定路径和文件名,可以使用
* 和 ? 通配符。
 * 匹配任意个字符,如“ *.xls” 匹配所有 Excel 工作簿文件
 ? 匹配单个字符,如“ text*.txt” 匹配如
text1.txt 、 texta.txt 等文件,但不匹配 texta1.txt 文

• attributes 可选参数,指定文件属性,可为下列任一
常量或之和。
vbNormal 常规,值 0
vbReadOnly 只读,值 1
vbHidden 隐藏,值 2
vbSystem 系统文件,值 4
vbDirectory 文件夹,值 16
使用 Dir 函数
Sub ListExcelFiles()
Dim strPath As String, strTemp As String
Dim fDialog As FileDialog
Dim i As Integer
Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
If fDialog.Show = -1 Then
strPath = fDialog.SelectedItems(1)
Else
Exit Sub
End If
Set fDialog = Nothing
strTemp = Dir(strPath & "\*.xls")
i=1
Do While strTemp <> ""
Cells(i, 1) = strTemp
i=i+1
strTemp = Dir
Loop
End Sub

• 第一次调用 Dir 函数一定需要 pathname 参数,返回匹配到的第一个文件名



• 如需继续匹配文件,需再次调用 Dir 函数,这次调用不需参数。
• 练习
• 如果没有匹配到的文件,返回空字符串,所以一般使用 Do While 循环。

分别写出判断文件或文件夹是否存在的自定义函数
FileSearch 对象
• 如果需要跟多的定制搜索功能(如按日期或大小排序,搜索子目录文件),使用
FileSearch 对象
• Execute 方法的 SortBy 参数: msoSortBySize 以文件大小排序 ,
msoSortByFileName 以文件名排序 , msoSortByFileType 以文件类型排序 ,
msoSortByLastModified 以最后修改日期排序 , msoSortByNone 不排序
Sub SearchFiles()
Dim strPath As String
Dim fDialog As FileDialog
Dim i As Integer
Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
If fDialog.Show = -1 Then
strPath = fDialog.SelectedItems(1)
Else
Exit Sub
End If
With Application.FileSearch
.NewSearch
.LookIn = strPath
.SearchSubFolders = True
.Filename = "*.xls;*.doc"
.Execute SortBy:=msoSortBySize, SortOrder:=msoSortOrderDescending
If .FoundFiles.Count > 0 Then
For i = 1 To .FoundFiles.Count
Cells(i, 1).Value = .FoundFiles(i)
Next
End If
End With
End Sub
目录
• 文件、文件夹对话框
• 文件搜索
• 文件、文件夹操作
• 文本文件读写
• FSO 介绍
CurDir 函数

• 语法 CurDir([drive])
• drive 可选参数 , 省略的话使用当前驱动器
返回文件路径,表示当前文件夹名称
• 如果当前驱动器是 C 的话,下面的语句返
回相同的结果
• CurDir
• CurDir(“”)
• CurDir(“C”)
• CurDir(“D”) 则返回驱动器 D 的当前文件
夹路径
ChDir 和 ChDrive 语句

• ChDir path 改变当前文件夹


• 如果 path 没有指定驱动器,则是改变当前驱
动器上的当前文件夹
• ChDir(“D:\temp”) 改变 D 盘的当前文件夹,
但不改变当前驱动器
• ChDrive drive 改变当前驱动器
• drive 参数指定一个存在的驱动器,如果使用
零长度字符串“”,则不会改变当前驱动器。
如果 drive 参数有多个字符,则使用第一个字

• 例如: ChDrive “DEF” 与 ChDrive “D” 相
Name 语句

• Name oldpathname As newpathname


重命名文件或文件夹
• oldpathname 表示想要重命名的文件或文件夹的路
径和名称, newpathname 表示文件或文件夹的新
名称
• 使用 Name 语句可以将一个文件从一个文件夹移动到
另外一个文件夹并重命名,但不能移动文件夹
• 新文件名称不能指向已经存在的文件
• 不能移动已经打开的文件
• Name “C:\test.txt” As “C:\1\test.txt”
• Name “C:\test.txt” As “C:\1\newtest.txt”
• Name “C:\test.txt” As “C:\newtest.txt”
Kill 语句

• Kill pathname 删除文件


• Pathname 指定要删除的一个或多个文件的
名称,可以包括驱动器和文件夹名称。
• 可以使用通配符( * 和 ? )来匹配多个文件一
次删除
• 不能删除已经打开的文件
• Kill “C:\test\test.txt” 删除指定目录下
的 test.txt 文件
• Kill “C:\test\*.txt” 删除指定目录下所有
的 txt 文本文件
FileCopy 语句

• FileCopy source,destination 复制
文件
• source 指定要复制的文件名称
• destination 指定复制的目的地
• 不能复制已经打开的文件
• FileCopy “C:\t1.txt”,“C:\1\t1.txt”
• FileCopy “C:\t1.txt”,“C:\1\t2.txt”
FileLen 和 FileDateTime 函数

• FileLen(pathname) 获取文件大小
• Pathname 是一个字符串,指定需要处理的
文件,可以包括驱动器和文件夹名称
• 该函数以字节方式返回文件大小
• 如果该文件已打开,返回该文件最后一次保存
时的大小
• FileDateTime(pathname) 获取文件
最后修改的日期和时间
• 该函数返回指定文件的日期和时间印记,格式
取决于控制面板的区域设置
GetAttr 和 SetAttr 函数

• GetAttr(pathname) 返回一个整数表示文件
的属性,这个整数表示下列常量中的一个或多个
常量之和(参考Dir函数)
• 要知道文件是否具有某个属性,可以使用 AND 运算符
将 GetAttr 函数的结果与常量数值比较,如果返回一
个非零数值,则该文件具有这个属性
• GetAttr(“C:\test.txt” AND vbHidden
• SetAttr pathname,attributes 设置一个文
件或文件夹的属性
• attributes 表示一个或多个要设置的属性常量
• SetAttr “C:\test.txt”, vbReadOnly+vbHidden
MkDir 和 RmDir 语句

• MkDir path 创建一个文件夹


• path 指定要创建的新文件夹名称,如果没有
指定驱动器,则在当前驱动器上创建新文件夹
• RmDir path 删除一个文件夹
• path 指定要删除的文件夹名称,如果忽略驱
动器名称,将试图删除当前驱动器下存在的相
同名称的文件夹。否则,显示错误信息“路径
未找到”
• 使用 RmDir 语句只能移除空文件夹,如果
改文件夹包含文件,不可使用该语句,需
要先用 Kill 语句删除这些文件
目录
• 文件、文件夹对话框
• 文件搜索
• 文件、文件夹操作
• 文本文件读写
• FSO 介绍
Open 语句
• Open pathname For mode [Access access]
[lock] As [#] filenumber
• pathname 必要参数,文件名。可以包括文件夹和驱动器,如果
没有知道文件夹的话则表示当前目录下的文件
• mode 必要参数,文件打开方式。
 Input 打开顺序文件读取数据
 Output 打开顺序文件覆盖写入
 Append 打开顺序文件追加写入
 Binary 打开二进制文件
 Random 打开随机文件,默认值
• access 可选参数,对打开的文件可以进行的操作,有 Read 、
Write 或 Read Write
• lock 可选参数,限定其它程序对打开文件的操作,有
Shared 、 Lock Read 、 Lock Write 和 Lock Read
Write
• filenumber 必要参数,文件号,数值范围 1 到 511 ,可以使用
FreeFile 语句产生
读取文本文件
Sub ReadTextFile()
Dim strTemp As String, strContent As String
Dim filenum As Integer
Dim strFile As String
strFile = Application.GetOpenFilename(" 文本文件 (*.txt),*.txt", , " 请选择文本文件 ", , False)
If strFile = "False" Then Exit Sub
filenum = FreeFile
Open strFile For Input As #filenum
strContent = " 文件长度为: " & LOF(filenum) & " 字节 "
Do While Not EOF(filenum)
Line Input #filenum, strTemp
strContent = strContent & vbCrLf & strTemp
Loop
Close #filenum
MsgBox strContent
End Sub

• LOF 函数返回文件大小
• EOF 函数表示文件的结尾
• Line Input # 语句读取一个打开的顺序文件中的一行并
将内容保存在一个字符串变量中,不包括回车符
(Chr(13)) 或回车 - 换行符 (Chr(13)&Chr(10))
• 练习
获取指定文本文件内容的总行数
Input # 语句
• 语法 Input(number,[#]filenumber)
• number 必要参数,指定要读取的字符数
• filenumber 必要参数,文件号
• Input 函数返回读取的所有字符,包括回车符、
换行符等
• 使用 LOF 函数可以一次完全读取文件内容
‘ 这个过程对于特定的文本文件会出错,当文本文件包含非 ASCII 字符时,返回结果为空。
Sub ReadAll()
Dim strContent As String
Dim strFile As String
strFile = Application.GetOpenFilename(" 文本文件 (*.txt),*.txt", , " 请选择文本文件 ", , False)
If strFile = "False" Then Exit Sub
On Error Resume Next
Open strFile For Input As #1
strContent = Input(LOF(1), #1)
Close #1
MsgBox strContent
End Sub
写语句 – Print # 和 Write #
• 语法 Print #filenumber,[outputlist]
• outputlist 表示要写入的表达式或表达式列表,它的格式如下:
 [{Spc(n)|Tab[(n)]}][expression][charpos]
 Spc(n) 表示写入 n 个空白字符, Tab(n) 表示将写入点定位
在某个绝对列号 n 上。 expression 表达式是要打印的字符
串表达式或数值表达式。 charpos 表示下一个字符串的写入

• 语法 Write #filenumber,[outputlist]
• outputlist 要写入文件的数值表达式或字符串表达式,用一个或
多个逗号将这些表达式分界。
• 不同之处
• Write 语句使用引号来标记写入的字符串,并在项目和用来标记
字符串的引号之间插入逗号。 Write # 语句在将 outputlist
中的最后一个字符写入文件后会插入一个新行字符,即回车换行
符, (Chr(13) + Chr(10)) 。
• 一般使用 Input # 读取 Write # 写入的数据,使用 Line Input
# 和 Input 来读取 Print # 写入的数据。
写入数据
Sub PrintMethod() Sub WriteMethod()
Open "c:\testPrint.txt" For Output As #1 Open "c:\testWrite.txt" For Output As #1
Print #1, " 这是一个 Print# 测试文件 " Write #1, " 这是一个 Write# 测试文件 "
Print #1, Write #1,
Print #1, " 第一打印区 "; Tab; " 第二打印区 " Write #1, " 第一打印区 "; Tab; " 第二打印区 "
Print #1, " 第一个数据 ", 234 Write #1, " 第一个数据 ", 234
Print #1, Spc(5); " 前面有 5 个空格 " Write #1, Spc(5); " 前面有 5 个空格 "
Print #1, Tab(15); " 从第 15 列开始 " Write #1, Tab(15); " 从第 15 列开始 "
Close #1 Close #1
End Sub End Sub

• 对比不同方法写出来的文件不同之处
• 练习
使用 Open 方法将工作表内指定单元格内容写入一个文本文件,
以逗号分隔每个单元格,以回车符分隔每行。
目录
• 文件、文件夹对话框
• 文件搜索
• 文件、文件夹操作
• 文本文件读写
• FSO 介绍
WSH
• WSH 是 Windows Scripting Host 的简称,即 Windows 脚本
宿主,用于与 Windows 脚本兼容的脚本引擎
• 非常适合于非交互性脚本编写,例如管理脚本、自动化等
• 可以在屏幕上打印信息,使用 CreateObject 或 GetObject ,映射网
络驱动器,连接打印机,处理文件和文件夹,读写注册表等等
• 在 VBE 编辑器窗口中,选择菜单“工具” ->“ 引用”,在“引用”窗口
中,找到并选择“ Microsoft Scripting Runtime”
• 按 F2 打开“对象浏览器”,在“所有库”的下列列表中选
择“ Scripting” ,可以看到 WSH 的对象列表
FSO
• FSO 是 FileSystemObject 的简称,是 WSH 的一个
对象,它允许使用大家比较熟悉的 object.method 方
法来处理文件夹和文件
• 可以使用 CreateObject 函数从 VBA 过程中引用这些
WSH 的对象
• 对象列表
FileSystemObject 主对象,用来创建、删除和获得有关信息
Drive 包括收集驱动器信息的方法和属性
Drives 集合,提供驱动器列表
File 包含用来创建、删除或移动文件的方法和属性
Files 集合,提供包含在文件夹下的所有文件列表
Folder 包含用来创建、删除或移动文件夹的方法和属性
Folders 集合,提供文件夹列表
TextStream 用来读写文本文件(暂不支持二进制文件)
FileSystemObject 对象的方法和属性
• FileExists 如果指定文件存在,返回 True
• GetFile 返回一个 File 对象
• CopyFile 复制文件
• MoveFile 移动文件
• DeleteFile 删除文件
• DriveExists 如果指定驱动器存在,返回 True
• GetDrive 返回一个 Drive 对象
• FolderExists 如果指定文件夹存在,返回 True
• GetFolder 返回一个 Folder 对象
• GetSpecialFolder 返回操作系统文件夹路径
• CreateFolder 创建文件夹
• CopyFolder 复制文件夹
• MoveFolder 移动文件夹
• DeleteFolder 删除文件夹
• CreateTextFile 创建文本文件
• OpenTextFile 打开文本文件
• Drives 属性 返回驱动器集合
FileSystemObject 对象示例
Sub FSOFileTest()
Dim fs As Object
Dim strFile As String Sub FSOFolderTest()
Dim strNewFile As String Dim fs As Object
Dim objFolder As Object
Set fs = CreateObject("Scripting.FileSystemObject") Dim objFile As Object
strFile = "C:\test.txt" Cells(1, 1).Select
strNewFile = "C:\test\newtest.txt" Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(strFile) Then If fs.FolderExists("C:\test") Then
MsgBox strFile & " 存在 " Set objFolder = fs.GetFolder("C:\test")
fs.CopyFile strFile, strNewFile For Each objFile In objFolder.Files
fs.DeleteFile strFile ActiveCell.Select
Else ActiveCell.Value = objFile.Name
MsgBox strFile & " 不存在 " ActiveCell.Offset(0, 1).Select
End If ActiveCell.Value = objFile.Type
End Sub ActiveCell.Offset(1, -1).Select
Next
Else
Sub GetDriveList()
Set objFolder = fs.CreateFolder("C:\test")
Dim fs As Object
'fs.CopyFolder "C:\test", "C:\othertest"
Dim objDrives As Object
'fs.DeleteFolder "C:\test"
Set fs = CreateObject("Scripting.FileSystemObject")
objFolder.Copy "C:\othertest"
Set objDrives = fs.Drives
objFolder.Delete
For Each Drive In objDrives
End If
Debug.Print Drive.DriveLetter & ":"
End Sub
Next
End Sub
Drive 对象
• AvailableSpace 可用空间,用字节表示
• FreeSpace 同 AvailableSpace
• DriveLetter 驱动器字母
• DriveType 驱动器类型
0 – 未知
1 – 可移动
2 – 固定
3 – 网络
4 – CD-ROM
5 – RAM 磁盘
• FileSystem 文件系统,如 FAT 、 NTFS
• IsReady 如果插入了合适的媒介(如 CD )并可以访问,返回
True
• Path 根文件夹路径
• SerialNumber 驱动器系列号
• TotalSize 驱动器总容量
• 练习
列举出所有驱动器的类型、总容量、可用容量和文件类型
Folder 对象
• Attributes 文件夹属性
• DateCreated 文件夹创建日期
• Drive 包含该文件夹的驱动器
• Files 文件夹在的文件集合
• Name 文件夹名称
• ParentFolder 指定文件夹的父文件夹
• Path 文件夹的完整路径
• Size 文件夹大小
• SubFolders 文件夹的子文件夹集合
• 方法: Copy 、 Move 、 Delete
• Type 文件夹类型
• 练习
列举指定文件夹下所有文件夹的创建日期、大小、名称和完整路
径(包含子文件夹)
File 对象
• Attributes 文件属性(参考 GetAttr )
• DateCreated 创建日期
• DateLastAccessed 最后访问日期
• DateLastModified 最后修改日期
• Drive 驱动器名称
• Name 文件名
• ParentFolder 文件的父文件夹
• Path 文件的完整路径
• Size 文件大小
• Type 文件类型
• 方法: Copy 、 Move 、 Delete
• 练习
列举指定文件夹下所有文件的日期信息、大小、路径和文件类型
(包括子文件夹下的文件)
创建文本文件的三个方法
• Object.CreateTextFile(filename[, overwrite[, unicode]])
• Object 是 FSO 对象
• 参数 filename 为必需项,指定要文件的完整路径。
• 参数 overwrite 可选项, Boolean 值,指明是否覆盖原有文件。
• 参数 unicode 为可选项, Boolean 值,指明是以 Unicode 方式还是 ASCII
方式创建文件,默认是 False ,以 ASCII 方式。
• Object.OpenTextFile(filename[, iomode[, create[, format]]])
• Object 是 FSO 对象
• 参数 iomode 表示输入 / 输出方式,可选,以下三个常量之一
 ForReading 1 以只读方式打开文件
 ForWriting 2 以写方式打开文件
 ForAppending 8 打开文件并从文件末尾处开始写
• 参数 create 表示文件不存在是是否创建新文件
• 参数 format 用于打开文件的格式,可选参数。以下三个常量之一
 TristateUseDefault -2 以系统默认方式打开文件
 TristateTrue -1 以 Unicode 方式打开文件
 TristateFalse 0 以 ASCII 方式打开文件,默认
• Object.OpenAsTextStream([iomode, [format]])
• Object 是 File 对象
• 参数 iomode 和 format 为可选项,用法与 OpenTextFile 方法相同
读写的三个方法

• 写
Write 向打开的文件写入数据,但不自动在数据后添
加一个换行符
WriteLine 自动在写入的数据后添加一个换行符,如
果数据为空,仅写入一个换行符
WriteBlankLine 写入指定数量的换行符
• 读
Read 从文件中读取指定数量的字符并返回给字符串
,可以使用 FileLen 函数获取指定文件的长度以读取
所有文件内容
ReadLine 读取一行数据,不包括换行符
ReadAll 读取文件的整个内容
Sub WriteFile()
读写示例
Dim fso, f1, ts Sub ReadFile()
Dim strTmp As String Dim fso, f1, ts
Set fso = CreateObject("Scripting.FileSystemObject")
Dim strTmp As String
Set f1 = fso.CreateTextFile("c:\ 八月的梦游者 1.txt", True)
f1.WriteLine (" 八月的梦游者 ") Set fso = CreateObject("Scripting.FileSystemObject")
f1.WriteBlankLines (2) Set f1 = fso.OpenTextFile("c:\ 八月的梦游者 1.txt", 1)
f1.WriteLine (" 海底的石钟敲响 ") Do Until f1.AtEndOfStream
f1.WriteLine (" 敲响,抛起了波浪 ") strTmp = strTmp & vbCrLf & f1.ReadLine()
f1.WriteBlankLines (1)
Loop
f1.WriteLine (" 敲响的是八月 ")
f1.WriteLine (" 八月的正午没有太 ") f1.Close
f1.WriteBlankLines (1) Set f1 = fso.OpenTextFile("c:\ 八月的梦游者 2.txt", 1)
f1.WriteLine (" 涨满乳汁的三角帆 ") strTmp = strTmp & vbCrLf & f1.ReadAll
f1.Write (" 高耸在漂浮的尸体上 ") f1.Close
f1.Close
Set f1 = fso.OpenTextFile("c:\ 八月的梦游者 3.txt", 1)
Set f1 = fso.OpenTextFile("c:\ 八月的梦游者 2.txt", 2, True)
f1.WriteBlankLines (1) strTmp = strTmp & vbCrLf & _
f1.WriteLine (" 高耸的是八月 ") f1.Read(FileLen("c:\ 八月的梦游者 3.txt"))
f1.WriteLine (" 八月的苹果 下山 ") f1.Close
f1.WriteBlankLines (1) MsgBox strTmp
f1.WriteLine (" 熄灭已久的灯塔 ")
End Sub
f1.WriteLine (" 被水手们的目光照亮 ")
f1.WriteLine ""

• 练习
f1.WriteLine (" 照亮的是八月 ")
f1.Write (" 八月的集市又临霜降 ")
f1.Close
fso.CreateTextFile ("c:\ 八月的梦游者 3.txt")
Set ts = fso.GetFile("c:\ 八月的梦游者 3.txt")
使用 FSO 方法将工作表内指定
Set f1 = ts.OpenAsTextStream(2, 0) 单元格内容写入一个文本文件,
f1.WriteBlankLines (1)
f1.WriteLine (" 海底的石钟敲响 ") 以逗号分隔每个单元格,以回车
f1.WriteLine (" 敲响,抛起了波浪 ")
f1.WriteBlankLines (1)
符分隔每行。
f1.WriteLine (" 八月的梦游者 ")
f1.WriteLine (" 看见过夜里的太阳 ")
f1.Close
End Sub
End , Thanks