当前位置: 首页 > 文档资料 > 简明 Excel VBA >

05 Excel 相关常用操作

优质
小牛编辑
121浏览
2023-12-01

5.1 Excel 基础操作

  1. Range相关 Range 属性的一些 A1 样式引用
Range("A1")             ' 单元格 A1
Range("A1:B5")          ' 从单元格 A1 到单元格 B5 的区域
Range("C5:D9, G9:H16")  ' 多块选定区域
' 选中不关联的单元格,cells(2, 3)返回结果为:B3
Union(Range("A1:A10"), Range("K10"), Range("A1:" & cells(2, 3).Address)).Select
Range("A:A")            ' A 列
Range("1:1")            ' 第一行
Range("A:C")            ' 从 A 列到 C 列的区域
Range("1:5")            ' 从第一行到第五行的区域
Range("1:1, 3:3, 8:8")  ' 第 1、3 和 8 行
Range("A:A, C:C, F:F")  ' A 、C 和 F 列
  1. 行列相关 行和列的引用
Rows(1)         ' 第一行
Rows            ' 工作表上所有的行
Columns(1)      ' 第一列
Columns("A")    ' 第一列
Columns         ' 工作表上所有的列
Union(Rows(1), Rows(3), Rows(5))  ' 引用第1, 3, 5行
  1. 循环Selction区域的每一个单元格Cell
For Each rngDataCell In RngDataSelection
    If Not rngDataCell.HasFormula And Not (Trim(rngDataCell.Value)  = "") Then
        ...
    End If
Next rngDataCell
  1. 选择当前工作表中的单元格
ActiveSheet.Cells(5, 4).Select
或:ActiveSheet.Range("D5").Select
  1. 选择同一工作簿中其它工作表上的单元格
Application.Goto (ActiveWorkbook.Sheets("Sheet2").Range("E6"))
' 也可以先激活该工作表,然后再选择:
Sheets("Sheet2").Activate
ActiveSheet.Cells(6, 5).Select
  1. 选择与当前单元格相关的单元格/偏离当前单元格(Offset)
    语法:Offset(D, R) 以当前为基础原点,向下D,且向右D移动,如果负数即为向反方向移动 即向上和向左移动。
    例如,要选择距当前单元格下面5行左侧4列的单元格
ActiveCell.Offset(5, -4).Select
  1. 选择一个指定的区域并扩展区域的大小
' 要选择当前工作表中名为“Database”区域,然后将该区域向下扩展5行,可以使用下面的代码:
Range("Database").Select
Selection.Resize(Selection.Rows.Count + 5, Selection.Columns.Count).Select
  1. 选择一个指定的区域,再偏离,然后扩展区域的大小
' 选择名为“Database”区域下方4行右侧3列的一个区域,然后扩展2行和1列,可以使用下面的代码:
Range("Database").Select
Selection.Offset(4, 3).Resize(Selection.Rows.Count + 2, Selection.Columns.Count + 1).Select
  1. 同时选择两个或多个指定区域
    注意:所选区域必须在同一工作表(sheet)中。
Set rngUnionSelection = Application.Union(Range("Sheet1!A1:B2"), Range("Sheet1!C3:D4"))
  1. 选择两个或多个指定区域的交叉区域 注意:所选区域必须在同一工作表(sheet)中。
' 要选择名为“Test1”和“Test2”的两个区域的交叉区域
Application.Intersect(Range("Test1"), Range("Test2")).Select
  1. 利用End函数的相关操作

End(xldown):从被选中的单元格向下寻找,如果被选中单元格为空,则一直向下走到 第一个非空单元格;如果被选中单元格为非空,则向下走到最后一个非空单元格。
End函数的4个方向参数:xlUp, xlDown, xlToLeft, xlToRight。

' 选择连续数据列中的最后一个单元格
ActiveSheet.Range("a1").End(xlDown).Select
' 选择连续数据列底部的空单元格
ActiveSheet.Range("a1").End(xlDown).Offset(1, 0).Select
' 获取连续数据最后一行的行号
Selection.end(xldown).Row
' 想选择连续数据最后面的空白行
Rows(Selection.End(xldown).Row + 1).Select
' 选择某列中连续数据单元格区域
ActiveSheet.Range("A1", ActiveSheet.Range("a1").End(xlDown)).Select
ActiveSheet.Range("A1:" & ActiveSheet.Range("a1").End(xlDown).Address).Select
' 选择某列中非连续数据单元格区域
ActiveSheet.Range("A1", ActiveSheet.Range("a65536").End(xlUp)).Select
ActiveSheet.Range("A1:" & ActiveSheet.Range("a65536").End(xlUp).Address).Select

补充: 对于上述代码中非连续数据,也可以利用UsedRange.Rows.Count获取所有数据的条/行数。

Dim lngCountData As Long
lngCountData = ActiveSheet.UsedRange.Rows.Count

5.2 打开Excel两种方式

  • 利用 GetObject 方法打开Excel文档
    Sub GetWorkbook()
        Dim wbWorkFile As Workbook
        Set wbWorkFile = GetObject("D:\test.xlsx")
        ' wbWorkFile.Windows(1).Visible = True ' 这种方法打开的文件是隐藏的,如果需要显示,则设置Visible值为ture
        wbWorkFile.Close False
        Set wbWorkFile = Nothing
    End Sub
  • 利用 Open 方法打开Excel文档
Sub OpenWorkbook()
    Dim wbWorkFile As Workbook
    Set wbWorkFile = Workbooks.Open("D:\test.xlsx")
    wbWorkFile.Windows(1).Visible = False
    wbWorkFile.Close False
    Set wbWorkFile = Nothing
End Sub

延伸其扩展方法:

  • GetObject封装方法,可以作为共通Function
Sub GetWorkbook()
    Dim objExcel                As Object       ' 用于存放Microsoft Excel 引用的变量。
    Dim blnExcelWasNotRunning   As Boolean      ' 用于最后释放的标记。

    ' 测试 Microsoft Excel 的副本是否在运行。
    On Error Resume Next                        ' 延迟错误捕获。
    ' 不带第一个参数调用 Getobject 函数将返回对该应用程序的实例的引用。如果该应用程序不在运行,则会产生错误。
    Set objExcel = Getobject(, "Excel.Application")
    If Err.Number <> 0 Then blnExcelWasNotRunning = True
    Err.Clear                                   ' 如果发生错误则要清除 Err 对象。

    Set objExcel = Getobject("C:\excel.xlsx")   ' 将对象变量设为对要看的文件的引用。

    ' 设置其 Application 属性,显示 Microsoft Excel。然后使用 objExcel 对象引用的 Windows 集合显示包含该文件的实际窗口。
    objExcel.Application.Visible = True
    objExcel.Parent.Windows(1).Visible = True
    ' 在此处对文件进行操作。
    ' ...
    ' 如果在启动时,Microsoft Excel 的这份副本不在运行中,则使用 Application 属性的 Quit 方法来关闭它。
    ' 注意,当试图退出 Microsoft Excel 时,标题栏会闪烁,并显示一条消息询问是否保存所加载的文件。
    If blnExcelWasNotRunning = True Then
        objExcel.Application.Quit
    End IF

    Set objExcel = Nothing   ' 释放对该应用程序

End Sub
  • OpenWorkbook封装方法,可以作为共通Function
Function OpenWorkbook(ByVal strWorkbookFilePath As String)
    Dim wb As Workbook
    Dim fileName As String
    fileName = Dir(strWorkbookFilePath)

    On Error Resume Next
    Set wb = Workbooks(fileName)
    On Error GoTo 0
    If wb Is Nothing Then
        Set wb = Workbooks.Open(strWorkbookFilePath)
    End If

    Set OpenWorkbook = wb

End Function

5.3 操作Excel工作表(Worksheet)

5.3.1 移动工作表

移动工作表是指将工作表移到工作簿中的其他位置。 在VBA中,可以使用WorkSheet.Move方法来移动工作表。

语法:表达式.Move(Before, After) 其中,在Move方法中,主要包含两个参数,其功能如下:

Before 在其之前放置移动工作表的工作表。如果指定了After,则不能指定Before。 After 在其之后放置移动工作表的工作表。如果指定了Before,则不能指定After。 例如:移动 "工资表" 至Sheet3工作表之后,可以输入以下代码:

Sub 移动工作表()
    Sheets("工资表").Select
    Sheets("工资表").Move After:=Sheets(3)
End Sub

另外,如果既不指定Before也不指定After,Microsoft Excel将新建一个工作簿, 其中包含所移动的工作表。例如,输入以下代码,即可新建一个工作簿, 且该工作表中包含有 "工资表" 工作表。

Sub A()
    Sheets("工资表").Move
End Sub

5.3.2 复制工作表

复制工作表是指将工作表进行备份,以便于用户对备份文件进行操作时,不会损坏原有文件。 在VBA中,使用Sheets.Copy方法可以将工作表复制到工作簿的另一位置。 语法:

表达式.Copy(Before, After)

其中,在Copy方法中,包含的两个参数与在Move方法中的参数相似,其参数功能如下: Before 将要在其之前放置所复制工作表的工作表。如果指定了After,则不能指定Before。 After 将要在其之后放置所复制工作表的工作表。如果指定了Before,则不能指定After。 例如:复制 "工资表" 表格至Sheet3工作表之后,可以输入以下代码:

Sub 复制工作表()
    Sheets("工资表").Select
    Sheets("工资表").Copy After:=Sheets(3)
End Sub

另外,用户还可以在不同的工作簿之间进行复制。 例如:将当前工作簿中的“工资表”工作表复制到打开的Book1工作表中,可以输入以下代码:

Sub 复制工作表至Book1中()
    Sheets("工资表").Copy After:=Workbooks("Book1").Sheets(1)
End Sub

5.4 Excel AutoFilter / Excel 自动筛选操作

5.4.1 显示所有数据记录

Sub ShowAllRecords()
    If ActiveSheet.FilterMode Then
        ActiveSheet.ShowAllData
    End If
End Sub

5.4.2 开关Excel自动筛选

先判断是否有自动筛选,如果没有为A1添加一个自动筛选

Sub TurnAutoFilterOn()
    'check for filter, turn on if none exists
    If Not ActiveSheet.AutoFilterMode Then
        ActiveSheet.Range("A1").AutoFilter
    End If
End Sub

清除自动筛选

Sub TurnFilterOff()
    'removes AutoFilter if one exists
    Worksheets("Data").AutoFilterMode = False
End Sub

5.4.3 隐藏过滤箭头

隐藏所有的箭头

Sub HideALLArrows()
    'hides all arrows in heading row
    'the Filter remains ON
    Dim c As Range
    Dim i As Integer
    Dim rng As Range
    Set rng = ActiveSheet.AutoFilter.Range.Rows(1)
    i = 1
    Application.ScreenUpdating = False

    For Each c In rng.Cells
        c.AutoFilter Field:=i, _
            Visibledropdown:=False
        i = i + 1
    Next

    Application.ScreenUpdating = True
End Sub

只保留一个箭头,其他的过滤箭头全隐藏

Alt text

Sub HideArrowsExceptOne()
'hides all arrows except
' in specified field number
Dim c As Range
Dim rng As Range
Dim i As Long
Dim iShow As Long
Set rng = ActiveSheet.AutoFilter.Range.Rows(1)
i = 1
iShow = 2 'leave this field's arrow visible
Application.ScreenUpdating = False

For Each c In rng.Cells
    If i = iShow Then
        c.AutoFilter Field:=i, _
        Visibledropdown:=True
    Else
        c.AutoFilter Field:=i, _
        Visibledropdown:=False
    End If
    i = i + 1
Next

Application.ScreenUpdating = True
End Sub

隐藏部分箭头

Alt text

Sub HideArrowsSpecificFields()
    'hides arrows in specified fields
    Dim c As Range
    Dim i As Integer
    Dim rng As Range
    Set rng = ActiveSheet.AutoFilter.Range.Rows(1)
    i = 1
    Application.ScreenUpdating = False

    For Each c In rng.Cells
        Select Case i
            Case 1, 3, 4
            c.AutoFilter Field:=i, _
                Visibledropdown:=False
        Case Else
            c.AutoFilter Field:=i, _
                Visibledropdown:=True
        End Select
        i = i + 1
    Next

    Application.ScreenUpdating = True
End Sub

5.4.4 复制所有的过滤后的数据

Sub CopyFilter()
    'by Tom Ogilvy
    Dim rng As Range
    Dim rng2 As Range

    With ActiveSheet.AutoFilter.Range
        On Error Resume Next
            Set rng2 = .Offset(1, 0).Resize(.Rows.Count - 1, 1) _
            .SpecialCells(xlCellTypeVisible)
        On Error GoTo 0
    End With
    If rng2 Is Nothing Then
        MsgBox "No data to copy"
    Else
        Worksheets("Sheet2").Cells.Clear
        Set rng = ActiveSheet.AutoFilter.Range
        rng.Offset(1, 0).Resize(rng.Rows.Count - 1).Copy _
        Destination:=Worksheets("Sheet2").Range("A1")
    End If

    ActiveSheet.ShowAllData
End Sub

5.4.5 检查是否有自动筛选:

可以打开立即窗口,即类似于控制台的 Immediate Window,快捷键:Ctrl+G ,查看如下code的 iARM的打印值。

Alt text

Sub CountSheetAutoFilters()
    Dim iARM As Long
    'counts all worksheet autofilters
    'even if all arrows are hidden
    If ActiveSheet.AutoFilterMode = True Then iARM = 1
    Debug.Print "AutoFilterMode: " & iARM
End Sub  

5.5 清理Excel数据相关操作

5.5.1 清理单元格或Range中的内容

如若清空某个选中的单元格中的数据,使用的API为:ClearContents
示例:

Range("A1").Select
Selection.ClearContents

5.5.1 清理/删除Excel中第一个标题行以外的所有行

同样使用ClearContents方法,主要是确定如何选中除第一行以外的表格。
示例代码如下:

Sub ClearContentExceptFirst()
    Rows("2:" & Rows.Count).ClearContents
End Sub