存档在 ‘Excel对象模型’ 分类中.

再谈工作表代码名称

工作表代码名称是指代表工作表对象的名称,而不是我们常见的工作簿底部工作表标签名,如下图所示。
WSCodeName5VBAProject
当我们创建一个新工作簿时,一般情况下(当然是取决于您的Excel的设置)Excel会创建三个新工作表,其默认名称依次为Sheet1、Sheet2、Sheet3。工作表的代码名称与工作表标签名相同,也为Sheet1、Sheet2、Sheet3,如上图所示。
当然,我们可以修改这些名称,使之更具描述性。
使用CodeName属性可以获得工作表的代码名称,而使用Name属性则可获得工作表标签名称。
使用工作表代码名称有很多优点,例如不受用户更改工作表名称的影响、容易处理复制粘贴操作等。

标签: ,

FileSystemObject对象简介

FileSystemObject对象位于File System对象模型(如下图所示)的最高层,提供了对计算机文件系统的访问。要访问File System对象模型,需要添加对Microsoft Scripting Runtime库的引用,然后可以创建FileSystemObject对象的一个实例。使用File System对象模型,可以访问本地文件或网络文件,允许查找、创建、删除或者用其他方法操作文件夹和文本文件。
FileSystemModel
语法:Scripting.FileSystemObject
属性:Drives 属性
方法:BuildPath方法、CopyFile方法、CopyFolder方法、CreateFolder方法、CreaterTextFile方法、DeleteFile方法、DeleteFolder方法、DriveExists方法、FileExists方法、FolderExists方法、GetAbsolutePathName方法、GetBaseName方法、GetDrive方法、GetDriveName方法、GetExtensionName方法、GetFile方法、GetFileName方法、GetFolder方法、GetParentFolderName方法、GetSpecialFolder方法、GetTempName方法、MoveFile方法、MoveFolder方法、OpenTextFile方法
示例:
Sub test()
    Dim fs As FileSystemObject
    Dim a As TextStream
    Set fs = CreateObject(”Scripting.FileSystemObject”)
    Set a = fs.CreateTextFile(”c:\testfile.txt”, True)
    a.WriteLine (”This is a test.”)
    a.Close
End Sub

上面的示例代码中,CreateObject函数返回一个FileSystemObject对象,然后使用CreateTextFile方法在C盘根目录下创建一个名为testfile.txt的文本文件,该文件为一个TextStream对象。代码中的WriteLine方法向创建的文本文件中写入一行文本,Close方法用于刷新缓冲区并关闭文件。

VBA代码引用工作表的方法探讨

在VBA代码中引用工作表时,可以考虑三种方式:
(1)使用工作表在工作簿中的位置,即索引值。在工作簿的底部,从左到右顺序编号。如果在工作簿使用过程中,移动工作表的位置,则其索引值也会相应改变。
(2)使用工作表名称,即工作表标签。在工作簿使用过程中,用户可能随时改变其名称。
(3)使用工作表“真正的”名称,即代码名称。当创建工作表时,Excel会自动赋给该工作表代码名称,缺省情况下为Sheet后接数字,除非您在VBE中为其重命名。
在VBE中的工程窗口中,通常您可以看到:Sheet1(Sheet1),其中左侧为该工作表的代码名称,右侧括号内的为工作表标签名称(即用户为该工作表起的名字),您也可以为该工作表起别的名字如“汇总”。
下图指出了VBE中工作表代码名称和工作表名称,以及修改方法。
projectWindow

探讨
(1)编写VBA代码时,如果使用工作表索引值或工作表名称,有可能在代码运行时,用户会改变工作表的位置或工作表名称,从而会导致代码运行错误。
(2)这三种方式中,唯一不变的是工作表代码名称,除非最终用户删除了工作表或者在VBE窗口中对其重命名。这样,在用户移动工作表或者改变工作表标签时,代码仍会正常运行。因此,这种方式相对来说,应该是最安全的。
您可以在VBE中将工作表的代码名称改为有意义的名称。
(3)例如,要激活上图中的第一个工作表,则相对应的引用工作表的三种方式是:

  • 通过索引值:Sheets(1).Activate
  • 通过工作表名称:Sheets(“汇总”).Activate
  • 通过代码名称:Sheet1.Activate

(4)再举一个例子,要将上图中“汇总”工作表上A1:C10中的数据复制到“上半年”工作表中的A1:C10中,相应的也有三种方式:

  • 通过索引值:Sheets(1).[A1:C10].Copy Sheets(2).[A1]
  • 通过工作表名称:[汇总!A1:C10].Copy [上半年!A1]
  • 通过代码名称:Sheet1.[A1:C10].Copy [Sheet3.A1]

(5)不可以跨工作簿使用工作表代码名称,即不能在一个工作簿中使用另一个工作簿中的工作表代码名称。

标签: , ,

VBA:介绍WindowState属性

一般来讲,工作表窗口或工作簿窗口有三种状态:最大化、正常或最小化。使用Windowstate属性可以返回或设置窗口的状态,该属性为XlWindowState 类型,可读写。XlWindowState可为以下XlWindowState常量之一:xlMaximized、xlNormal、xlMinimized。
其语法为:expression.WindowState
其中,expression为必需,该表达式返回Application对象或Window对象。
例如,下面的三行代码分别设置窗口的三种状态。
ActiveWindow.WindowState = xlMaximized ‘当前窗口最大化
ActiveWindow.WindowState = xlMinimized ‘当前窗口最小化
ActiveWindow.WindowState = xlNormal ‘当前窗口恢复正常状态
窗口的正常状态是指工作簿标题显示在当前工作簿标题栏中,而不是Excel应用程序标题栏中(参见下图)。
WindowNormal
当然,可以使用窗口的相关属性,利用循环结构创建窗口的动态效果。例如,下面的代码将从小到最大逐渐调整工作表窗口,好像工作表窗口在增长:
Sub SheetGrow()
    Dim x As Integer

    With ActiveWindow
        .WindowState = xlNormal
        .Top = 1
        .Left = 1
        .Height = 50
        .Width = 50
    
        For x = 50 To Application.UsableHeight
            .Height = x
        Next x
    
        For x = 50 To Application.UsableWidth
            .Width = x
        Next x
    
        .WindowState = xlMaximized
    End With
End Sub

运行代码后,工作簿窗口先恢复为正常状态,然后调整高度和宽度分别为50,然后高度逐渐增长到窗口能占用的最大高度,接着宽度逐渐增长到窗口能占用的最大宽度,最后将工作簿最大化。

CommandBar对象介绍

CommandBar对象代表三个Excel用户界面元素:

  • 自定义工具栏
  • 自定义菜单
  • 自定义(右键)快捷菜单

在Excel 2007中,CommandBar对象出现在一个相当奇怪的位置。如果编写定制菜单或工具栏的VBA代码,Excel会拦截代码并忽略一些命令,定制的菜单和工具栏将出现在加载项选项卡中的菜单命令或自定义工具栏组中。为便于应用,Excel 2007中的CommandBar对象仅限制在快捷菜单操作中。
本文将提供一些关于CommandBars的背景信息。
CommandBar类型
Excel支持三种类型的CommandBars,通过其Type属性来区分。而Type属性是下面的三个值之一:

  • msoBarTypeNormal:工具栏(Type = 0)
  • msoBarTypeMenuBar: 菜单栏(Type = 1)
  • msoBarTypePopUp: 快捷菜单(Type = 2)

虽然在Excel 2007中没有使用工具栏和菜单栏,但它们仍然被包含于对象模型中,以便于与老版本的Excel相兼容。但是,试图在Excel 2007中显示类型为0或1的命令栏是无效的。例如,在Excel 2003中,下面的语句显示标准工具栏:

CommandBars("Standard").Visible = True

但在Excel 2007中,该语句将被忽略。下面专门介绍类型为2的命令栏(快捷菜单)。
列出快捷菜单
Excel 2007有65个快捷菜单,您可以运行下面的ShowShortcutMenuNames过程,遍历命令栏,如果Type属性为msoBarTypePopUp(内置的常量值为2),则在工作表中显示命令栏的索引值和名称。
Sub ShowShortcutMenuNames()
    Dim Row As Long
    Dim cbar As CommandBar
    Row = 1
    For Each cbar In CommandBars
        If cbar.Type = msoBarTypePopup Then
            Cells(Row, 1) = cbar.Index
            Cells(Row, 2) = cbar.Name
            Row = Row + 1
        End If
    Next cbar
End Sub

图1显示了该过程输出结果的一部分。
ListShortcutMenu
图1:一个简单的宏来生成所有快捷菜单的列表
引用命令栏
可以通过Index属性或Name属性引用一个特定的CommandBar对象,例如,下面的两个语句都引用在Excel桌面(Excel中没有打开任何文档时)中单击右键时的快捷菜单:

Application.CommandBars (47)

Application.CommandBars("Desktop")

CommandBars集合是Application对象的一个成员,在标准VBA模块或工作表模块中引用这个集合时,可以忽略对Application对象的引用。例如,下面的语句显示CommandBars集合中索引值为47的对象的名称:

MsgBox CommandBars(47).Name

在ThisWorkbook对象代码模块中引用CommandBars集合时,必须在其前面加上Application对象,如:

MsgBox Application.CommandBars(47).Name

注意,在不同的Excel版本中,Index值不总是保持不变。
引用命令栏中的控件
一个CommandBar对象包含Control对象,该对象是按钮或菜单。可以通过其Index属性或Caption属性来引用某控件。下面是一个简单的示例过程,显示单元格快捷菜单中第一个菜单项的标题:
Sub ShowCaption()
    MsgBox Application.CommandBars("Cell"). _
       Controls(1).Caption
End Sub

下面的过程显示在工作表选项卡中单击右键时出现的快捷菜单中每个控件的Caption属性(该快捷菜单名为Ply):
Sub ShowCaptions()
    Dim txt As String
    Dim ctl As CommandBarControl
    For Each ctl In CommandBars("Ply").Controls
        txt = txt & ctl.Caption & vbNewLine
    Next ctl
    MsgBox txt
End Sub

执行该过程后的结果如图2所示。
CellShortcutMenuCaption
图2:显示控件的Caption属性
在一些情况下,某快捷菜单中的Control对象包含其它的Control对象。例如,单元格右键菜单中的“筛选”控件包含其它控件,“筛选”控件是一个子菜单,而另外的项目是菜单项。
-----------------------
查找控件
如果所编写的代码将在不同的语言版本的Excel中使用,则应避免使用Caption属性来访问某特定的快捷菜单项。Caption属性随语言的不同而不同,因此在英文版本的Excel中编写的代码可能在其它语言的Excel版本中运行失败。
取而代之的是,应该与控件的ID一起使用FindControl方法(它们将独立于Excel的语言版本)。例如,假设想禁用工作表选项卡快捷菜单中的“重命名”菜单,如果该工作簿仅由Excel英文版本的用户使用,则下面的语句将正常运行:

CommandBars("Ply").Controls("Rename").Enabled = False

为了确保该命令在非英语版本的Excel中也能工作,需要知道该控件的ID,上面的语句将告诉您其ID是889:

MsgBox CommandBars("Ply").Controls("重命名(R)").ID

然后,来禁用该控件,使用下面的语句:

CommandBars.FindControl(ID:=889).Enabled = False

命令栏的名称在各语言版本的Excel中都是一致的,因此,对CommandBars("Desktop")的引用将总会正常运行。
-----------------------
下面的语句显示“筛选”子菜单中的第一个子菜单项:

MsgBox CommandBars("Cell").Controls("筛选(E)").Controls(1).Caption

命令栏控件的属性
命令栏控件有一些属性,来确定控件的外观和状态。下面包含了命令栏控件的一些最常用的属性:

  • Caption: 控件中显示的文本。如果该控年仅显示一个图像,则为鼠标悬浮在该控件上时的标题文字。
  • ID: 用来识别控件的一个独立的数字。
  • FaceID: 代表显示在控件文本旁边的图形图像的数字。
  • Type: 一个值,用来确定控件是按钮(msoControlButton)还是子菜单 (msoControlPopup)。
  • Picture: 显示在控件文本旁边的图形图像。
  • BeginGroup: 值为True时将在控件前面显示一个分隔条。
  • OnAction: 用户单击控件时执行的VBA宏名称。
  • BuiltIn: 如果该控件是Excel内置控件则为True。
  • Enabled: 如果可以单击控件则为True。
  • Visible: 如果控件可见则为True。一些快捷菜单包含了隐藏的控件。
  • ToolTipText: 用户移动鼠标指针到控件之上时出现的文本(对快捷菜单是不可用的)

显示所有的快捷菜单项
下面的ShowShortcutMenuItems过程创建一个表,列出了每个快捷菜单中的所有第一层次控件。对每个控件,该表包括了快捷菜单的Index和Name以及ID、Caption、Type、Enabled和Visible属性值。
Sub ShowShortcutMenuItems()
    Dim Row As Long
    Dim Cbar As CommandBar
    Dim ctl As CommandBarControl
    Range("A1:G1") = Array("Index", "Name", "ID", "Caption", _
      "Type", "Enabled", "Visible")
    Row = 2
    Application.ScreenUpdating = False
    For Each Cbar In Application.CommandBars
      If Cbar.Type = 2 Then
        For Each ctl In Cbar.Controls
            Cells(Row, 1) = Cbar.Index
            Cells(Row, 2) = Cbar.Name
            Cells(Row, 3) = ctl.ID
            Cells(Row, 4) = ctl.Caption
            If ctl.Type = 1 Then
                Cells(Row, 5) = "Button"
            Else
                Cells(Row, 5) = "Submenu"
            End If
            Cells(Row, 6) = ctl.Enabled
            Cells(Row, 7) = ctl.Visible
           Row = Row + 1
       Next ctl
     End If
    Next Cbar
End Sub

图3显示了过程运行后的一部分结果:
ListAllShortcutMenu
图3:列出所有快捷菜单项
如果运行ShowShortcutMenuItems宏,则会看到有一些快捷菜单包含隐藏或禁用的控件,它们代表在当前上下文环境中不可用的项目。
示例工作簿参见:show shortcut menu items.xlsm