ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 29721|回复: 47

[分享]VBA中名称的使用

[复制链接]

TA的精华主题

TA的得分主题

发表于 2006-11-16 22:18 | 显示全部楼层 |阅读模式
VBA中名称的使用
分类:ExcelVBA>>技术技巧

理解工作表中的名称
在Excel工作表中,一般可以通过两种方式来定义名称。第一种方式是直接在“名称框”(如图1所示)中输入名字来命名所选定的单元格或单元格区域,通常,在名称框中显示的是所在单元格的行号列标,单击其右侧的下拉箭头,可以看到工作簿中的名称列表。第二种方式是使用“定义名称”对话框来指定名称(选取菜单“插入——名称——定义”命令后,调出“定义名称”对话框,如图2所示),在该对话框中,可以定义名称常量和动态名称,而这些名称则不会出现在“名称框”中。
  图1:名称框
  图2:定义名称对话框
名称又分为全局名称和局部名称。全局名称可以在当前工作簿中的任一工作表中使用,而局部名称只能在指定的工作表中使用。如图2中所示,name1为全局名称,name2为局部名称,即局部名称所在的工作表在该名称的右侧。
此外,正如前所述,还可以在“定义名称”框中定义名称常量,如图2中的x。还可以动态命名,如图2中的NameList。它们在引用位置中进行输入。
通过在工作表中定义名称,可以更好的管理工作表数据,方便地编写公式和设置表格。正如在工作表中定义和使用名称一样,在VBA中也可以创建和使用名称,并能利用名称处理工作表中的数据。

[分享]VBA中名称的使用

[分享]VBA中名称的使用

[分享]VBA中名称的使用

[分享]VBA中名称的使用

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-11-16 22:19 | 显示全部楼层
在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 Integer
For i = 1 To 10
   MyArray(i) = i
Next i
Names.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。
注意,当前工作簿中重命名已有名称和删除名称时,要注意所要操作的名称是全局名称还是局部名称。如果为局部名称,则必须在代码中加上该名称所在工作表的引用。

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-11-16 22:20 | 显示全部楼层
命名名称注意事项
(1) 名称的最大长度为255个字符。
(2) 名称可以字母、空格或下划线开头。
(3) 名称中不能包含空格、连字线等字符。
(4) 避免在名称中使用与单元格引用相同的字符,如A1、G11等。
(5) 避免在名称中使用Excel的保留字,如:Criteria、Database、Extract、Print_Area、Print_Titles等。

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-11-16 22:22 | 显示全部楼层
一些示例
[示例1] 检查当前工作簿中某名称是否存在
Sub test()
  Dim str As Boolean
  str = NameExists("myName")
  If str = True Then
    MsgBox "该名称存在于当前工作簿中."
  Else
    MsgBox "该名称不存在."
  End If
End Sub
‘- - - - - - - - - - - - - - - - - - - - -
Function NameExists(FindName As String) As Boolean
  Dim rng As Range
  Dim myName As String
  On Error Resume Next
  myName = ActiveWorkbook.Names(FindName).Name
  If Err.Number = 0 Then NameExists = True
End Function
或者:
Function NameExists(TheName As String) As Boolean
  On Error Resume Next
  NameExists = Len(ThisWorkbook.Names(TheName).Name) <> 0
End Function

[示例2]工作簿中的所有名称可见
Sub UnHideName()
  Dim Nm As Name
  For Each Nm In Names
    Nm.Visible = True
  Next
End Sub

[示例3]列出当前工作簿中所有名称的相关信息
Sub ShowNames()
  Dim N As Integer
  For N = 1 To ActiveWorkbook.Names.Count
    On Error Resume Next
    Cells(N, 1) = "'" & ActiveWorkbook.Names(N).Name
    Cells(N, 2) = "'" & ActiveWorkbook.Names(N).RefersToRange.Address
    Cells(N, 3) = "'" & ActiveWorkbook.Names(N).ShortcutKey
    Cells(N, 4) = "'" & ActiveWorkbook.Names(N).Visible
  Next
End Sub

[示例4]显示当前单元格所命名的名称
Sub ShowNames_activecell()
  On Error Resume Next
  MsgBox ActiveCell.Name.Name
  Select Case Err.Number
    Case 0
    Case 1004
      MsgBox "单元格" & ActiveCell.Address(4) & “没有命名。”
    Case Else
      MsgBox Err.Number & " -- " & Err.Description
  End Select
End Sub
示例说明:如果要获取指定单元格所定义的名称,可以使用Name属性两次。

[示例5]删除当前工作簿中含有“name”字符的名称
Sub DeleteName()
  Dim Nm As Name
  For Each Nm In ActiveWorkbook.Names
    If Nm.Name Like "*name*" Then
      Nm.Delete
    End If
  Next Nm
End Sub

[示例6] 判断某单元格或单元格区域是否与命名区域部分重叠(By Chip Pearson)
Function NameOfParentRange(Rng As Range) As String
  Dim Nm As Name
  For Each Nm In ThisWorkbook.Names
    If Rng.Parent.Name = Nm.RefersToRange.Parent.Name Then
      If Not Application.Intersect(Rng, Nm.RefersToRange) Is Nothing Then
        NameOfParentRange = Nm.Name
        Exit Function
      End If
    End If
  Next Nm
  NameOfParentRange = ""
End Function
示例说明:如果Rng所代表的单元格或单元格区域与命名区域相交叉,则返回命名区域的名称,否则返回空。

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-11-16 22:25 | 显示全部楼层

名称的高级操作
(下面的内容整理自Chip Pearson的文章)
[增大名称框的尺寸]
在Excel工作表的名称框中(如图1所示),大约只能显示16个字符,当超过它所能容纳的字符时,后面的字符将会被截取,将不能看到完整的名称,这对前面的字符相同而区别在最后几个字符的名称来说,很不方便,但是在Excel中没有改变名称框尺寸的设置。这可通过调用Windows API来解决,通过调用API来增加下拉框的宽度。
在VBE编辑器中插入一个标准模块,并输入以下的代码:
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public 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
Public 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 Long
    Const CB_SETDROPPEDWIDTH = &H160
    Const cWidth = 400 '<<<<<<<<<<<<<<<<<<<<<<
    Res = SendMessage( _
            FindWindowEx( _
                FindWindowEx( _
                    FindWindow("XLMAIN", Application.Caption) _
                , 0, "EXCEL;", vbNullString) _
            , 0, "combobox", vbNullString), _
          CB_SETDROPPEDWIDTH, cWidth, 0)
End Sub
示例说明:上述代码运行前后的结果如图3和图4所示。在上面的代码中,可以通过改变常量cWidth(<<<所示的代码行)的值来定义下拉框的宽度。
  图3:原名称框
  图4:修改后的名称框


[为名称框定义快捷键]
Excel提供的快捷键中没有名称框的快捷键。但是,您能使用VBA代码设置快捷键,以方便能快速定位到名称框。
在VBE编辑器中,插入一个标准模块,并输入以下代码:
Public Declare Function SetFocus Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public 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 Long
    Res = SetFocus( _
        FindWindowEx( _
            FindWindowEx( _
                FindWindow("XLMAIN", Application.Caption) _
                    , 0, "EXCEL;", vbNullString) _
                    , 0, "combobox", vbNullString))
End Sub
在Excel中,选择菜单“工具——宏——宏”命令,调出“宏”对话框,为刚创建的SetFocusNameBox代码指定快捷键,如Ctrl+Shift+N。那么,以后在该工作簿中,按下Ctrl+Shift+N组合键,即可定位到名称对话框。

By fanjy in 2006-11-16

[分享]VBA中名称的使用

[分享]VBA中名称的使用

[分享]VBA中名称的使用

[分享]VBA中名称的使用

TA的精华主题

TA的得分主题

发表于 2006-11-16 23:01 | 显示全部楼层
fanjy兄弟很善于总结,谢谢分享,学习ing.

TA的精华主题

TA的得分主题

发表于 2006-11-16 23:37 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2006-11-17 09:03 | 显示全部楼层
楼主很牛!谢谢分享。顶起来,让更多的人看到此帖。

TA的精华主题

TA的得分主题

发表于 2006-11-17 09:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
好帖

TA的精华主题

TA的得分主题

发表于 2006-11-18 15:49 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-20 15:51 , Processed in 0.047585 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表