以下是我写的ActiveX Exe的测试代码,名为TestGetData.GetData
目的是希望开新的线程来执行数据库的数据读取操作,这是个简单的测试Option Explicit
'\\查询得到的记录个数
Public mReCount As Long'\\查询结束事件
Public Event OnQueryEnd()
Public Sub ExecSQL(ByRef strSQL As String, ByRef mConn As ADODB.Connection)
'\\执行SQL语句的接口
    Dim rsTemp As New ADODB.Recordset
    rsTemp.Open strSQL, mConn, 1, 1
    mReCount = rsTemp.RecordCount
    RaiseEvent OnQueryEnd    
    
End Sub在窗体引用编译后的TestGetData.exe
Option ExplicitDim WithEvents objTest As TestGetData4.GetData4
Dim Conn As ADODB.ConnectionPrivate Sub Command1_Click()    Dim strSQL As String
    strSQL = "select * from Tab1"
    objTest.ExecSQL strSQL, Conn
    End SubPrivate Sub Form_Load()    Set Conn = New ADODB.Connection
    Dim strSQL As String
    strSQL = ".........."          '\\这里是连接数据库的语句
    Conn.ConnectionString = strSQL
    Conn.Open
    Set objTest = New TestGetData.GetDataEnd SubPrivate Sub objTest_OnDataExeced()    Dim lngRe As Long
    lngRe = objTest.mReCount
    MsgBox lngReEnd Sub现在出现的错误是:
“实时错误3001,参数类型不正确,或不在可以接受的范围之内
或者与其他参数冲突”
请教各位,帮忙看看代码,看看哪错了!

解决方案 »

  1.   

    怎么一时TestGetData4.GetData4,一时TestGetData.GetData
      

  2.   

    不好意思,都是TestGetData.GetData因为我写了几个例程来测试,加上编号1,2,3,4了
    刚才贴代码出来的时候不小心贴错了
      

  3.   

    奇怪,刚才我将ActiveXExe里面的代码拷贝出来
    封装成一个DLL,然后测试,是可以顺利执行的哦
      

  4.   

    我想问一下,你的代码就这些吗?你是如何体现ActiveX EXE的好处的?你这样用ActiveX EXE还不如用ActiveX DLL的好,因为你的这种做法,当ActiveX EXE的操作需要很长时间时,你的主程序一样被挂起了,这个“多进程”又有什么用?
      

  5.   

    哈哈,XunBaian(蓝水晶)
    你昨天才回我这个问题啊
    http://community.csdn.net/Expert/topic/3856/3856106.xml?temp=.9145471我现在不就是按照你的意见正在做测试啊请教请教,这个ActiveX Exe有什么好的写法
      

  6.   

    按照我的理解
    ActiveX Exe会另外开一个进程来执行其中的代码
    将数据库的操作封装在内,其他非数据库的操作可以正常运行
    不会因为数据库操作导致迟钝是不是这样??
      

  7.   

    调用ActiveX EXE的接口,如果这个接口是费时操作的话,是达不到“多进程”的效果的。
    所以,“费时”的操作必须异步执行,你的这种调用方法明显是有问题的。你可以试试在你的接口中加个费时的操作,再在主程序中调用,你会发再主程序不能操作了(被要求挂起)
      

  8.   

    ActiveX EXE用法举例说明,仅供参考:Bas标准模块:
    Public gstrSQL As String接口类:'\\执行SQL语句的接口
    Public Sub ExecSQL(ByVal vstrSQL As String)
       gstrSQL = vstrSQL'接口仅赋值,然后立即返回
    End Sub窗体,加一个Timer1
    Private Sub Timer_Timer()  rst.Open gstrSQL ... '费时的操作在这里进行
      ...
      RaiseEvent 将数据以事件的形式返回到接口类,再由接口类返回给主程序End Sub
      

  9.   

    做了测试,的确如 XunBaian(蓝水晶) 所说,谢谢指教我试试你给的代码
      

  10.   

    经过XunBaian(蓝水晶),重新编写这个ActiveX EXE
    经过测试,可以正常运行,大家看看代码,提点意见,呵呵ActiveX EXE名称:TestGetData6.GetData6组成:窗体 - Form1(放置一个定时器timer1)
          模块 - mdlDefine
          类模块 - GetData6
    代码:
    窗体:Option ExplicitPublic Event OnQueryEnd()Private Sub Timer1_Timer()    Dim mstrSQL As String
        Timer1.Enabled = False
        If colSQL.Count <> 0 Then
            mstrSQL = colSQL.Item(1)
            Set Rs = Nothing
            Set Rs = New ADODB.Recordset
            DoEvents
            Rs.Open mstrSQL, Conn, 1, 1
            DoEvents
            RaiseEvent OnQueryEnd
        End If
        Timer1.Enabled = TrueEnd Sub模块mdlDefineOption Explicit
    Public colSQL As Collection   '\\SQL 队列
    Public Conn As ADODB.Connection
    Public blnConnOpen As Boolean
    Public Rs As ADODB.Recordset类模块 GetData6
    Option ExplicitPublic Event OnQueryEnd()
    Dim WithEvents mForm As Form1Public Sub ExecSQL(ByVal mstrSQL As String)    colSQL.Add mstrSQL   '\\将SQL命令存入队列中End SubPublic Sub Init()
    '\\类初始化
        
        Set colSQL = New Collection
        Set mForm = New Form1
        Set Conn = New ADODB.Connection
        mForm.Timer1.Enabled = True
        mForm.Timer1.Interval = 2000End SubPublic Sub OpenConn(ByVal mConnectionString As String)
    '\\建立数据库连接    Conn.ConnectionString = mConnectionString
        Conn.Open
        
        If Err.Number = 0 Then
            blnConnOpen = True
        Else
            blnConnOpen = False
        End If
        Err.ClearEnd SubPrivate Sub mForm_OnQueryEnd()
        
        RaiseEvent OnQueryEndEnd SubPublic Function GetReordset() As ADODB.Recordset
    '\\获得结果记录集
        Set GetReordset = RsEnd FunctionPublic Sub objClose()
    '\\关闭释放资源   
        mForm.Timer1.Enabled = False
        Set mForm = Nothing
        Conn.Close
        Set Conn = Nothing
        Set colSQL = NothingEnd Sub
      

  11.   

    补充:
    在窗体代码那里要加上一句
    colSQL.Remove 1
    在队列中清除已经执行完毕的SQL
      

  12.   

    ActiveX EXE 这样用就对了,只是觉得为了打开一个记录集用ActiveX EXE有点用牛刀杀小鸡(题外话)。
      

  13.   

    另外你的程序有太多的缺陷,就举一个例子吧:你在类初始化中New集合对象是不对的,你这个集合是工程内部的一个全局对象,你应在bas的Sub Main中New,否则当该类被生成多个实例时,岂不是New了多次?这只是一个,另外的自已找找吧,我们要习惯用严谨的思维思考问题。
      

  14.   

    当然在类里也行,但必须要适当的处理一下:
    If colSQL IsNothing Then
       Set colSQL = New Collection
    End If
      

  15.   

    进程间传递数据是不是很耗资源的?呵呵,现在问题是取数据的时候,系统不会迟钝了但是,从ActiveXExe传RecordSet对象回主系统的时候系统会迟钝啊