自定义COM DLL在对象浏览器可见但Excel VBA报用户定义类型未定义
问题修复步骤
一、修正VB.NET代码的COM兼容问题
- 给SQLCOMS类补充COM必要特性,补充异常逻辑避免空引用报错:
Imports System.Runtime.InteropServices Imports System.Windows.Forms Imports ADODB ' 提前在项目中引用ADODB互操作程序集 Namespace bbsSQLForExcel <ComVisible(True)> <Guid("请通过VS菜单栏「工具→创建GUID」生成唯一ID替换此处内容")> <ClassInterface(ClassInterfaceType.AutoDual)> ' 显式指定类接口类型,确保COM可识别所有公共成员 Public Class SQLCOMS ' 新增显式公共无参构造函数,满足COM实例化要求 Public Sub New() MyBase.New() End Sub ' 原有SQLDate、ConvertToRecordset、TranslateType方法无需修改 Function RunSQL(ByVal strSQL As String, ByVal strDatabase As String, Optional ByVal strTeam As String = "", Optional ByVal blAlwaysDS As Boolean = False, Optional ByVal blTimeLogComments As Boolean = False, Optional ByVal blSomerfield As Boolean = False, Optional ByVal blUsePayrollLive As Boolean = False, Optional ByVal intTimeOutOverride As Integer = 15) As ADODB.Recordset Dim strConn As String Dim sqlConnection As System.Data.SqlClient.SqlConnection Dim sqlCommand As System.Data.SqlClient.SqlCommand Dim dataAdapter As System.Data.SqlClient.SqlDataAdapter Dim dataSet As System.Data.DataSet Select Case strDatabase Case "Employees", "Users" strConn = "data source=192.168.0.222;initial catalog=BBSEmployees;persist security info=False;user id=user;workstation id=DELL_LT;packet size=4096;password=pwd" Case "P3" strConn = "data source=192.168.0.222;initial catalog=p3;persist security info=False;user id=user;workstation id=DELL_LT;packet size=4096;password=pwd" If Not (blUsePayrollLive) Then strSQL = Replace(strSQL, "PayrollSQL", "PayrollSQLTest", , , CompareMethod.Text) End If End Select sqlConnection = New System.Data.SqlClient.SqlConnection(strConn) strSQL = "Set Arithabort ON; " + strSQL sqlCommand = New System.Data.SqlClient.SqlCommand(strSQL, sqlConnection) sqlCommand.CommandTimeout = intTimeOutOverride dataAdapter = New System.Data.SqlClient.SqlDataAdapter(sqlCommand) dataSet = New System.Data.DataSet() Try dataAdapter.Fill(dataSet) ' 补充空表判断,避免查询无结果时报错 If dataSet.Tables.Count > 0 Then Return ConvertToRecordset(dataSet.Tables(0)) Else Return Nothing End If Catch ex As System.Data.SqlClient.SqlException MessageBox.Show(ex.Message) Return Nothing Catch ex As Exception MessageBox.Show(ex.Message) Return Nothing End Try End Function ' 剩余原有方法无需修改 End Class End Namespace
- 项目属性检查:
- 切换到「生成」选项卡,勾选「为COM互操作注册」
- 平台目标和Excel位数保持一致:32位Excel选「x86」,64位Excel选「x64」,不要使用「Any CPU」
- 打开「应用程序→程序集信息」,勾选「使程序集COM可见」
二、DLL注册规范
如果是跨机器部署,需要用对应位数的regasm工具以管理员权限执行注册:
- 32位Excel:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe 你的DLL完整路径 /codebase /tlb - 64位Excel:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe 你的DLL完整路径 /codebase /tlb
三、VBA端问题修复
- 早绑定报「用户定义类型未定义」:
- 进入VBA编辑器「工具→引用」,同时勾选你编写的DLL和「Microsoft ActiveX Data Objects x.x Library」(返回ADODB.Recordset必须引用该库)
- 变量定义写法示例:
Dim obj As bbsSQLForExcel.SQLCOMS Set obj = New bbsSQLForExcel.SQLCOMS
- 晚绑定报无法创建ActiveX组件:
- 90%以上是注册位数和Excel位数不匹配导致,按上述注册步骤重新操作即可
- 可打开注册表搜索
bbsSQLForExcel.SQLCOMS,确认是否存在对应的CLSID项,检查ProgID是否正确
内容的提问来源于stack exchange,提问作者Matt Bartlett
相关产品推荐
相关产品推荐

