0

我越來越想刪除一個表時出現以下錯誤:DoCmd.DeleteObject,它可作用 - 「無法鎖定表,因爲它是已在使用」

Run-time error '3211'

The database engine could not lock table 'RuleViolations1516' because it is already in use by another person or process.

這裏是有問題的過程中,有評論示出了線引發錯誤:

Public Sub ImportRuleViolations() 

    DoCmd.Close acForm, "frmImportRuleViolations" 

    If _ 
     TableExists("RuleViolations1516") = True _ 
    Then 

     Debug.Print "Table RuleViolations1516 already exists" 

     DoCmd.DeleteObject acTable, "RuleViolations1516" ' <-- EXECUTION STOPS HERE 
     Debug.Print "...old table deleted..." 

     DoCmd.TransferSpreadsheet acTable, _ 
        10, _ 
        "RuleViolations1516", _ 
        Forms!frmImportRuleViolations.txtRuleViolationsPath & Forms!frmImportRuleViolations.txtRuleViolationFile, _ 
        -1 
     Debug.Print "...new data imported." 

    ElseIf _ 
     TableExists("RuleViolations1516") = False _ 
    Then 

     Debug.Print "Table RuleViolations1516 does not already exist" 

     DoCmd.TransferSpreadsheet acTable, _ 
          10, _ 
          "RuleViolations1516", _ 
          Forms!frmImportRuleViolations.txtRuleViolationsPath & Forms!frmImportRuleViolations.txtRuleViolationFile, _ 
          -1 
     Debug.Print "...new data imported." 

    End If 

    Dim db As DAO.Database 
    Dim tDef As TableDef, fld As DAO.Field 

    Set db = CurrentDb 

    db.TableDefs.Refresh 

    ' LRN 

     Set tDef = db.TableDefs("RuleViolations1516") 
     Set fld = tDef.CreateField("newLRN", dbText, 20) 
     fld.OrdinalPosition = 2 
     tDef.Fields.Append fld 

     db.Execute _ 
      "UPDATE RuleViolations1516 Set newLRN=[Learner Ref]", dbFailOnError 

     ' delete old field 
     tDef.Fields.Delete "Learner Ref" 
     tDef.Fields.Refresh 

     ' rename new field 
     tDef.Fields("newLRN").name = "LRN" 
     tDef.Fields.Refresh 

     Set fld = Nothing 
     Set tDef = Nothing 

    ' AimRef 

     Set tDef = db.TableDefs("RuleViolations1516") 
     Set fld = tDef.CreateField("newAimRef", dbText, 20) 
     fld.OrdinalPosition = 7 
     tDef.Fields.Append fld 

     db.Execute _ 
      "UPDATE RuleViolations1516 Set newAimRef=[Aim Reference Number]", dbFailOnError 

     ' delete old field 
     tDef.Fields.Delete "Aim Reference Number" 
     tDef.Fields.Refresh 

     ' rename new field 
     tDef.Fields("newAimRef").name = "AimRef" 
     tDef.Fields.Refresh 

     Set fld = Nothing 
     Set tDef = Nothing 

    Set db = Nothing 

    DoCmd.OpenForm "frmImportRuleViolations" 

End Sub 

有問題的子也使得參考另一功能:

Public Function TableExists(name As String) As Boolean 

    TableExists = DCount("*", "MSysObjects", "Name = '" & name & "' AND Type = 1") 

End Function 

上面的子和函數在它們自己的獨立模塊(不綁定到表單模塊)上運行。

RuleViolations1516沒有打開時,我運行子。表單frmImportRuleViolations在某些子表單後面的某些查詢中使用了RuleViolations1516表,但正如您從子表單中可以看到的那樣,我已經在第一行中關閉了這個表單。

任何指針,將不勝感激。

更新:

frmImportRuleViolations上有2子窗體...刪除它們(暫時)停止發行。我需要窗體上的子窗體,但是我怎樣才能解決這個問題?

+0

如果在if語句之前執行'DoCmd.DeleteObject',會發生什麼?它在那裏也失敗了嗎? – BIBD

+0

僅作爲測試,如果您刪除或禁用「DoCmd.Close acForm」,「frmImportRuleViolations」,然後在* frmImportRuleViolations *關閉時運行* ImportRuleViolations *,您是否仍然得到相同的錯誤? – HansUp

+0

@BIBD我評論了除了'DoCmd.DeleteObject'這行之外的所有代碼。發生相同的錯誤。 –

回答

1

據我瞭解您的更新問題,你有一個形式,稱爲frmImportRuleViolations,並有一個子表格,我會打電話frmImportRuleViolationsSubform1

frmImportRuleViolationsSubform1引用其上某處的RuleViolations1516表。

我假設你也觸發這個從按鈕或其他控制01​​重新加載。如果是這樣,那麼這是錯誤的原因。到達結束事件時,訪問可能沒有放棄對RuleViolations1516的每一個引用。

這個和一個窗體關閉和重新打開本身可以得到一種毛茸茸的。

一個相當容易的事情就是在frmImportRuleViolationsSubform1打開之前刪除並加載表。作爲用戶(和開發人員),這正是我所期望的 - 我打開表單並且它是最新的。最糟糕的情況是關閉表格並重新打開它,這讓我更新。

失敗(它必須在窗體關閉後重新加載);那麼我會將其作爲一個模式窗口打開frmImportRuleViolations,然後在調用frmImportRuleViolations之後重新加載表代碼,因爲它將等待,直到控制返回到調用窗口。

您也可以將數據加載到臨時登臺表中,然後刪除RuleViolations1516的內容並從登臺表中重新填充它。這可能是我會採取的路線,因爲它會消除關閉和打開frmImportRuleViolations表單。你只需要告訴表格刷新子表格(我將爲讀者留下一個練習)。


從,一對夫婦的風格筆記

旁白:

'' this 
If _ 
    TableExists("RuleViolations1516") = True _ 
Then 

'' could be equally written as 
If TableExists("RuleViolations1516") Then 
'' the "= True" is implied and not required 

而且

'' this 
ElseIf _ 
    TableExists("RuleViolations1516") = False _ 
Then 

'' is redundant to the previous if. A simple else would do, since we 
'' know if the last time it ran, it wasn't true, it must be false 

而且DoCmd塊看起來像它在如果兩個同樣的事情,否則,這樣我傾向於像這樣提取它:

If TableExists("RuleViolations1516") then 
    Debug.Print "Table RuleViolations1516 already exists" 
    DoCmd.DeleteObject acTable, "RuleViolations1516" 
    Debug.Print "...old table deleted..." 
else 
    Debug.Print "Table RuleViolations1516 does not already exist" 
end if 

DoCmd.TransferSpreadsheet acTable, _ 
    10, _ 
    "RuleViolations1516", _ 
    Forms!frmImportRuleViolations.txtRuleViolationsPath & _ 
     Forms!frmImportRuleViolations.txtRuleViolationFile, _ 
    -1 
Debug.Print "...new data imported." 

這樣,當你回來改變文件名(或其他)時,你只是在一個地方改變它,並遵循DRY原則 - 「幹 - 不要重複你的自我」。

I like the use of underscores so that what you have coded does not run off the edge of the screen like some extract from war and peace. It makes it much more readable. 

你所做的事是錯。這不是大多數開發人員會做的。儘管我們爲計算機編寫代碼以實現我們想要的功能,但我們還希望下一位開發人員在5年後觸摸您的代碼,輕鬆瞭解您正在執行的操作。代碼總是會持續比您想象的更長的時間:^)

祝您好運!

+0

(1/3)感謝所有這些指針 - 都非常有用。表單的關閉/打開不是預期設計的一部分,它只是我試圖讓Access去放開表格,然後把它留在我的問題中,以顯示錶格仍然很奇怪當使用它的所有內容不再顯示在屏幕上時,視爲已打開數據刷新來自調用'ImportRuleViolations()'的窗體上的命令按鈕。 –

+0

(2/3)不幸的是,我不能完全自動化刷新,因爲它依賴於導入電子表格的文件名可能會有所不同(所以用戶必須使用文件對話框手動選擇一個.xlsx文件:http:// i。 imgur.com/wMRLsxT.jpg)。我提出了簡單地分割表單的解決方法,以便有一個單獨的導入表單處理獲取新數據,然後在完成時使用子表單打開表單。 –

+0

(3/3)感謝您提供這些風格的提示。我經常以一種非常明確的方式編寫我的初始代碼,直到我很高興它一切正常......因此,我傾向於用隱含的'= True'和'= False'部分編寫'IF'語句這對我來說最容易掃描)。然後,當我有更多的時間時,我通常會把事情縮小。對於'TransferSpreadsheet'的多餘使用你是完全正確的;有點馬虎,謝謝你的發現。儘管我用了一種不同的方法來解決這個問題,但我可以看到你所提出的建議是合理的,所以我已經標記爲答案。謝謝。 –

相關問題