Excel 2007出于安全的考虑,对文件名作了处理,以xlsx为后缀名的文件不包含任何宏或者VBA代码,而以xlsm为后缀名的文件才可以enable macro。所以如果要为Excel 2007撰写任何VBA代码,都需要保存为xlsm的类型,而不要保存为xlsx类型,否则VBA代码将会丢失。
首先, 我们先创建一个 Excel 加载宏文件:
1) 新建一个 Excel 工作薄, 按 Alt + F11 转至 VBE 窗口, 点击菜单 "插入/模块", 在打开的 "模块1" 代码窗口中我们将添加一个自定义工作表函数 SplitText. 把下面的代码复制过去:
Public Const funlDirectionByRow = 1
Public Const funlDirectionByColumn = 0
Public Const funlDirectionByColumn = 0
Public Function SplitText( _
ByVal Text As String, _
Optional ByVal Delimiter As String = ",", _
Optional ByVal Direction = funlDirectionByColumn) As Variant
ByVal Text As String, _
Optional ByVal Delimiter As String = ",", _
Optional ByVal Direction = funlDirectionByColumn) As Variant
If Trim(Text) = "" Then
vReturn = ""
Else
vReturn = Split(Text, Delimiter)
End If
If Direction = funlDirectionByRow Then
SplitText = vReturn
Else
SplitText = Application.WorksheetFunction.Transpose(vReturn)
End If
End Function
vReturn = ""
Else
vReturn = Split(Text, Delimiter)
End If
If Direction = funlDirectionByRow Then
SplitText = vReturn
Else
SplitText = Application.WorksheetFunction.Transpose(vReturn)
End If
End Function
2) 关闭 VBE 窗口回到 Excel 界面, 按 Ctrl + S 保存工作薄, 在弹出的 "另存为" 对话框中选择 "Microsoft Office Excel 加载宏(*.xla)" 文件类型, 输入文件名 "FuncL", 点击 "确定". 这时 Excel 会在默认的 AddIn 位置保存 FuncL.xla. 保存成功后关闭 Excel.
3) 重新打开 Excel, 并安装 FuncL.xla. 对于 Excel 2007 请点击 "Excel 选项/加载项", 在 "管理" 中选择 "Excel 加载项" 并点击 "转到"; 对于 Excel 2003 及之前版本请点击 "工具/加载宏". 在弹出的窗口中勾选上 "FuncL". 至此, Funcl.xla 已经安装成功.
如何使用 SplitText 呢? 很简单, 在任何一个打开的 Excel 文件中都已经可以使用 SplitText 工作表函数了.
接下来就介绍一下如何注册自定义工作表函数:
对于上面定义的 SplitText 其实 Excel 会为它自动注册为 "自定义" 类别的工作表函数, 请看下图:
但有点遗憾的是没有函数说明, 而且当点击 "确定" 按钮时, 也没有参数说明:
如果能像 Excel 内置函数那样给予准确的函数说明及参数说明就显示更加专业了.
方法1: 添加函数说明, 不能设置函数分类, 不能添加参数说明
当我们还没将 FuncL 工作薄保存为加载宏(xla)文件之前可以在 VBE 中为 SplitText 函数添加函数说明, 具体方法:
1) 在 VBE 界面中按 F2 打开对象浏览器窗口
2) 在 "工程/库" 下拉列表框中选择 VBAProject,
3) 这时在 "类" 列表中就会显示出 VBAProject 库下的所有模块及类模块, 在列表中点击 "模块1", 就会在 "模块1" 的成员列表中显示出 "模块1" 的所有成员:
4) 用鼠标右键点击 "SplitText", 并点击 "属性". 这时弹出 "成员选项" 对话框:
在 "描述" 中可以输入函数的说明, 输入完成后, 点击 "确定".
5) 关闭 VBE 窗口回到 Excel 界面, 这里点击公式编辑栏上的 fx 就会看到函数的说明信息了
但此方法仍然没办法设置函数的参数说明信息.
方法2: 添加函数说明, 可设置函数分类, 不能添加参数说明
Excel 对象模型中的 Application 对象提供一个方法 MacroOptions, 利用此方法不仅可以设置函数说明, 同时可以设置函数分类. 格式如下:
MacroOptions(Macro, De script ion, HasMenu, MenuText, HasShortcutKey, ShortcutKey, Category, StatusBar, HelpContextID, HelpFile)
其中的部分参数:
Macro: 函数名
De script ion: 函数说明
Category: 函数类别. 可以是自定义的类别名称, 也可以是数值, 其中值对应的类别:
在Excel中编写自定义函数后,如果希望能够像使用其他Excel内置函数一样去使用用户的自定义函数,需要用Application.MacroOptions方法对用户自定义函数进行注册,Auto_Open和Auto_Close过程都是Excel打开和关闭时自动调用的过程,用户可以通过重写这两个过程并使用Application.MacroOptions方法来注册和注销用户自定义函数。比如:
'将摄氏温度转换为华氏温度
Function Fehrenheit(Centigrade)
Fehrenheit = Centigrade * 9 / 5 + 32
End Function
Function Fehrenheit(Centigrade)
Fehrenheit = Centigrade * 9 / 5 + 32
End Function
'注册自定义函数
Sub Auto_Open()
Dim sDes As String
sDes = "将摄氏温度转换为华氏温度"
'=用于对普通变量赋值,:=用于对对象赋值,相当于set Obs = object,Category用于告诉Excel此函数的分类,14表示用户自定义
Application.MacroOptions Macro:="Fehrenheit", Description:=sDes, Category:=14
'指定函数的快捷键为Ctrl+y
Application.OnKey "^y", "Fehrenheit"
End Sub
'注销自定义函数
Sub Auto_Close()
Application.MacroOptions Macro:="Fehrenheit", Description:=Empty, Category:=Empty
End Sub
Sub Auto_Open()
Dim sDes As String
sDes = "将摄氏温度转换为华氏温度"
'=用于对普通变量赋值,:=用于对对象赋值,相当于set Obs = object,Category用于告诉Excel此函数的分类,14表示用户自定义
Application.MacroOptions Macro:="Fehrenheit", Description:=sDes, Category:=14
'指定函数的快捷键为Ctrl+y
Application.OnKey "^y", "Fehrenheit"
End Sub
'注销自定义函数
Sub Auto_Close()
Application.MacroOptions Macro:="Fehrenheit", Description:=Empty, Category:=Empty
End Sub
另一个需要注意的是,在Excel中开发自定义函数,代码需要写在VBA模块中,而不是ThisWorkbook,工作表或者窗体代码中。
方法3: 添加函数说明, 可设置函数分类, 可添加参数说明
这里借用了一下 Excel Macro 4.0 的 Register 宏函数, 而通过 Application 的 ExecuteExcel4Macro 方法来调用 Excel 的宏函数命令. 请将下面代码粘贴至任意工作薄的一个模块中:
Public Sub gRegisterUDF( _
ByVal FunctionName As String, _
ByVal Category As String, _
ByVal De script ion As String, _
ByVal Args As String, _
ByVal De script ionArgs As String)
ByVal FunctionName As String, _
ByVal Category As String, _
ByVal De script ion As String, _
ByVal Args As String, _
ByVal De script ionArgs As String)
Application.ExecuteExcel4Macro _
"REGISTER(""" & mGetSys32Path() & "\user32.dll"",""CharPrevA"",""PPP"",""" _
& FunctionName & """,""" & Args & """,1" _
& ",""" & Category & """,,,""" & De script ion & """," & De script ionArgs & ")"
"REGISTER(""" & mGetSys32Path() & "\user32.dll"",""CharPrevA"",""PPP"",""" _
& FunctionName & """,""" & Args & """,1" _
& ",""" & Category & """,,,""" & De script ion & """," & De script ionArgs & ")"
End Sub
上面的方法可以自动注册一个 Excel 自定义工作表函数, 其中参数:
FunctionName: 工作表函数名
Category: 函数类别
Category: 函数类别
De script ion: 函数说明
Args: 参数列表. 参数之间用 "," 分隔
De script ionArgs: 参数说明.参数说明之间用 "," 分隔
甚至我们可以利用 Unregister 宏函数注销一个工作表函数, 让函数仅在需要的时候出现在 "插入函数" 对话框中. 注销函数代码如下:
Public Sub gUnregisterUDF( _
ByVal FunctionName As String)
ByVal FunctionName As String)
With Application
.ExecuteExcel4Macro "UNREGISTER(" & FunctionName & ")"
.ExecuteExcel4Macro "REGISTER(""" & mGetSys32Path() & "\user32.dll""" & _
",""CharPrevA"",""P"",""" & FunctionName & """,,0)"
.ExecuteExcel4Macro "UNREGISTER(" & FunctionName & ")"
End With
End Sub
.ExecuteExcel4Macro "UNREGISTER(" & FunctionName & ")"
.ExecuteExcel4Macro "REGISTER(""" & mGetSys32Path() & "\user32.dll""" & _
",""CharPrevA"",""P"",""" & FunctionName & """,,0)"
.ExecuteExcel4Macro "UNREGISTER(" & FunctionName & ")"
End With
End Sub
注册 SplitText 的示例:
Call gRegisterUDF( _
FunctionName:="SplitText", _
Category:="文本", _
De script ion:="分隔字符串,并返回一个二维数组(只包含一行或一列)。", _
Args:="Text, Delimiter, Direction", _
De script ionArgs:="""字符串"",""分隔符(默认为半角的逗号) "",""返回数组的方向(0 - 列方向; 1 - 行方向) """)
FunctionName:="SplitText", _
Category:="文本", _
De script ion:="分隔字符串,并返回一个二维数组(只包含一行或一列)。", _
Args:="Text, Delimiter, Direction", _
De script ionArgs:="""字符串"",""分隔符(默认为半角的逗号) "",""返回数组的方向(0 - 列方向; 1 - 行方向) """)
运行完上面一行代码后我们再来看一下 "插入函数" 的参数说明界面:
发现参数的说明已经出现了.
而且通过此方法可以在任意 Excel 文件中输入 = Sp 出现 SplitText 的函数提示:
一切问题全部解决!