1.特殊的三类对象

Name对象

  1. WorksheetWorkbookApplication对象都有Name对象;
  2. Worksheet级的Name对象通过Worksheet、Workbook和Application都可以访问;
  3. Workbook级的Name对象通过Workbook和Application可以访问,通过Worksheet不可访问;

    Activesheet对象

    每个Workbook都有一个ActiveSheet

    Range对象

  4. Application.Range:有且只有一个,即为活动工作表下的活动单元格

  5. Worksheets.Range:为工作表下的所有单元格;

2.单元格对象

2.1 单元格对象的引用方式

Range方式

  1. Range方式可以以一个字符串的方式引用一个单元格或区域。如:Range("A1")Range("A1:B6")
  2. Range方式也可以添加变量,但一般添加行变量,列变量不太容易添加,如:Range("A" & i)
  3. Range可以联合Cells方式获得一个区域,如:Range(Cells(1, 1), Cells(6, 6))此时,cells中可以引入参数,从而实现Range方式行列都可引入参数 :::info 特别注意:Range中,隔开的不是非连续区域,而是一个最大的连续区域 :::

    1. Public Sub test()
    2. Range("A1:C9", "E1") = 1
    3. End Sub

    image.png

  4. Range若要选择不连续区域,应在一个字符串内用,隔开。如:Range("A1:B5,C1:F5,G1")

  5. Range内部为字符串,可以通过字符串拼接的方式传入地址;

    Cells方式

  6. 引用方式为Cells(行号,列号),其中行号和列号都为数字。如:Cells(3,2);

  7. 可以引入行、列两个变量,Cells(i,j)
  8. Cells方式不能引用区域,只能引用一个单元格

    [ ]方式

  9. [ ]方式可以直接引用单元格、区域和不连续区域,如:[A1][A1:B5][A1:B5,D9]

  10. [ ]方式中不能有任何参数,故只能引用固定的区域

    2.2 单元格对象的常用属性

    Range.Offset

    Range.Offset(a,b)为Range区域偏移a行(向下偏移a行),同时偏移b列(向右偏移b列)后的新区域

  11. 偏移后的区域大小和range本身大小一致;

  12. 参数a、b可以为负数。a、b为负数时分别代表向上和向左偏移; :::info 这里的a,b为偏移数,不包含本身单元格。1代表移动一个单元格。 ::: ```vbnet Public Sub Offset_演示()

Range(“A1:B5”).Select Stop Range(“A1:B5”).Offset(3, 2).Select

End Sub

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/389342/1667130210198-e07ec267-dd69-4747-8445-b78761b74e61.png#averageHue=%23fefb01&clientId=ud9a7ccdc-4b79-4&from=paste&height=295&id=u062509a6&originHeight=443&originWidth=697&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15495&status=done&style=none&taskId=ueaa1d1bc-56ee-443f-b180-1339884887b&title=&width=464.6666666666667)
  2. <a name="sS7vM"></a>
  3. ### Range.Resize
  4. `Range.Resize(a,b)`为重新获取新的Range区域。获得的新区域为以原来Range左上角为顶点,向下包含a行,向右包含b列所组成的区域
  5. 1. 参数ab可以为负数。ab为负数时分别代表向上延伸和向左延伸;
  6. :::info
  7. 这里的ab为最终Range的行列数,即都为1时就是原Range区域的左上角单元格
  8. :::
  9. ```vbnet
  10. Public Sub resize_演示()
  11. Range("A1:B5").Select
  12. Stop
  13. Range("A1:B5").Resize(8, 4).Select
  14. End Sub

image.png

Range.CurrentRegion

Range.CurrentRegion属性没有参数。结果返回包含原range区域或range区域内,已经被使用连续区域

  1. 若range区域附近没有连续区域则,返回range区域本身;
  2. 若range区域内包含了已使用区域和未使用区域,则只返回已经被使用的区域 ```vbnet ‘若本案例中A1:B2被使用,其他单元格均未被使用

Public Sub CurrentRegion_演示()

Debug.Print Range(“A1:C4”).CurrentRegion.Address

End Sub

结果返回值为:$A$1:$B$2

  1. <a name="CtXmd"></a>
  2. ### Range.End
  3. `Range.End(Direction)`函数返回一个range对象。即**已经被使用的第一个**或**连续被使用的最后一个**单元格
  4. 1. 范围的区域仅有两种状态,即已经被使用的单元格与未被使用的单元格;
  5. 2. 界定已经被使用的第一个或连续被使用的最后一个单元格方式为看源Range属于哪一类。若Range为已经被使用得单元格,就从range按照Direction方向找到连续被使用的最后一个单元格。如果Range为未被使用得单元格,则在该方向找到第一个被使用的单元格。若果以上条件都无法满足,返回Direction方向的边界单元格。
  6. 3. 若range本身就在边界时结果较为混乱
  7. 4. 本质与`CTRL+方向键`效果一致
  8. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/389342/1667143455249-60039689-3ecd-4a02-915e-a5c362cbd082.png#averageHue=%23fafaf9&clientId=u4627e7f4-a597-4&from=paste&height=365&id=u66e5857a&originHeight=547&originWidth=633&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11071&status=done&style=none&taskId=u05d2669b-445a-4a57-9a90-a12381a05a9&title=&width=422)
  9. ```vbnet
  10. '代码中单元格内容如上图,A16以下单元格全未使用
  11. Public Sub end_演示()
  12. Debug.Print Range("A1").End(xlDown).Address '结果为:$A$3
  13. Debug.Print Range("A2").End(xlDown).Address '结果为:$A$3
  14. Debug.Print Range("A3").End(xlDown).Address '结果为:$A$6
  15. Debug.Print Range("A4").End(xlDown).Address '结果为:$A$6
  16. Debug.Print Range("A5").End(xlDown).Address '结果为:$A$6
  17. Debug.Print Range("A6").End(xlDown).Address '结果为:$A$16
  18. Debug.Print Range("A65536").End(xlUp).Address '结果为:$A$16
  19. End Sub
  1. Public Sub test()
  2. '直接给定该列最后一个单元格地址Range("A65536")
  3. '这样做的缺点是通用性不好,在07版中最大列数为1048576,可能A65536列是一个被使用的单元格
  4. '如果直接使用Range("A1048576"),代码在03版本中运行会出现兼容错误
  5. Debug.Print ActiveSheet.Range("A65536").End(xlUp).Address '结果为:$A$16
  6. End Sub
  1. Public Sub test()
  2. '通过计算最大行数来确定Range单元格地址,解决代码兼容性
  3. Debug.Print ActiveSheet.Rows.Count '07及以后版本中结果为:1048576 03版本中结果为:65536
  4. Debug.Print ActiveSheet.Range("A" & ActiveSheet.Rows.Count).End(xlUp).Address '结果为:$A$16
  5. End Sub

Range.Text和Range.Value

Range.TextRange.Value的内容大部分情况下是一致的,但也有以下不同:

  1. Range.Text是单元格内的显示样式,看到什么样子就显示什么样子;Range.Value是输入栏中的内容;
  2. 当Range是一个单元格区域时,**Range.Text**的数据类型变为Null,不可用;而**Range.Value**的数据类型变为Variant(),是一个变体数组;
  3. 如果省略默认为Range.Value

image.png

  1. Public Sub test()
  2. [B1].text '结果为:########
  3. [B1].value '结果为:2022/5/4
  4. End Sub

2.2.6 Range.HorizontalAlignment和Range.VerticalAlignment

  1. Range.HorizontalAlignment为单元格内容的水平对其方式
  2. Range.VerticalAlignment为单元格内容的垂直对其方式
  3. 不用记忆,可以通过录制宏得到

    2.2.7 Range.RowHeight和Range.ColumnWidth

  4. Range.RowHeight为单元格行高

  5. Range.ColumnWidth为单元格列宽
  6. 由于excel计算行高和列标准不一致,所以即便设置了相同行高和列宽最终单元格也不是正方形 ```vbnet Sub 行高列宽()

‘行高列宽设置一致结果为长方形 Range(“A1”).RowHeight = 20 Range(“A1”).ColumnWidth = 20

End Sub

Sub 行高列宽正方形()

‘以下参数结果为正方形 Range(“A13”).RowHeight = 28.2 Range(“A13”).ColumnWidth = 4.33

End Sub

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/389342/1667568894862-68fb3c4e-68ed-4503-bc26-32ff98e35a4c.png#averageHue=%23f2e3d7&clientId=u6fcd2fb5-11d1-4&from=paste&height=117&id=u056faff7&originHeight=113&originWidth=248&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1025&status=done&style=none&taskId=uf4f5f331-2e09-4384-910d-1a6c5cd0bef&title=&width=257.3333435058594)
  2. 4. VBA中有专门的属性确定使用英寸单位还是厘米单位
  3. 1. `Application.CentimetersToPoints(x)`
  4. 2. `Application.InchesToPoints(x)`
  5. ```vbnet
  6. Sub RngToPoints()
  7. '用cm作为单位
  8. With Range("A1")
  9. .RowHeight = Application.CentimetersToPoints(2)
  10. .ColumnWidth = Application.CentimetersToPoints(1.5)
  11. End With
  12. '用英寸作为单位
  13. With Range("A2")
  14. .RowHeight = Application.InchesToPoints(1.2)
  15. .ColumnWidth = Application.InchesToPoints(0.3)
  16. End With
  17. End Sub

2.2.8 Range.Validation

Range.Validation是设置区域数据有效性的属性,不用记忆代码过程,可以通过录制宏产生

  1. 判断一个单元格是否有数据有效性的方法Range.Validation.TypeRange.Validation.Type返回一个数字就代表该单元格有数字有效性,并且可以通过返回的数字类型判断出是哪种数据有效性。如果无数据有效性报错

image.png

  1. 如果担心Range.Validation.Type出现报错,可以是用on error resume next语句将错误代码跳过。因为错误是一个对象 ```vbnet Sub 判断数据有效性() On Error Resume Next

    s = [A2].Validation.Type ‘这里一定要注意,必须要将 [A2].Validation.Type赋值给一个变量.并用这个变量判断是否为空.因为报错不等 空,但赋值给变量时,变量为空 If s <> “” Then

    1. Debug.Print "有数据有效性"

    Else

    1. Debug.Print "没有数据有效性"

    End If

End Sub

  1. 3. `Range.Validation.delete``Range.Validation.add`
  2. 1. **如果原来单元格的数据有效性不删除,添加新数据有效性时报错。所以,一般添加数据有效性时,先删除原有的数据有效性**
  3. 2. 可以发送alt+方向下按键指令展开下拉菜单`Application.SendKeys "%{down}"`
  4. ```vbnet
  5. Sub 添加数据有效性()
  6. ' 添加数据有效性
  7. With [A1:A10].Validation
  8. .Delete '删除原来的有效性
  9. .Add Type:=xlValidateList, Formula1:="1,2,3,4" '添加新的有效性,添加时尽量使用:=方式给参数赋值
  10. End With
  11. End Sub

:::info 特别注意:
在添加数据有效性的代码中,Range.Validation.Add中的参数使用参数赋值x:=a形式不容易报错 :::

2.2.8 Range.Formula及Range.HasFormula

Range.Formula是在单元格中直接录入公式的属性

  1. 这个属性也可以通过录制宏得到。但一般不用,因为通过录制宏方式得到的代码为R1C1引用样式结果,不便于公式理解;
  2. 可以直接写公式样式。在这里可以实现公式字符串拼接

    1. Sub 写入公式()
    2. Dim r As Range
    3. Set r = Range("XFD1").End(xlToLeft)
    4. r.Select
    5. s = r.Address()
    6. Range("C2").Formula = "=sum(A" & s & ")" 'sum(A)
    7. End Sub

    Range.HasFormula是用于判断单元格内是否有公式。有公式返回True,否则返回False

    2.2.8 Range.Address

    Range.Address可以显示出单元格地址的属性。

  3. Range.address(RowAbsolute,ColumnAbsolute)其中RowAbsolute,ColumnAbsolute参数为1或默认时,返回结果为绝对引用。为0时为相对引用

    2.2.9 Range.Comment

    Range.Comment是单元格的批注,是一个可读可写属性。

  4. 如果range中没有批注,则返回Nothing

  5. 其他的相关属性和方法

    1. Range.ClearComments清除批注
    2. Range.Comment.Visible批注可见性。False为不可见,True为可见
    3. Range.Comment.Text(Text)文字批注内容
    4. Range.Comment.Shape批注中的形状(包含图片)
      1. Range.Comment.Shape.Fill.UserPicture(图片路径)利用图片路径填充图片
      2. Range.Comment.Shape.Height图片高度
      3. Range.Comment.Shape.Width图片宽度

        2.2.10 Range.Font

        Range.Font是单元格的字体对象。其内部有较多有关字体的属性,其中包含.Name.Size.Underline.Color.Bold等属性。不用记忆,可通过录制宏的到

        2.2.11 Range.Interior

        Range.Interior是单元格的背景对象。其中属性主要包含.Pattern.PatternThemeColor.Color.PatternTintAndShade等,不用记忆,可通过录制宏的到

        2.2.12 Range.Borders()和Range.BorderAround方法

        Range.Borders()为单元格边框对象。其中包含属性主要有.LineStyle.Weight.Color
  6. Range.Borders()的括号需要加上,当括号内没有没内容时,是指代所有边框(外部+内部);

  7. 也可以在Range.Borders()的括号中指定特殊位置的边框对象

    1. Range.Borders(xlEdgeLeft)
    2. Range.Borders(xlEdgeRight)
    3. Range.Borders(xlEdgeTop)
    4. Range.Borders(xlEdgeBottom)
    5. Range.Borders(xlInsideHorizontal)
    6. Range.Borders(xlInsideVertical)
    7. Range.BorderAround方法可以设置单元格外边框

      2.2.13 Range.Locked

      Range.Locked是一个给单元格加锁的方法,一般需要配合worksheet.protect属性使用
  8. Range.Locked=True相当于选择了锁定

image.png

2.2.14 Range.Row/Column & Range.EntireRow/EntireColumn

Range.Row/Column属性返回range的行号/列号

  1. Rows(Range.Row)返回Range所在行的一整行,但仅能引用一个整行。
  2. Range.EntireRow返回Range区域包含的所有行,可以是多行。

    2.2.15 Range.MergeCells

    Range.MergeCells用于判断Range中是否包含合并单元格的属性。为一个可读属性

  3. 结果为False:Range区域中无任何合并单元格区域

  4. 结果为True:Range区域中都是合并单元格区域
  5. 结果为null:Range区域中既有合并单元格区域也有未合并区域

    2.3 单元格对象的常用方法

    2.3.1 Range.Select

    Range.Select为选中range的区域

  6. 使用select方法选择单元格区域后,其中的ActiveCell为Range区域的左上角单元格

  7. 使用select方法选择区域的时候必须保证被选择的表为活动工作表,若用select方法选择一个非活动工作表的区域将报错 ```vbnet ‘若工作簿中有”最终汇总”工作表、”Sheet1”工作表和”Sheet2”工作表

Public Sub activate演示()

Worksheets(“最终汇总”).Range(“A1:C4”).Select

End Sub

  1. :::info
  2. "最终汇总"工作表为活动工作表时,运行以上代码正常A1:C4区域被选择<br />若"Sheet1"工作表为活动工作表时,运行以上代码后报错
  3. :::
  4. <a name="UIG7t"></a>
  5. ### 2.3.2 Range.SpecialCells
  6. `Range.SpecialCells(Type,Value)`方法为定位符合条件的单元格
  7. 1. 一般不用记参数,所有参数可以通过录制宏录制
  8. 2. Range如果为一个单元格就是对整个表进行定位操作 , 如果为一个区域就是在这个区域内定位;
  9. <a name="gSUZh"></a>
  10. ### 2.3.3 Range.Find
  11. `Range.Find (What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)`方法用于寻找符合条件的单元格
  12. 1. 返回值为符合条件的第一个单元格,如果未发现匹配项,此方法返回 **Nothing**并报错。一般判断语句为:`If rng Is Nothing``If NOT rng Is Nothing`
  13. 2. 使用`Range.[FindNext](https://learn.microsoft.com/zh-cn/office/vba/api/excel.range.findnext) ` `Range.[FindPrevious](https://learn.microsoft.com/zh-cn/office/vba/api/excel.range.findprevious) `**方法**可重复搜索。当搜索到达指定的搜索区域末尾时,它会绕到该区域开头位置。
  14. > 若要在发生此绕回时停止搜索,需保存第一个找到的单元格的地址,然后将此后搜索到地址和保存的第一个地址对比,若相同停止搜索。
  15. ```vbnet
  16. Sub 宏3()
  17. Dim i, j, rng As Range
  18. Set rng = Selection.Find(What:="孙*", After:=Selection(1)) '此处需要使用Selection(1)作为区域的第一个单元格
  19. '如果没有符合条件的直接弹框
  20. If rng Is Nothing Then
  21. MsgBox "没有符合条件的结果!"
  22. End
  23. End If
  24. '激活被找到的单元格,作为下一次查找的After参数
  25. Selection.Find(What:="孙*", After:=[F1]).Activate
  26. '更改单元格颜色
  27. With ActiveCell.Interior
  28. .Pattern = xlSolid
  29. .PatternColorIndex = xlAutomatic
  30. .Color = 65535
  31. .TintAndShade = 0
  32. .PatternTintAndShade = 0
  33. End With
  34. '由于循环查找会无休止循环,所以需要记录第一次没找到的单元格地址,做为循环终止条件
  35. j = Selection.Find(What:="孙*", After:=[F1]).Address
  36. '开始循环查找
  37. For i = 1 To Cells.Rows.Count
  38. '循环终止条件
  39. If Selection.FindNext(After:=ActiveCell).Address = j Then '注意Range.FindNext方法的使用
  40. Exit For
  41. End If
  42. Selection.FindNext(After:=ActiveCell).Activate
  43. With ActiveCell.Interior
  44. .Pattern = xlSolid
  45. .PatternColorIndex = xlAutomatic
  46. .Color = 65535
  47. .TintAndShade = 0
  48. .PatternTintAndShade = 0
  49. End With
  50. Next
  51. End Sub
  1. 此方法不用记忆参数,所有功能可以通过录制宏得到;
  2. Range.Find中的Range为Cells为搜索整个工作表;
  3. find方法中可以使用l 匹配通配符

    2.3.4 关于Range的清除方法

  4. Range.Clear 清空Range区域内的所有内容,包括格式;

  5. Range.ClearFormats 仅清空Range区域内的格式。其中包括单元格颜色边框等格式,也包括内容的显示格式。如日期格式会变成数字;
  6. Range.ClearContents 仅清空Range区域的单元格内容,但保留所有格式;

    2.3.5 Range.Copy

    Range.Copy (Destination)为复制单元格或区域,并粘贴至Destination的方法,相当于CTRL+C、CTRL+V

  7. Destination参数省略,仅复制至剪切板;

  8. 可以直接通过**Destination**参数粘贴至非活动工作簿或工作表中,不用像用**WorkSheet.Paste**方法一样需要激活工作表并选择被粘贴的单元格 ```vbnet ‘复制C1:E5的内容,粘贴至Sheet2工作表的A1

Sub Copy方法演示()

Range(“C1:E5”).Copy Destination:=Worksheets(“Sheet2”).Range(“A1”) ‘不用激活工作表,直接路径指定即可

End Sub

  1. ```vbnet
  2. 'WorkSheet.Paste方法粘贴至其他工作表
  3. Sub copy_paste演示()
  4. Range("C10:E14").Copy
  5. Worksheets("7777").Activate '激活工作表
  6. Range("C1").Select '选择粘贴的单元格
  7. ActiveSheet.Paste '执行粘贴
  8. End Sub

2.3.6 Range.PasteSpecial

Range.PasteSpecial(Paste, Operation, SkipBlanks, Transpose)为选择性粘贴,不用记参数,可以通过录制宏得到

  1. Range.PasteSpecial方法仅用于选择性粘贴,需要在其之前搭配Range.Copy方法使用
  2. 四个参数对应下表的四个区域

image.png

2.3.7 Range.Merge/ Range.UnMerge

Range.Merge为单元格合并的方法。Range.UnMerge为解除单元格合并的方法

  1. 一般情况下,单元格合并时容易弹出对话框。所以一般用 Application.DisplayAlerts属性先关闭弹框 ```vbnet Sub 合并相同单元格()

    Application.DisplayAlerts = False

    Dim i, rng As Range

    Set rng = Range(“A3:A16”)

    i = 3 For Each r In rng.Resize(rng.Rows.Count + 1) ‘此处务必须要在原来区域基础上向下延伸一个单元格,否则最后的相同区域无法合并

    1. If r.Value <> Cells(i, 1).Value Then
    2. Range(Cells(r.Row - 1, 1), Cells(i, 1)).Merge
    3. i = r.Row
    4. End If

    Next

    Application.DisplayAlerts = True

End Sub

  1. ```vbnet
  2. Sub 合并单元格的打散()
  3. Application.DisplayAlerts = False
  4. Dim i, rng As Range
  5. Set rng = Range("A3:A16")
  6. rng.UnMerge
  7. For Each r In rng
  8. If r.Value = "" Then
  9. r.Value = Cells(i, 1).Value
  10. Else
  11. i = r.Row
  12. End If
  13. Next
  14. Application.DisplayAlerts = True
  15. End Sub

image.png

3.工作表对象

3.1 工作表对象的引用方式

  1. 使用系统自定的名称(大名)引用,如:Workbooks("汇总").Worksheets(Sheet1)

    此方式常用,因为系统自定的工作表名称不会随着name属性更改,也不会随着位置属性更改

  2. 使用对象名称(小名)引用:如:Workbooks("汇总")

  3. 使用对象的索引号引用,如:Worksheets(2)

    索引号同样为系统自动生成,但是和工作表的位置相关 索引号为可见工作表的排列顺序

  4. 父对象的引用方式,如:ActiveCell.Parent

image.png
image.png

3.2 工作表对象的常用属性

3.2.1 Sheet.UsedRange

Sheet.UsedRange返回工作表对象中已经被使用的区域。已经被使用的区域定义为能够包含所有被使用单元格的最小矩形连续区域

  1. 即便的当前激活的工作表,Sheet也不能省略 ```vbnet Public Sub function_UsedRange()

ActiveSheet.UsedRange.Select

End Sub

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/389342/1667141756851-d2767fb6-8bcb-4646-8f91-dbe5a329d0c9.png#averageHue=%23e2e2e2&clientId=u4627e7f4-a597-4&from=paste&height=454&id=u1b3b0971&originHeight=546&originWidth=786&originalType=binary&ratio=1&rotation=0&showTitle=false&size=14749&status=done&style=none&taskId=u7ba25b49-c133-40d7-aff1-3bb35e08585&title=&width=654)
  2. <a name="UZ7JP"></a>
  3. ## 3.3 工作表对象的常用方法
  4. <a name="jGBCk"></a>
  5. ### 3.3.1 WorkSheet.Activate
  6. `WorkSheet.Activate`为激活工作表,也可以用Activate方法激活单元格或工作簿
  7. ```vbnet
  8. Public Sub activate演示()
  9. Worksheets("最终汇总").Activate
  10. Worksheets("最终汇总").Range("A1:C4").Select
  11. End Sub

3.3.2 WorkSheet.Select

WorkSheet.Select为选择工作表,也可以用select方法选择单元格

  1. .Select方法和.Activate方法区别

    1. 如果Select一张隐藏工作表或不存在的工资表会报错;
    2. activate一张隐藏工作表不会报错。但activate一张不存在的工资表会报错

      3.3.3 WorkSheet.Paste

      WorkSheet.Paste方法没有参数,仅为在指定工作表在活动单元格内粘贴剪切板的内容
  2. 仅能粘贴在活动工作簿活动工作表下的被选择单元格;

  3. 工作簿工作表需要分别先激活,激活后用select方法选择单元格 ```vbnet ‘粘贴至其他工作表

Sub 宏6()

  1. Range("C10:E14").Copy
  2. Worksheets("7777").Activate '激活工作表
  3. Range("C1").Select '选择粘贴的单元格
  4. ActiveSheet.Paste '执行粘贴

End Sub

  1. <a name="T6fPF"></a>
  2. ### 3.3.4 WorkSheet.Protect/Unprotect
  3. `WorkSheet.Protect(Password)`给worksheet加锁<br />`WorkSheet.Unprotect(Password)`给worksheet解锁
  4. 1. 特别注意,加锁之前需要先运行`Range.Locked = True`
  5. <a name="pFp4e"></a>
  6. # 4.工作簿对象
  7. <a name="Yr7MB"></a>
  8. # 5.应用程序对象
  9. 应用程序对象为在VBA中输入Application.后出现方法或属性
  10. <a name="iyKr8"></a>
  11. ## 5.1 应用程序对象的属性
  12. 1. 由于属性是应用程序级别,若确实需要更改,在代码中一般成对存在(即先关闭,再打开),否则影响程序功能;
  13. 2. 或者放入条件中,条件满足时关闭,不满足时打开
  14. <a name="qPoGV"></a>
  15. ### 5.1.1 控制对话框弹出的属性
  16. `Application.DisplayAlerts`为控制对话框弹出的属性,保证代码运行不因对话框弹出而中断
  17. 1. `Application.DisplayAlerts`值为False时,任何对话框都不弹出,反之正常弹出;
  18. 2. `Application.DisplayAlerts = False`和`Application.DisplayAlerts = True`一般成对存在;
  19. ```vbnet
  20. Application.DisplayAlerts = False
  21. pass
  22. Application.DisplayAlerts = True

5.1.2 复制粘贴后复制区域的虚线框

Application.CutCopyMode = False可以取消复制粘贴后复制区域的虚线框
image.png

5.1.3 控制单元格拖放及下拉的属性

Application.CellDragAndDrop可控制单元格拖放及下拉

  1. Application.CellDragAndDrop=False禁用下拉,Application.CellDragAndDrop= True启用下拉 ```vbnet ‘指定名称的工作表禁用单元格拖放及下拉

Private Sub Workbook_SheetActivate(ByVal Sh As Object)

  1. If Sh.Name = "xxx" Or Sh.Name = "1111" Or Sh.Name = "Sheet1" Then '用于判断工作表名称
  2. Application.CellDragAndDrop = False '符合条件禁止下拉
  3. Else
  4. Application.CellDragAndDrop = True '不符合条件允许下拉,此处必须要做判断,否则整个工作簿都不下拉
  5. End If

End Sub

  1. ```vbnet
  2. '以上代码中对于工资表名称的判断写法较为复杂,可简化
  3. Private Sub Workbook_SheetActivate(ByVal Sh As Object)
  4. Dim s As String
  5. s = ",xxx,1111,Sheet1," '设定不能修改表的名称集合,且用逗号作为占位符,原因是为了未来匹配",XXXX,",这样不会出现名称包含错误
  6. If Not VBA.InStr(s, "," & Sh.Name & ",") Is Nothing Then '将工作表名称构建成",XXXX,"的样式,用instr函数查找
  7. Application.CellDragAndDrop = False
  8. Else
  9. Application.CellDragAndDrop = True
  10. End If
  11. End Sub

5.1.4 调用工作表函数的属性

Application.WorksheetFunction.函数名(参数)

5.1.5 获得交叉区域的属性

Intersect(Range1, Range2,...)获得Range1, Range2区域的交叉区域。

  1. 如果没有交叉区域返回Nothing
  2. 代码中me表示当前对象 ```vbnet ‘在工作表的使用区域内开启高亮灯

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

If Not Intersect(Target, Me.UsedRange) Is Nothing Then Cells.Interior.Color = xlNone Intersect(Rows(Target.Row), Range(“A1:G13”)).Interior.Color = 666 ‘Rows(Target.Row)可以换成Target.EntireRow Intersect(Columns(Target.Column), Range(“A1:G13”)).Interior.Color = 666 End If

End Sub

  1. <a name="JXg9G"></a>
  2. ### 5.1.6 自动计算的属性
  3. `Application.Calculation`返回当前计算模式的属性。对于超大计算量的更改来说一般先关闭自动计算,所有代码运行完毕后开启。
  4. 1. 返回值情况
  5. 1. `xlCalculationAutomatic`或 `-4105`:自动计算
  6. 2. `xlCalculationManual` 或`-4135`:手动计算
  7. <a name="GZcuN"></a>
  8. ### 5.1.7 单元格自身对象
  9. `Application.ThisCell`
  10. <a name="AOSMx"></a>
  11. ### 5.1.7 单元格自身对象
  12. `Application.Volatile` 自动计算
  13. 加载宏<br />split函数
  14. <a name="JAsfn"></a>
  15. ## 5.2 应用程序对象的方法
  16. 所有应用程序对象方法都能通过`Appllication.`引用出。如果不显示,按ctrl+j
  17. <a name="H0sPQ"></a>
  18. ### 5.2.1 InputBox
  19. `InputBox`方法为接收用户录入的信息
  20. 1. 用户录入的信息必须用一个变量承接;
  21. 2. inputbox的参数除了下表列出的以外,还有一个比较重要的可选参数[type],指定返回的数据类型。 如果省略此参数,则返回文本。
  22. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/389342/1667302896699-95ccddcf-88c7-4ab5-bd5e-96cc8b44528d.png#averageHue=%23fcfcfb&clientId=u958a345e-ce3c-4&from=paste&height=259&id=u666bd30b&originHeight=317&originWidth=880&originalType=binary&ratio=1&rotation=0&showTitle=false&size=13044&status=done&style=none&taskId=u556507f3-e7b9-4b19-a5a7-576e153392a&title=&width=719.6666870117188)
  23. 3. 对于能够接收多个类型值的,type参数可以为对应类型只和。如type参数为3,则为数字和文本
  24. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/389342/1667302019357-4b042a8c-f598-4385-a57f-ed93c67cc419.png#averageHue=%235290bd&clientId=u958a345e-ce3c-4&from=paste&height=216&id=uf22e06ac&originHeight=324&originWidth=832&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33867&status=done&style=none&taskId=ub678c959-5475-4074-b59b-dd89f13e373&title=&width=554.6666666666666)
  25. <a name="XAgss"></a>
  26. ### 5.2.2 SendKeys
  27. `SendKeys(Keys)`方法可通过代码模拟按下键盘按键的功能
  28. 1. `Keys`参数是一个字符串需要加引号
  29. 2. 功能按键需要用`{}`包裹,如:`"{F1}"`。不用`{}`包裹的默认输出这个字母的按键
  30. 3. `Keys`参数也可以为`{key number}`的形式确定按键点击次数,如:`{h 10} `则是指 10 次按下 H 键
  31. ```vbnet
  32. '如果鼠标选择在第一列的一个非空单元格,那么自动进入这个单元格的编辑状态
  33. Private Sub Worksheet_SelectionChange(ByVal Target As Range) '利用Worksheet_SelectionChange事件处理
  34. '这里必须要先判断Target区域的单元格数量及列号,确定只有一个单元格后再判断值是否为空,不能一并用两个and判断
  35. '原因为若选择区域为多个区域Target.Value为一个可变数组,会报数据类型错误
  36. If Target.Count = 1 And Target.Column = 1 Then '先判断单元格个数和所在列号
  37. If Target.Value <> "" Then '在判断单元格是否为空
  38. Application.SendKeys "{F2}"
  39. End If
  40. End If
  41. End Sub

5.2.3 GOTO

GOTO(reference,[scroll])方法可以直接选中将未激活工作表的区域,从而代替先Activate再select的方法

  1. reference参数为一个Range,也可以是workbook.worksheet.range形式 ```vbnet ‘常规方式为先激活工作簿,再激活工作表,最后选择单元格。但goto函数可以一步做到

‘有两个工作簿为:123.xlsm和工作簿1.xlsm ‘123.xlsm包含工作表为:Sheet1,Sheet2 ‘工作簿1.xlsm包含的工作表为:汇总,Sheet1,Sheet2,Sheet3 ‘目前活动单元格为:Workbooks(“工作簿1.xlsm”).Sheets(“汇总”)

Sub function_goto()

Application.Goto reference:=Workbooks(“123.xlsm”).Sheets(“Sheet2”).[A1:B5]

End Sub

  1. <a name="bvaxZ"></a>
  2. ### 5.2.4 Union
  3. `Union(range1,range2,...)`方法为连接不同的range,最终形成新的range
  4. ```vbnet
  5. Public Sub function_Union()
  6. Union(Range("A1:B5"), Range("A11:B15")).Select
  7. End Sub

5.2.5 Application.worksheetfunction

6.常用的函数

所有vba函数都能通过vba.引用出。如果不显示,按ctrl+j

5.1 Replace函数

Replace (expression,find,replace,[start],[count],[compare])函数用于将expression字符串中find字符串替换为replace字符串

5.2 InStr函数

InStr([start],string1,string2,[compare])函数返回一个数字。该数字为string2首次在string1中出现的位置

  1. 特殊的string1和string2时的返回值如下表

image.png

  1. 未找到匹配位置时返回Nothing ```vbnet ‘以上代码中对于工资表名称的判断写法较为复杂,可简化

Private Sub Workbook_SheetActivate(ByVal Sh As Object)

  1. Dim s As String
  2. s = ",xxx,1111,Sheet1," '设定不能修改表的名称集合,且用逗号作为占位符,原因是为了未来匹配",XXXX,",这样不会出现名称包含错误
  3. If Not VBA.InStr(s, "," & Sh.Name & ",") Is Nothing Then '将工作表名称构建成",XXXX,"的样式,用instr函数查找
  4. Application.CellDragAndDrop = False
  5. Else
  6. Application.CellDragAndDrop = True
  7. End If

End Sub

  1. <a name="DAwrK"></a>
  2. ### 5.3 Dir函数
  3. `Dir()`函数返回一个文件名字符串,其中包含问看类型后缀。若果在路径下能够找到该文件,返回文件名+后缀名,如果不能则返回空,其内部可以使用通配符
  4. 1. 函数参数为一个文件名称的完整路径,其中可以包含通配符
  5. 2. 如果路径中有符合条件的文件
  6. ```vbnet
  7. 'ThisWorkbook.Path路径为:
  8. Sub 插入批注图片()
  9. Dim rng As Range
  10. 图片路径 = Dir(ThisWorkbook.Path & "\图片\" & [A3].Value & ".*")
  11. Debug.Print 图片路径
  12. 图片路径 = ThisWorkbook.Path & "\图片\" & 图片路径
  13. Debug.Print 图片路径
  14. Next
  15. End Sub

5.4 TypeName函数