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 Function SplitText( _
           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
 
   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
'注册自定义函数
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)
       Application.ExecuteExcel4Macro _
           "REGISTER(""" & mGetSys32Path() & "\user32.dll"",""CharPrevA"",""PPP"",""" _
           & FunctionName & """,""" & Args & """,1" _
           & ",""" & Category & """,,,""" & De script ion & """," & De script ionArgs & ")"
   End Sub
   上面的方法可以自动注册一个 Excel 自定义工作表函数, 其中参数:
   FunctionName: 工作表函数名
   Category: 函数类别
   De script ion: 函数说明
   Args: 参数列表. 参数之间用 "," 分隔
   De script ionArgs: 参数说明.参数说明之间用 "," 分隔

   甚至我们可以利用 Unregister 宏函数注销一个工作表函数, 让函数仅在需要的时候出现在 "插入函数" 对话框中. 注销函数代码如下:
   Public Sub gUnregisterUDF( _
       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
 
   注册 SplitText 的示例:
   Call gRegisterUDF( _
        FunctionName:="SplitText", _
        Category:="文本", _
        De script ion:="分隔字符串,并返回一个二维数组(只包含一行或一列)。", _
        Args:="Text, Delimiter, Direction", _
        De script ionArgs:="""字符串"",""分隔符(默认为半角的逗号) "",""返回数组的方向(0 - 列方向; 1 - 行方向) """)

   运行完上面一行代码后我们再来看一下 "插入函数" 的参数说明界面:
  
   发现参数的说明已经出现了.
 
   而且通过此方法可以在任意 Excel 文件中输入 = Sp 出现 SplitText 的函数提示:
  
 
   一切问题全部解决!