2011-11-01 156 views
2

我想運行下面的代碼來循環記錄集並在需要時進行更新。訪問VBA - 運行時錯誤'3197'

我有一個Microsoft Access數據庫連接到MySql後端。每當我運行此代碼,我得到了以下錯誤:

The Microsoft Office Access database engine stopped the process because you and another user are attempting to change the same data at the same time.

的代碼如下:

Private Sub test() 

Dim rs As DAO.Recordset, rsCnt As Long, i As Long 
Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET) 
rs.MoveLast 
rsCnt = rs.RecordCount 
rs.MoveFirst 
For i = 1 To rsCnt 

rs.Edit 
rs!MyFieldInTable = "test" 
rs.Update 

Next i 

End Sub 

我是這麼認爲的我把以前的備份Access數據庫可能已損壞,但它做同樣的事情這讓我認爲這是一個MySql問題。

我們在鏈接到不同的MySql表的另一個版本的數據庫上使用相同的一段代碼,它工作正常。

此外,當我打開查詢記錄集是基於我可以編輯查詢中的數據沒有任何問題。

只需添加,在第一個循環中,rs!MyFieldInTable被更新,然後我得到錯誤。

回答

4

它似乎沒有移動到記錄集中的另一條記錄。簡單遞增i不會移至下一條記錄。更傳統的方法是迭代記錄集而不需要其他變量(irsCnt)。

Dim rs as DAO.Recordset 
Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET) 
rs.moveFirst 
Do Until rs.EOF 
    rs.Edit 
    rs!FieldNameHere = "test" 
    rs.Update 
    rs.MoveNext 
Loop 

編輯 有點搜索我的後跨this thread來到這似乎是類似於您的問題。在線程底部,建議通過選擇「高級」選項卡並選擇「返回匹配行」選項來修改MySQL DSN的ODBC設置。該帖子還表示放棄鏈接表,然後將其重新鏈接到您的Access數據庫。 我以前沒有在MySQL中使用Access,所以我不知道這是否可行,所以請謹慎操作!

你也可以嘗試改變你的記錄使用dbOptimistic標誌記錄鎖定選項,看看是否有幫助可言:

set rs = CurrentDB.OpenRecordSet("qryMyQuery", DB_OPEN_DYNASET, dbOptimistic)

+0

很好地完成! + 1 – XIVSolutions

+0

+1就像@XIVSolutions一樣,當我收到消息說已經加載了一個新答案時,我寫了一個類似的答案。 – mwolfe02

+0

另外,糾正我,如果我錯了,但我相信rs.Edit必須進入循環。從DAO幫助文件中:**編輯方法:** *將可更新記錄集對象的**當前記錄**複製到複製緩衝區以供後續編輯。* – mwolfe02

1

我沒有的MySQL在這裏嘗試這種打擊,但它在我看來好像你的代碼沒有在rs.Update方法執行後推進記錄集,所以你試圖在fierst記錄中更新相同的字段。

添加此行的rs.Update後:

rs.MoveNext 

希望有所幫助。

+0

此外,Tim Lentine發佈的代碼是一種更優雅的方式。他在我還在寫我的答案時發帖。 – XIVSolutions

+1

如果人們要冷靜下來,如果他們會用一些推理來支持投票,那就太好了。只是說' – XIVSolutions

1

嘗試從設置爲CurrentDb()的對象變量中調用OpenRecordset,而不是直接從CurrentDb()中調用。

Dim rs as DAO.Recordset 
Dim db As DAO.Database 
Set db = Currentdb 
Set rs = db.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET) 
rs.moveFirst 
Do Until rs.EOF 
    rs.Edit 
    rs!FieldNameHere = "test" 
    rs.Update 
    rs.MoveNext 
Loop 

該建議的原因是我發現在CurrentDb上的操作可以直接引發關於「未設置塊」的錯誤。但是,當使用對象變量時,我不會收到錯誤。 ISTR OpenRecordset就是這樣一個問題。

而且,我的印象是你的方法是實現的相當於麻煩的方式:

UPDATE qryMyQuery SET FieldNameHere = "test"; 

不過,我懷疑的例子是對現實世界的情況,其中記錄的方法是有用的代理。這仍然讓我懷疑在執行UPDATE語句時是否會看到相同或不同的錯誤。

如果您仍然遇到此問題,可能有助於向我們展示qryMyQuery的SQL視圖。

2

兩件事你可以嘗試。首先,嘗試打開記錄時添加dbSeeChanges選項:

Dim rs as DAO.Recordset, db As DAO.Database 
Set db = Currentdb 
Set rs = db.OpenRecordset("qryMyQuery", dbOpenDynaset, dbSeeChanges) 
Do Until rs.EOF 
    rs.Edit 
    rs!FieldNameHere = "test" 
    rs.Update 
    rs.MoveNext 
Loop 

另一種選擇,如@HansUp建議,是使用SQL更新語句,而不是動態的記錄集。關鍵是打開記錄集作爲快照,以便您對記錄所做的更改不會影響記錄集本身。

Dim rs as DAO.Recordset, db As DAO.Database 
Set db = Currentdb 
Set rs = db.OpenRecordset("qryBatchPayments", dbOpenSnapshot) 
Do Until rs.EOF 
    db.Execute "UPDATE Payments " & _ 
       "SET DCReference='test' " & _ 
       "WHERE PaymentID=" & !PaymentID, dbFailOnError 
    rs.MoveNext 
Loop 
0

我發現,如果有人試圖保存與MySql記錄中已存在的數據相同的數據,Access將顯示此類錯誤。我嘗試了一些來自這個主題的建議,但沒有幫助。

這個簡單的解決方案是通過使用手動時間戳保存稍微不同的數據。這裏是一個起伏排序字段,並將它設置爲10,20,30的例子...

i = 10 
    timeStamp = Now() 
    Do Until Employee.EOF 
     Employee.Edit 
     Employee!SortOrderDefault = i 
     Employee!LastUpdated = timeStamp 
     Employee.Update 
     i = i + 10 
     Employee.MoveNext 
    Loop 

我試過自動時間戳在MySQL表,但沒能幫助新記錄數據時,和舊的一樣。

+0

我也經歷過相同的。在這個MySQL錯誤報告中提到:http://bugs.mysql.com/bug.php?id=46406 這似乎是由Access的形式更新查詢的方式造成的。它可以像你建議的客戶端或服務器端使用'timestamp'列來解決。 – AronVanAmmers

0

我的一點有用的提示是,在將SQL錶鏈接到Microsoft Access時要使用的數據類型非常非常非常糟糕,因爲只有SQL Server能夠理解這個位是什麼,Microsoft Access很難解釋這個位是什麼。將任何位數據類型更改爲int(整數),並重新鏈接應清除事務的表。另外,請確保您的布爾值在您的VBA代碼中始終包含1或0(不是yes/no或true/flase),否則您的更新將無法連接到SQL表格,因爲Microsoft Access會嘗試使用True/False或是/否,SQL不會那樣。

0

我也有同樣的問題;我解決了他們使用dao.recordset添加這些代碼:

**rst.lockedits = true** 
rst.edit 
rst.fields(...).value = 1/rst!... = 1 
rst.update 
**rst.lockedits = false** 

這似乎是解決剛開業數據之間的衝突(如表格),並與代碼更新它們。

對不起我的英語不好......我讀了很多,但我從來沒有學過它!我只是意大利人。

+0

如果您已將代碼更改爲SQL語句,請注意。 Form_Unload事件嘗試更新您通過SQL更改的相同數據並引發不可管理的錯誤;這可以消除所有的應用程序。 – AntonioFico