对不起墙壁的文的人,但这一要求expliaining,太多的代码来后...

我进口宽度固定的文件进入访问的方法,需要输入数据。我进口的文件中使用transferText成两个规范(那些全球性的,其他是特殊情况).

我有一个功能,使用道,以期通过的所有领域中的对象TableDefs建立一个重复表包括一个自动增量PK所以我们的能力,以编辑这些记录。我推入数据,表格与插入。

伟大工程。错误被发现,用户进入数据输入手动纠正这节奏通过筛选400字线路和重新组织的一切方式,它应该是。伟大的作品!

的问题:当数据输入的变化都作出了承诺按钮被按下要求一个功能模块内外的形式。它关闭了数据输入形成并推动信息回到原来的表减去autoincremented PK,并且应该是下降的复制的表ID的,并产生一个新的搜索再一次错误...

它推回原来的只是好的,但它将不会下降ID表。总是回到我的消息,表示该表是锁着的。我注意到了该表是indefiniatly锁定下来,直至所有职能/潜艇退出。在任何时逐步通过代码我不能手动删除它,一旦执行已经完成了我能去除它。

我假设因为我称这个过命令的形式,这锁不会被释放,直到所有代码的完成和形式终止可以被称为和做的事情。任何想法?是的,这是非常野蛮的,但它工作得很好,我只是需要能够把这种其他表离开这个星球所以我可以redrop更新的副本...

在最糟糕的情况下,我可以使用户密切形式和打的另一个按钮在的主要形式,但这是正在设计的重与用户compitence记在心。但是这现在已经我全的关注和想至少找到一个解决方案,即使它不是最佳的一个。

-编辑

两种形式是用在这个问题

FormA (Role: Load in and search for problems)

Examine button is pressed that:

 - Uses TextTransfer based on predefined specs into tempExtract to
       import the file

 - DAO fires off on the Fields collection in tableDefs for
   tempExtract, creates new table tempExtractID

 - Performs searches through the file to find errors.  Errors are saved to
   a table Problem_t.  Table contains Problem_ID (Set from the ID field
   added to tempExtractID) and Description

 - Execution of these tasks is successfully requerying the initial
   form to showing a list of problems and number of occurances.  A button
   gains visibility, with onClick that opens the form DataEntry.            

 - At this point in the code after DAO execution, I can DROP the table
   tempExtractID.  DAO is NOT used again and was only used to build a new table.

FormB数据条目形式

只要我打开这种形式,表tempExtractID变被锁,我不能下降表。该记录源的形式querys tempExtractID对ID在Problems_t只返回是我们需要的关键。

我不能下降表,直到该形式具有完全终止。按钮在数据输入的形式是按承诺的变化,其中有的只是 5 行代码,获得火了之前我得到我的锁错误。

*Xargs refers to the list of Field names pulled earlier through DAO.  As DAO loops through Field objects, the physical names are added to an Xargs String which is placed in this table.  Basically everything but the AutoNumber is being inserted back

    docmd.Close acForm, "frmDataEntry", acSaveNo
    call reInitializeExtract
         > docmd.RunSQL "DELETE FROM tempExtract"
         > docmd.RunSQL "INSERT INTO tempExtract SELECT (" & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" & ") FROM tempExtractID"
    docmd.DeleteObject acTable, "tempExtractID"

这是唯一的代码之间运行的时间那里的形式打开(其中表第一被锁定),并继续被锁定,直至所有潜艇和功能已经完成。

有帮助吗?

解决方案

我建议设置形式vbNullString的记录源,然后删除该表。这应该工作,除非你也有组合框等等绑定到该表。

其他提示

没有代码这很难说,但是如果您使用的道你需要清理你的代码的对象。这意味着设定为什么你的数据库对象,并关闭和设置没有任何记录集中的对象。

  Dim db As DAO.Database
  Dim rs As DAO.Recordset

  Set db = DBEngine.OpenDatabase("[path to database]")
  Set rs = db.OpenRecordset("[SELECT statement]")
  rs.Close
  Set rs = Nothing
  db.Execute("[DML or DDL statement]", dbFailOnError)
  db.Close
  Set db = Nothing

  Set db =CurrentDB
  Set rs = db.OpenRecordset("[SELECT statement]")
  rs.Close
  Set rs = Nothing
  Set db = Nothing  ' you don't close a db variable initialized with CurrentDB

同时VBA是应该收拾这些对象,当他们出去的范围,这不是100%可靠的(因为VBA使用的参考计数,以跟踪一个物体是否可以释放,并且它不总是知道什么时候的所有参考文献已经清除).

留下的对象是最可能的来源的锁,所以你应该确保你在清理你的对象变量后,你已经完成了他们。

编辑看了之后,你使用DoCmd.RunSQL:

使用DoCmd.RunSQL是有可能的原因问题。它肯定是带走你的方案管理的连接。如果您使用的道而你会拥有控制权的连接,以及避免真正的陷阱的DoCmd.RunSQL,这是它不处理错误。如果仔言或声明不能成功地完成在全,整个事情应该失败。例如,如果你追加100记录和10他们的失败为关键的侵犯行为,DoCmd.RunSQL将透明地追加的90和未报告的10个失败。它是相同的更新和任何其/言发言。DoCmd.RunSQL"有益的"默默地完成了许多更新,因为它可以离开你有没有想到,一些它无法完成。

理所当然的,在某些情况下,你可能会想要这样的事情发生,例如,如果你追加记录的,你知道可能具有PK碰撞和不想要花费的CPU周期外加入,消除了重复的一套记录你追加。

但大多数时候,这不是这种情况。

正如我在上面的评论,我使用一个功能,目的是要以透明代替DoCmd.RunSQL和使用一道执行的发言和错误的处理。我已经发布了几次关于如此(这里有一个),这里的版本,我在生产使用在我的目前最活跃的发展项目:

  Public Function SQLRun(strSQL As String, Optional db As Database, _
       Optional lngRecordsAffected As Long) As Long
  On Error GoTo errHandler
    Dim bolCleanup As Boolean

    If db Is Nothing Then
       Set db = CurrentDb
       bolCleanup = True
    End If
    'DBEngine.Workspaces(0).BeginTrans
    db.Execute strSQL, dbFailOnError
    lngRecordsAffected = db.RecordsAffected
    'DBEngine.Workspaces(0).CommitTrans

  exitRoutine:
    If bolCleanup Then
       Set db = Nothing
    End If
    SQLRun = lngRecordsAffected
    'Debug.Print strSQL
    Exit Function

  errHandler:
    MsgBox "There was an error executing your SQL string: " _
       & vbCrLf & vbCrLf & Err.Number & ": " & Err.Description, _
       vbExclamation, "Error in SQLRun()"
    Debug.Print "SQL Error: " & strSQL
    'DBEngine.Workspaces(0).Rollback
    Resume exitRoutine
  End Function

(交易作了评论,因为他们造成的问题,我没有时间去解决)

你可以替代这些行你的:

  DoCmd.RunSQL "DELETE FROM tempExtract"
  DoCmd.RunSQL "INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" & ") FROM tempExtractID"

...这个:

  SQLRun "DELETE FROM tempExtract"
  SQLRun "INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" & ") FROM tempExtractID"

你也可以这样做:

  Debug.Print SQLRun("DELETE FROM tempExtract") & " records deleted."
  Debug.Print SQLRun("INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" _
    & ") FROM tempExtractID") & " records inserted."

由于功能返回。RecordsAffected每个执行时,可以打印的"即时"窗口,或者你可以指定将返回值变量,或通过现有的变量,通过它的工作与可变因此:

  Dim lngRecordsAffected As Long
  ...
  Call SQLRun("DELETE FROM tempExtract", , lngRecordsAffected)
  Debug.Print lngRecordsAffected & " records deleted."
  Call SQLRun("INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" _
    & ") FROM tempExtractID", , lngRecordsAffected)
  Debug.Print lngRecordsAffected & " records inserted."

这一点是,如果有错误,在执行声明,整个事情将会失败(及弹出一个错误消息-你可能想要改变它,所以,如果有一个错误,它返回-1或一些这样的,而不是出现一个MsgBox).

我用这个功能的最经常通过在一个预先缓存的数据库可变的,所以我不想把它清理干净之后。如果你使用一个不同的数据库比其他CurrentDB(),你真的想要确定的任何数据库的可变指着你的外部数据库关闭和设置到什么。没有,锁定保留在顶级的数据库对象,并LDB文件仍然开放和积极的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top