Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 在VBA中传递记录集对象销毁_Excel_Recordset_Destroy_Excel 2013_Vba - Fatal编程技术网

Excel 在VBA中传递记录集对象销毁

Excel 在VBA中传递记录集对象销毁,excel,recordset,destroy,excel-2013,vba,Excel,Recordset,Destroy,Excel 2013,Vba,我想我已经理解了记录集的传递。它总是通过引用传递。我想问的是物体的破坏 我有一个从Access获取记录集的函数。我从给定的例程调用该函数,将SQL语句传递给它并从中获取记录集结果。请参阅下面的代码示例 在调用例程结束时,我关闭记录集并将对象设置为Nothing。我不清楚的是是否需要做些什么来销毁被调用函数中的记录集对象。因为记录集是通过ref传递的,所以我倾向于认为关闭记录集并从调用例程中将其设置为Nothing也会破坏被调用函数中的记录集。更重要的是,我有一部分人认为被调用函数中的局部级别变量

我想我已经理解了记录集的传递。它总是通过引用传递。我想问的是物体的破坏

我有一个从Access获取记录集的函数。我从给定的例程调用该函数,将SQL语句传递给它并从中获取记录集结果。请参阅下面的代码示例

在调用例程结束时,我关闭记录集并将对象设置为Nothing。我不清楚的是是否需要做些什么来销毁被调用函数中的记录集对象。因为记录集是通过ref传递的,所以我倾向于认为关闭记录集并从调用例程中将其设置为Nothing也会破坏被调用函数中的记录集。更重要的是,我有一部分人认为被调用函数中的局部级别变量在函数完成后会被销毁,但我意识到自动销毁的变量不同于对象,即使在局部级别也必须手动销毁

所以问题是,我必须以某种方式销毁函数recordset对象,还是在调用例程结束时销毁recordset对象会同时销毁这两个实例?使用下面的代码示例,当rstSample被销毁时,GetReadOnlyRecords记录集是否会被销毁,或者我是否还需要做其他事情来销毁它

我问这个问题的另一个原因是,除了我已经想知道上面的事实之外,我还从另一个函数调用了GetReadOnlyRecords函数,但实际上我并不需要记录集。(请参见:私有函数ChkDataNew()作为布尔值)。在这里,我只需要知道生成的记录集是否包含任何记录,因此我不需要在调用函数中创建记录集的实例,而只需要说“if GetReadOnlyRecords(strSQL).RecordCount>0 Then”。因此,在这种情况下,调用函数中没有要销毁的记录集,这意味着GetReadOnlyRecords函数中的原始记录集不会关闭/设置为nothing。显然,我可以将记录集引入调用函数,但似乎没有必要,因为我可以在“If”语句中获得所需的所有信息。因此,如果从调用函数销毁记录集确实会在被调用函数中销毁记录集,那么我是否需要在调用函数中创建一个记录集,以便销毁它,即使我不需要它

Option Explicit

    'create a module-level, Public reference to a Connection object
    Public objConn As ADODB.Connection

    'create a string constant with the dB path
    Private Const strDBPath As String = "C:\MyPath.accdb"

    Private Const strConString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                "Data Source=" & strDBPath & ";" & _
                "Persist Security Info=False;"

Public Sub OpenDB()
    'create a new instance of the Connection object
    Set objConn = New ADODB.Connection
    objConn.Open strConString
End Sub

Public Sub CloseDB()
    objConn.Close
    Set objConn = Nothing
End Sub

Public Function GetReadOnlyRecords(strSQL As String) As Recordset

    'this routine presumes the Database already has an Open Connection
    'we can't risk possibly opening it twice

    Dim rstTMP As ADODB.Recordset

    Set rstTMP = New ADODB.Recordset
    rstTMP.Open strSQL, objConn, adOpenStatic, adLockReadOnly, adCmdText
    Set GetReadOnlyRecords = rstTMP

End Function

Private Sub UpdateData() 

    Dim rstSample As ADODB.Recordset
    Set rstSample = New ADODB.Recordset

    OpenDB
        strSQL = "SELECT * FROM tblExample"
        Set rstSample = GetReadOnlyRecords(strSQL)

        rstSample.DoStuff

        'Destroy the Recordset object
        rstDrawings.Close
        Set rstDrawings = Nothing
    CloseDB

End Sub

Private Function ChkDataNew() As Boolean

    Dim dtNewDate As Date
    Dim strSQL As String

    ChkDataNew = False
    Set dtNewDate = wsMySheet.Range("QDate").Value
    strSQL = "SELECT tblExample.[Date] FROM tblExample WHERE tblExample.[Date] = " & dtNewDate

    OpenDB
        If GetReadOnlyRecords(strSQL).RecordCount > 0 Then
            ChkDataNew = True
        End If
    CloseDB

End Function

将对象引用设置为Nothing时,实际上只是“断开”引用,而不是(直接)影响被引用对象。只要有至少一个引用指向一个被引用的对象,它就会被保留:当没有剩余的引用时,它会被自动垃圾回收(尽管可能不会立即回收)

函数中的任何记录集引用将在函数完成后立即超出范围(假设它们是局部变量而不是全局变量),因此您不必担心这些

<>技术上,在退出一个方法之前不需要设置对象引用,但是有些程序员认为它是“好的实践”。 关于“关闭”,她说:

使用Close方法关闭记录集、记录或流对象 释放关联数据和您可能拥有的任何独占访问权限 通过这个特定的对象来访问数据。你可以稍后打电话给 方法重新打开具有相同或修改的, 属性

当记录集对象关闭时,调用任何需要 实时光标生成错误

因此,关闭记录集不会导致对它的任何引用不起作用:例如,您仍然可以调用
Open
,但其他方法(例如
MoveNext
)会在关闭记录集时引发错误


我读到“在退出方法之前,不需要将对象引用设置为Nothing”,意思是“在退出创建它的例程之前,不需要将对象引用设置为Nothing”。射击。仍在试图找出如何在这里正确发布。如果我再说一遍,我道歉。(点击“enter”会给我带来很多问题,因此这将是一个连续的段落。)我认为“在退出方法之前,不需要将对象引用设置为Nothing”意味着“在退出创建它的例程之前,不需要将对象引用设置为Nothing”。这就引出了问题。关闭“那就用方法吧。如果我关闭记录集,那么所有对它的引用都将不再有效,对吗?我的意思是,当使用对象引用(无论是在创建对象的方法中,还是在接收该对象引用的任何“消费”方法中)时,在退出该方法之前,不需要将引用设置为“无”。当然,除非引用的范围与您的方法不同(例如,它可能是全局引用)。有关您的
关闭
问题,请参见我的上述编辑。我阅读了您引用的MSDN中的页面。我不知道在这之前我怎么没去过那里。我不知道有这样一种“克隆”方法,所以它为如何处理事情开辟了一整套全新的可能性。我会把这些都想清楚,再多读一些书。非常感谢你的努力,蒂姆。