丛林怪兽:VBA中名称的使用

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 17:55:26
 我们知道,通过在工作表中定义名称,可以更好地管理工作表数据,方便编写公式和设置表格。同样,在VBA中也可以创建和使用名称,也能利用名称方便地处理工作表中的数据。
在VBA中名称的基本操作
1、创建名称
① 可以使用下面的代码在当前工作簿中创建名称:
ActiveWorkbook.Names.Add Name:="MyName", RefersToR1C1:="=Sheet1!R2C2:R6C4"

或者

ActiveWorkbook.Names.Add Name:="MyName", RefersTo:="=Sheet1!$B$2:$D$6"

代码将当前工作簿中工作表Sheet1的单元格区域B2:D6命名为MyName,该名称为全局名称。
注意,在名称中不能出现空格和单元格引用,并且如果对命名区域使用A1样式的引用,那么最好使用绝对引用,否则所命名的区域将会不确定。
在名称前加上工作表名,将创建局部名称,例如:

ActiveWorkbook.Names.Add Name:="Sheet1!MyName1", RefersTo:="=Sheet1!$B$2:$D$6"

上面的代码在工作表Sheet1中将单元格区域B2:D6命名为MyName1,该名称为局部名称。
也可以通过引用指定的工作表创建局部名称,例如:

Worksheets("sheet2").Names.Add Name:="MyName2", RefersTo:="=Sheet2!$A$1:$B$3"

上面的代码在工作表Sheet2中创建一个局部名称MyName2,代表Sheet2中的单元格区域A1:B3。
② 一种简单的命名方法。例如:

Worksheets("Sheet1").Range("B8:C10").Name = "MyName3"

上面的代码将工作表Sheet1中的单元格区域B8:C10命名为MyName3,该名称为全局名称。

Worksheets("Sheet2").Range("H15:G16").Name = "Sheet2!MyName4"

上面的代码将工作表Sheet2中的单元格区域H15:G16命名为MyName4,该名称为局部名称。
注意,这种方法只能应用于命名单元格区域,不能够用来命名公式、数字等。
③ 在当前工作表中命名局部区域,该区域为其它工作表中的单元格区域。

Worksheets("Sheet1").Range("E6:F8").Name = "Sheet2!MyName5"

或者:

Worksheets("sheet2").Names.Add Name:="MyName5", RefersTo:="=Sheet1!$E$6:$F$8"

上面的代码在工作表Sheet2中命名工作表Sheet1中单元格区域E6:F8为MyName5,该名称为Sheet2中的局部名称。
④ 命名数字。例如:

Names.Add Name:="NameNumber", RefersTo:=666

将数字666命名为NameNumber。
⑤ 命名字符串。例如:

Names.Add Name:="NameString", RefersTo:="TV"

将字符串TV命名为NameString。
⑥ 命名数组。例如:

Dim MyArray(10)Dim i As IntegerFor i = 1 To 10MyArray(i) = iNext iNames.Add Name:="NameArray", RefersTo:=MyArray

上述代码先对数组赋值,然后指定名称。
⑦ 命名公式。例如:

Names.Add Name:="NameFormlas", RefersTo:="=OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),1)"

上面的代码命名了一个公式,可以用来创建动态表格或引用动态的区域。
使用上面的方法命名数字、字符串、数组或公式,在名称中存储经常要使用的值,比将该值存放在单元格中更有优势,它可以避免该值被易外修改并减少了对象的引用。
2、重命名已有的名称

Worksheets("Sheet2").Names("MyName5").Name = "MyName6"

上面的代码将工作表Sheet2中的局部名称MyName5改名为MyName6。但这种方法只能在单元格或单元格区域中进行重命名使用,而不能重命名代表公式、数组和字符串的名称。
3、改变所选区域所命名的名称的引用区域

Worksheets("Sheet1").Names.Add Selection.Name.Name,Sheet1.Range("B3:C4")

上面的代码将原来所选区域的名称的引用区域改为单元格区域B3:C4,即该名称所代表的区域已变为B3:C4,原来命名区域名称被取消。
4、提取命名区域
使用Evaluate方法,例如:

Evaluate("MyName").Interior.ColorIndex = 3

将工作表中名称MyName所代表的单元格区域的背景设置为红色。
5、隐藏名称

Names.Add Name:="HideName", RefersTo:="=$A$1:$C$3", Visible:=False

将隐藏所创建的名称。注意,如果以后创建的名称与所隐藏的名称相同,则被隐藏的名称将被覆盖。
6、删除名称

Names("MyName3").Delete

上面的代码删除当前工作簿中的名称MyName3。
注意,当前工作簿中重命名已有名称和删除名称时,要注意所要操作的名称是全局名称还是局部名称。如果为局部名称,则必须在代码中加上该名称所在工作表的引用。
命名名称注意事项
名称的最大长度为255个字符。

  • 名称可以字母、空格或下划线开头。
  • 名称中不能包含空格、连字线等字符。
  • 避免命名与单元格引用相同的名称,如A1、G11等。
  • 避免在名称中使用Excel的保留字,如:Criteria、Database、Extract、Print_Area、Print_Titles等。

一些示例
[示例1] 检查当前工作簿中某名称是否存在

Sub test()Dim str As Booleanstr = NameExists("myName")If str = True ThenMsgBox "该名称存在于当前工作簿中."ElseMsgBox "该名称不存在."End IfEnd Sub
Function NameExists(FindName As String) As BooleanDim rng As RangeDim myName As StringOn Error Resume NextmyName = ActiveWorkbook.Names(FindName).NameIf Err.Number = 0 Then NameExists = TrueEnd Function

或者:

Function NameExists(TheName As String) As BooleanOn Error Resume NextNameExists = Len(ThisWorkbook.Names(TheName).Name) <> 0End Function

[示例2]使工作簿中的所有名称可见

Sub UnHideName()Dim Nm As NameFor Each Nm In NamesNm.Visible = TrueNextEnd Sub

[示例3]列出当前工作簿中所有名称的相关信息

Sub ShowNames()Dim N As IntegerFor N = 1 To ActiveWorkbook.Names.CountOn Error Resume NextCells(N, 1) = "'" & ActiveWorkbook.Names(N).NameCells(N, 2) = "'" & ActiveWorkbook.Names(N).RefersToRange.AddressCells(N, 3) = "'" & ActiveWorkbook.Names(N).ShortcutKeyCells(N, 4) = "'" & ActiveWorkbook.Names(N).VisibleNextEnd Sub

[示例4]显示当前单元格所命名的名称

Sub ShowNames_activecell()On Error Resume NextMsgBox ActiveCell.Name.NameSelect Case Err.NumberCase 0Case 1004MsgBox "单元格" & ActiveCell.Address(4) & “没有命名。”Case ElseMsgBox Err.Number & " -- " & Err.DescriptionEnd SelectEnd Sub

示例说明:如果要获取指定单元格所定义的名称,可以使用Name属性两次。
[示例5]删除当前工作簿中含有“name”字符的名称

Sub DeleteName()Dim Nm As NameFor Each Nm In ActiveWorkbook.NamesIf Nm.Name Like "*name*" ThenNm.DeleteEnd IfNext NmEnd Sub

[示例6] 判断某单元格或单元格区域是否与命名区域部分重叠

Function NameOfParentRange(Rng As Range) As StringDim Nm As NameFor Each Nm In ThisWorkbook.NamesIf Rng.Parent.Name = Nm.RefersToRange.Parent.Name ThenIf Not Application.Intersect(Rng, Nm.RefersToRange) Is Nothing ThenNameOfParentRange = Nm.NameExit FunctionEnd IfEnd IfNext NmNameOfParentRange = ""End Function

示例说明:如果Rng所代表的单元格或单元格区域与命名区域相交叉,则返回命名区域的名称,否则返回空。
名称的高级操作
(下面的内容整理自Chip Pearson的文章)
[增大名称框的尺寸]
在Excel 2003及以前工作表的名称框中(如图1所示),大约只能显示16个字符,当超过它所能容纳的字符时,后面的字符将会被截取,因而不能看到完整的名称,这对前面的字符相同而最后几个字符不相同的名称来说,很不方便,但是在Excel中没有改变名称框尺寸的设置(Excel 2007改进了这一步,可以通过拖拉增加或减小名称框的尺寸),这个问题可以通过调用Windows API来解决。下面的代码通过调用API来增加下拉框的宽度。
在VBE编辑器中插入一个标准模块,并输入以下的代码:

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPublic Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _(ByVal hWnd1 As Long, ByVal hWnd2 As Long, _ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPublic Declare Function SendMessage Lib "user32" Alias "SendMessageA" _(ByVal hwnd As Long, ByVal wMsg As Long, _ByVal wParam As Long, lParam As Any) As Long Sub WidenNameBoxDrop2()Dim Res As LongConst CB_SETDROPPEDWIDTH = &H160Const cWidth = 400 '<<<<<<<<<<<<<<<<<<<<<<    Res = SendMessage( _FindWindowEx( _FindWindowEx( _FindWindow("XLMAIN", Application.Caption) _, 0, "EXCEL;", vbNullString) _, 0, "combobox", vbNullString), _CB_SETDROPPEDWIDTH, cWidth, 0)End Sub

示例说明:上述代码运行前后的结果如图1和图2所示。在上面的代码中,可以通过改变常量cWidth(<<<所示的代码行)的值来定义下拉框的宽度。
图1:原名称框
图2:修改后的名称框
[为名称框定义快捷键]
Excel提供的快捷键中没有名称框的快捷键。但是,您能使用VBA代码设置快捷键,以方便能快速定位到名称框。
在VBE编辑器中,插入一个标准模块,并输入以下代码:

Public Declare Function SetFocus Lib "user32" (ByVal hwnd As Long) As LongPublic Declare Function FindWindow Lib "user32" Alias "FindWindowA" _(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPublic Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _(ByVal hWnd1 As Long, ByVal hWnd2 As Long, _ByVal lpsz1 As String, ByVal lpsz2 As String) As Long Sub SetFocusNameBox()Dim Res As LongRes = SetFocus( _FindWindowEx( _FindWindowEx( _FindWindow("XLMAIN", Application.Caption) _, 0, "EXCEL;", vbNullString) _, 0, "combobox", vbNullString))End Sub

在Excel中,选择菜单“工具——宏——宏”命令,调出“宏”对话框,为刚创建的SetFocusNameBox代码指定快捷键,如Ctrl+Shift+N。那么,以后在该工作簿中,按下Ctrl+Shift+N组合键,即可定位到名称对话框。