编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Excel常用技能分享与探讨(5-宏与VBA简介 VBA的文件操作一)

wxchong 2025-07-09 18:07:37 开源技术 7 ℃ 0 评论

一、从电脑管家理解文件操作

文件管家模型

  • 文件柜(Folder) → 文件夹与子文件夹
  • 文件袋(File) → 各类文档
  • 标签机(FileSystemObject) → 核心操作对象
  • 操作手册 → VBA代码指令集

在VBA(Visual Basic for Applications)中,使用文件系统对象(FSO, FileSystemObject)是处理文件和文件夹的标准方式。无论是创建文件夹还是文件,使用FSO对象都是一个常见的做法,因为它提供了丰富的属性和方法来实现这些操作。

创建文件夹

要使用FSO创建文件夹,你需要首先创建一个FileSystemObject的实例,然后使用该实例的CreateFolder方法。

创建文件

创建文件(此处的文件是指文件文件.Txt)同样需要FileSystemObject,但使用CreateTextFile方法。

注意事项

  1. 引用FileSystemObject:在使用FSO之前,确保你的VBA项目已经引用了Microsoft Scripting Runtime库。在VBA编辑器中,可以通过“工具”->“引用”来添加。
  2. 路径和权限:确保你有权限在指定的路径上创建文件夹或文件。如果路径不存在,FSO将自动创建必要的上级目录。
  3. 错误处理:在实际应用中,考虑到各种可能的错误(如权限问题、路径无效等),建议添加适当的错误处理机制,例如使用On Error GoTo语句。

以下是关于文件夹的一些操作。


二、启用文件管家(FSO对象)

1 召唤文件管家

' 方法1:工具→引用→勾选 "Microsoft Scripting Runtime"
' 方法2:后期绑定(推荐)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

2 获取常用对象

2.1.创建文件夹

  • CreateFolder 方法
    直接创建文件夹(若存在则报错):
fso.CreateFolder "C:\NewFolder"
  • 安全创建(先检查是否存在):
If Not fso.FolderExists("C:\NewFolder") Then
    fso.CreateFolder "C:\NewFolder"
End If

2.2.删除文件夹

  • DeleteFolder 方法
    删除空文件夹:
fso.DeleteFolder "C:\OldFolder"
  • 强制删除(包含子文件夹和文件):
fso.DeleteFolder "C:\OldFolder", True  ' True 表示强制删除

2.3.复制文件夹

  • CopyFolder 方法
    复制文件夹(覆盖现有文件):
fso.CopyFolder "C:\Source", "D:\Destination\"
  • 不覆盖现有文件:
fso.CopyFolder "C:\Source", "D:\Destination\", False

2.4.移动/重命名文件夹

  • MoveFolder 方法
    移动或重命名文件夹:
fso.MoveFolder "C:\OldName", "C:\NewName"     ' 重命名
fso.MoveFolder "C:\Source", "D:\Destination\"  ' 移动

2.5.检查文件夹是否存在

  • FolderExists 方法
If fso.FolderExists("C:\Test") Then 
    MsgBox "文件夹存在!" 
Else  
    MsgBox "文件夹不存在。" 
End If

2.6.获取文件夹属性

  • 使用 GetFolder 获取对象后访问属性:
Dim folder As Object
Set folder = fso.GetFolder("C:\Test")

Debug.Print "名称: " & folder.Name
Debug.Print "路径: " & folder.Path
Debug.Print "创建时间: " & folder.DateCreated
Debug.Print "大小(字节): " & folder.Size  ' 包含子文件夹和文件的总大小

使用 GetFolder 方法获取 Folder 对象后,可访问以下属性:

2.6.1.基础属性

属性

描述

示例值

.Name

文件夹名称

"TestFolder"

.Path

完整路径

"C:\TestFolder"

.ParentFolder

父文件夹对象

返回父文件夹的 Folder 对象

.ShortName

短名称(8.3格式)

"TESTFO~1"

.ShortPath

短路径(8.3格式)

"C:\TESTFO~1"

.IsRootFolder

是否为根目录

True/False

2.6.2.时间属性

属性

描述

示例值

.DateCreated

创建时间

2024/06/01 10:00:00

.DateLastModified

最后修改时间

2024/06/01 11:30:00

.DateLastAccessed

最后访问时间

2024/06/01 12:15:00

2.6.3.大小与内容

属性

描述

示例值

.Size

总大小(字节,包含子文件夹和文件)

102400

.Files.Count

文件夹内文件数量

15

.SubFolders.Count

子文件夹数量

3

2.6.4.系统属性

属性

描述

示例值

.Attributes

文件夹属性(如隐藏、只读)

组合值(见下文详解)

2.6.5.文件夹的 Attributes 属性详解

通过 .Attributes 可获取或设置文件夹的系统属性(需管理员权限),其值为以下常量组合:

常量

描述

vbNormal

0

默认属性

vbReadOnly

1

只读

vbHidden

2

隐藏

vbSystem

4

系统文件夹

vbDirectory

16

文件夹(自动包含)

vbArchive

32

存档(通常用于文件)

示例:检查或设置属性

' 检查是否为隐藏文件夹
If (folder.Attributes And vbHidden) = vbHidden Then
    MsgBox "此文件夹已隐藏!"
End If

' 设置文件夹为隐藏+只读
folder.Attributes = vbHidden + vbReadOnly

2.7.遍历子文件夹和文件

  • 遍历子文件夹
Dim mainFolder As Object, subFolder As Object 
Set mainFolder = fso.GetFolder("C:\Test") 
For Each subFolder In mainFolder.SubFolders
    Debug.Print subFolder.Name 
Next

2.8. GetDrive 方法

  • 作用:获取指定路径的驱动器对象(Drive 对象),用于查询驱动器属性。
  • 语法:Set driveObj = fso.GetDrive(drivePath)
  • 参数
    • drivePath:可以是以下形式:
      • 驱动器字母(如 "C:")
      • 完整路径(如 "C:\Windows",会自动提取驱动器部分)
  • Drive 对象常用属性
.AvailableSpace ' 可用空间(字节) 
.DriveLetter ' 驱动器字母(如 "C") 
.DriveType ' 驱动器类型(0-未知,1-可移动,2-固定,3-网络等) 
.FileSystem ' 文件系统类型(如 "NTFS") 
.FreeSpace ' 剩余空间(字节) 
.IsReady ' 驱动器是否就绪(布尔值) 
.TotalSize ' 总容量(字节)
  • 示例
Dim fso As Object, drive As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set drive = fso.GetDrive("D:\")

If drive.IsReady Then
    Debug.Print "驱动器 " & drive.DriveLetter & ":"
    Debug.Print "文件系统:" & drive.FileSystem
    Debug.Print "总空间:" & drive.TotalSize / 1024^3 & " GB"
    Debug.Print "剩余空间:" & drive.FreeSpace / 1024^3 & " GB"
Else
    Debug.Print "驱动器未就绪"
End If

2.9.特殊文件夹路径

' 获取系统特殊文件夹路径
Debug.Print fso.GetSpecialFolder(WindowsFolder)  ' Windows 目录
Debug.Print fso.GetSpecialFolder(SystemFolder)   ' 系统目录(如 System32)
Debug.Print fso.GetSpecialFolder(TemporaryFolder) ' 临时文件夹

三、传统 VBA 命令(无需 FSO)

适用于简单场景,但功能有限。

3.1.创建文件夹

  • MkDir 语句
MkDir "C:\NewFolder"
  • 若路径不存在会报错,需手动处理错误:
On Error Resume Next
MkDir "C:\NewFolder"
On Error GoTo 0

3.2.删除文件夹

  • RmDir 语句(只能删除空文件夹):
RmDir "C:\EmptyFolder"

3.3.检查文件夹是否存在

  • 使用 Dir 函数
If Dir("C:\Test", vbDirectory) <> "" Then
    MsgBox "文件夹存在!"
Else
    MsgBox "文件夹不存在。"
End If

3.4.遍历文件夹内容

  • 使用 Dir 递归遍历
Sub ListFiles(ByVal folderPath As String)
    Dim fileName As String
    fileName = Dir(folderPath & "\*.*", vbDirectory)
    
    Do While fileName <> ""
        If fileName <> "." And fileName <> ".." Then
            If (GetAttr(folderPath & "\" & fileName) And vbDirectory) = vbDirectory Then
                ' 子文件夹
                ListFiles folderPath & "\" & fileName
            Else
                ' 文件
                Debug.Print folderPath & "\" & fileName
            End If
        End If
        fileName = Dir()
    Loop
End Sub

' 调用示例
ListFiles "C:\Test"

四、高级操作与技巧

4.1.递归删除非空文件夹

结合 FSO 强制删除或手动递归删除:

Sub DeleteNonEmptyFolder(folderPath As String)
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    If fso.FolderExists(folderPath) Then
        fso.DeleteFolder folderPath, True
    End If
End Sub

4.2.获取父文件夹路径

Dim parentPath As String
parentPath = fso.GetParentFolderName("C:\Test\SubFolder")  ' 返回 "C:\Test"

4.3.构建路径

避免手动拼接路径错误:

Dim fullPath As String
fullPath = fso.BuildPath("C:\Parent", "Child")  ' 返回 "C:\Parent\Child"

4.4.处理特殊文件夹

获取系统目录路径:

Debug.Print fso.GetSpecialFolder(0)  ' Windows 文件夹(如 C:\Windows)
Debug.Print fso.GetSpecialFolder(1)  ' 系统文件夹(如 C:\Windows\System32)
Debug.Print fso.GetSpecialFolder(2)  ' 临时文件夹

4.5.设置文件夹属性

使用 GetAttr 和 SetAttr(需结合传统方法):

' 设置为隐藏文件夹
SetAttr "C:\HiddenFolder", vbHidden

' 检查是否为隐藏文件夹
If (GetAttr("C:\HiddenFolder") And vbHidden) = vbHidden Then
    MsgBox "这是隐藏文件夹!"
End If

4.6.使用通配符筛选文件

  • 结合 Dir 函数按模式匹配文件名:
Dim fileName As String
fileName = Dir("C:\Test\*.xlsx")  ' 仅获取Excel文件
Do While fileName <> ""
    Debug.Print fileName
    fileName = Dir()
Loop

4.7.压缩与解压文件夹

  • 通过 Shell.Application 对象调用系统压缩功能:
Dim shell As Object 
Set shell = CreateObject("Shell.Application")
' 压缩文件夹到ZIP 
shell.NameSpace("C:\Archive.zip").CopyHere  
shell.NameSpace("C:\Test").Items
' 解压ZIP到目标路径 
shell.NameSpace("C:\ExtractFolder").CopyHere 
shell.NameSpace("C:\Archive.zip").Items

五、实例

5.1.生成文件夹树形结构

Sub PrintFolderTree(rootPath As String, Optional indent As String = "")
    Dim fso As Object, folder As Object, subFolder As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.GetFolder(rootPath)
    
    Debug.Print indent & "├─ " & folder.Name
    indent = indent & "│  "
    
    For Each subFolder In folder.SubFolders
        PrintFolderTree subFolder.Path, indent
    Next
End Sub
' 调用:PrintFolderTree "C:\Test"

5.2.计算文件夹总大小(优化递归)

Function GetFolderSize(folderPath As String) As Double
    Dim fso As Object, folder As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    If fso.FolderExists(folderPath) Then
        Set folder = fso.GetFolder(folderPath)
        GetFolderSize = folder.Size  ' 自动包含子文件夹
    Else
        GetFolderSize = 0
    End If
End Function

5.3.快速清空文件夹内容(保留文件夹)

Sub EmptyFolder(folderPath As String)
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    If fso.FolderExists(folderPath) Then
        fso.DeleteFolder folderPath, True  ' 删除所有内容
        fso.CreateFolder folderPath        ' 重新创建空文件夹
    End If
End Sub

5.4.备份文件夹

Sub BackupFolder(sourcePath As String, destPath As String)
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    On Error Resume Next
    If Not fso.FolderExists(destPath) Then
        fso.CreateFolder destPath
    End If
    
    If fso.FolderExists(sourcePath) Then
        fso.CopyFolder sourcePath & "\*", destPath, True  ' 覆盖现有文件
        MsgBox "备份完成!"
    Else
        MsgBox "源文件夹不存在!"
    End If
    On Error GoTo 0
End Sub

' 调用示例
BackupFolder "C:\Data", "D:\Backup\Data"

5.5.合并多个CSV

Sub 合并报表()
    Dim 输出文件 As Object
    Set 输出文件 = 管家.CreateTextFile("总表.csv", True)
    
    For Each 文件 In 管家.GetFolder("D:\分部数据").Files
        If 管家.GetExtensionName(文件) = "csv" Then
            Dim 输入流 As Object
            Set 输入流 = 管家.OpenTextFile(文件.Path)
            
            If 文件.Name <> "总表.csv" Then
                输出文件.WriteLine 输入流.ReadAll
            End If
            
            输入流.Close
        End If
    Next
    
    输出File.Close
End Sub

六、避坑指南:常见错误

  • 错误处理
    使用 On Error Resume Next 避免因文件夹不存在导致的程序中断。
  • 权限问题
    操作系统保护的核心目录(如 C:\Windows)可能需要管理员权限。
  • 路径格式
    使用 \ 作为路径分隔符,或通过 BuildPath 方法动态构建路径:
Dim fullPath As String
fullPath = fso.BuildPath("C:\Parent", "ChildFolder")
  • 递归操作
    遍历子文件夹时,需注意避免无限循环或权限冲突。

七、总结

  • 灵活选择工具:简单任务用 MkDir/RmDir,复杂操作用 FileSystemObject 或 Shell.Application。
  • 结合API扩展功能:处理长路径、权限、图标等高级需求。
  • 深度集成Excel:自动化生成文件列表、批量创建文件夹等场景。
  • 注重兼容性:处理跨平台(Win/Mac)和路径格式差异。

通过掌握这些方法,可以覆盖从基础到高级的文件夹操作需求,适用于数据清洗、自动化报表、文件管理系统等场景。


八、知识图谱


Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表