我正在努力將我們的多訪問 (2016) 檔案/資料庫轉換為一個帶有導航的統一訪問檔案,并將資料托管在 SQL 服務器 (2014) 上。目前,我們有一個包含以下代碼的按鈕,每次我到達 s.update 行時,都會收到錯誤訊息“不允許新事務,因為會話中有其他執行緒正在運行”。
我已經在谷歌上搜索了一兩天,似乎無法擺脫它。我讀到啟用 MARS 會有所幫助,因為我打開了 2 個記錄集,但這沒有幫助。我確實在該表連接字串上看到了“MARS_Connection=Yes”。我還讀到 for 回圈可能會導致問題,但實際上沒有 s.update 行在 for 回圈中。我很難找到與 Access 相關的這個問題
我正在重新學習 VBA,我沒有撰寫這個應用程式,我愿意接受建議。
Private Sub cmdNewWeek_Click()
On Error GoTo ErrorHandler
Dim r As DAO.Recordset, s As DAO.Recordset, f As Field, DifferentDate As Boolean, d As Date
d = Date - (Weekday(Date) - 2)
If IsNull(Me.cboSelAtty) Then
MsgBox "Select an attorney first."
cboSelAtty.SetFocus
Else
If IsNull(Me.employee) Then Me.employee = Me.cboSelAtty
DoCmd.RunCommand acCmdSaveRecord
DifferentDate = False
MsgBox cboSelAtty
Set r = CurrentDb.OpenRecordset("Select top 1 * From kt_workload Where employee=" & CSql(cboSelAtty) & " Order By week Desc", dbOpenSnapshot)
Set s = CurrentDb.OpenRecordset("kt_workload", dbOpenDynaset, dbSeeChanges)
If r.EOF Then
s.AddNew
s("employee") = cboSelAtty
s("week") = d
s.Update
s.Close
r.Close
Me.Requery
Exit Sub
ElseIf r("week") >= d Then
If MsgBox("A record for this week already exists. Do you want to enter one for a different week?", vbCritical vbYesNo) = vbNo Then
r.Close
Exit Sub
Else
DifferentDate = True
End If
End If
s.AddNew
For Each f In r.Fields
If f.Name <> "week" Then s(f.Name) = r(f.Name)
Next
s("week") = IIf(DifferentDate, r("week") 7, d)
s.Update
s.Close
r.Close
Me.Requery
End If
ErrorHandler:
'Start ODBC error Catch
Dim i As Integer
Dim st As String
For i = 0 To Errors.Count - 1
st = st & Errors(i).Description & vbCrLf
Next i
MsgBox st, vbCritical
'End ODBC error Catch
End Sub
示例資料(無論出于何種原因,我都無法正確格式化表格): 示例資料
最后,我們所做的只是復制最近的記錄,因為“測驗”欄位通常每周都相似。
編輯:我將功能縮減到以下。正如預期的那樣,我確實從我的“r”記錄中獲得了 1 條記錄。它可以很好地應用于“s”新記錄。
但是 s.update 會引發相同的錯誤。此外,如果我運行它并通過 SSMS 運行 SQL 查詢,該查詢將掛起,直到訪問表單拋出錯誤(約 60 秒),所以我不確定我假設的 SQL 連接端哪里出錯了。
精簡代碼:
Private Sub cmdNewWeek_Click()
On Error GoTo ErrorHandler
Dim r As DAO.Recordset, s As DAO.Recordset, DifferentDate As Boolean, d As Date
d = Date - (Weekday(Date) - 2)
Set r = CurrentDb.OpenRecordset("Select top 1 * From kt_workload Where employee=" & CSql("jcraig") & " Order By week Desc", dbOpenSnapshot)
Set s = CurrentDb.OpenRecordset("kt_workload", dbOpenDynaset, dbSeeChanges)
s.AddNew
For Each f In r.Fields
If f.Name <> "week" Then s(f.Name) = r(f.Name)
Debug.Print s(f.Name)
Next
s("week") = d
s.Update
s.Close
r.Close
ErrorHandler:
'Start ODBC error Catch
Dim i As Integer
Dim st As String
For i = 0 To Errors.Count - 1
st = st & Errors(i).Description & vbCrLf
Next i
MsgBox st, vbCritical
'End ODBC error Catch
End Sub
uj5u.com熱心網友回復:
最后,我認為這是訪問 2016、SQL Server 2014 和 ODBC 17 驅動程式所特有的一些連接問題。我沒有使用雙記錄源,而是打開讀取的記錄源并僅使用這些值插入新記錄,然后我將只選擇這條新記錄。它至少現在有效。
sql = "INSERT INTO kt_workload (employee, week, availweek, availMonth, availQtr, activeWeek, activeMonth, activeQtr) VALUES (" & _
CSql(r("employee")) & ",'" & _
r("week") & "'," & _
CSql(r("availweek")) & "," & _
CSql(r("availMonth")) & "," & _
CSql(r("availQtr")) & "," & _
CSql(r("activeWeek")) & "," & _
CSql(r("activeMonth")) & "," & _
CSql(r("activeQtr")) & _
");"
Debug.Print sql
CurrentDb.Execute sql
uj5u.com熱心網友回復:
每當您需要一個僅從中讀取資料的記錄集時,您應該將其作為快照打開。
在您的情況下,您只想讀取第一條記錄,因此您還應該使用TOP 1
.
如果您有一位名叫 的律師O'Brien
,您的密碼就會失效。使用SQL 連接變數時使用 Gustav 的CSql()
函式。它處理所有字串并防止 SQL 注入。
總之:
strSql = "Select TOP 1 * From table1 Where employee=" & CSql(cboSelAtty) & " Order By week Desc"
Set r = CurrentDb.OpenRecordset(strSql, dbOpenSnapshot)
這樣你就不會有沖突的交易。
請注意,您的 ODBC 錯誤處理回圈應該進入On Error Goto xxx
處理程式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/359964.html