问题描述
我有一个 MS Access 应用程序,我正在使用 sql Server Management Studio (SSMS) 将其转换为 sql Server 后端(仍然是 Access FE)。
该应用程序存储人力资源信息,并且有一个功能应该根据雇佣日期和试用期建立试用期到期日。
功能如下:
Private Sub BtnBuildSked_Click()
Const SUB_NAME As String = "BtnBuildSked_Click"
On Error GoTo ErrCond
Dim ThisReport,myresponse,MyStyle As Integer
Dim MYDB As Database
Dim Myrst,PdRec As DAO.Recordset
'Dim Myfrm As Form
Dim PdStr As String
Dim s,strsql As String
Dim t As TTracking
If Me.PaysrID.Value = "ON LEAVE" Then
MsgBox ("Record is marked ON LEAVE. Cannot proceed.")
Exit Sub
End If
'Set Myfrm = Screen.ActiveForm
Set MYDB = CurrentDb
s = "SELECT * FROM tblProbationReports"
Set Myrst = MYDB.OpenRecordset(s,dbOpenDynaset,dbSeeChanges)
MyStyle = vbOKOnly + vbExclamation
If IsNull(Me.PaysrID) Then
MsgBox ("Cannot process for empty Employee ID")
Exit Sub
End If
If (IsNull(Me.ApptDate)) Then
myresponse = MsgBox("Appointment Date field is empty ",vbCritical)
Exit Sub
End If
'----- Check that Probation Term ID is not blank
If (Me.ProbationTermId.Value < 1 Or Me.ProbationTermId.Value > 7 Or IsNull(Me.ProbationTermId)) Then
myresponse = MsgBox("You must select a probationary period to be able to build a schedule",MyStyle)
Exit Sub
End If
'----- Warning that any existing records for this employee will be deleted
myresponse = MsgBox("Warning!! This will delete any current probation schedule records for this Employee and Line No. combination. Do you want to proceed ?",vbYesNo)
Debug.Print myresponse
If myresponse = 7 Then
Exit Sub
End If
'------ Delete prevIoUs Probationary records for employee ; Keys = SS# and Line#
strsql = "DELETE tblProbationReports.* " & _
"FROM tblProbationReports " & _
"WHERE tblProbationReports.LineNo= '" & Me.LineNo & "' and tblProbationReports.PaysrID = '" & Me.PaysrID & "' "
DoCmd.SetWarnings False
DoCmd.Runsql (strsql)
DoCmd.SetWarnings True
'----- Point to the approp recoird in Probation Data
PdStr = "SELECT * " & _
"FROM [tblProbationData] " & _
"WHERE [ProbationTermID] = " & Me.ProbationTermId.Value
'Set PdRec = MYDB.OpenRecordset("SELECT * FROM [tblProbationData] WHERE [ProbationTermID] = & me.ProbationTermID.Value & ")
Set PdRec = MYDB.OpenRecordset(PdStr)
If Not PdRec.EOF Then
For ThisReport = 1 To PdRec("ProbationReports")
'With Myrst
Myrst.AddNew
Myrst.Fields("LineNumber") = Me.LineNo
Myrst.Fields("SSNO") = Me.SSNo
Myrst.Fields("PaysrID") = Me.PaysrID
Myrst.Fields("ReportNo") = ThisReport
Select Case ThisReport
Case 1
Myrst.Fields("FromDate") = Me.ApptDate
Myrst.Fields("ToDate") = Me.ApptDate + (PdRec("Report1weeks") * 7) '-1
Myrst.Fields("DueDate") = Me.ApptDate + (PdRec("Report1weeks") * 7) - 1 - 14
Myrst.Fields("SentDate") = Me.ApptDate + (PdRec("Report1weeks") * 7) - 1 - 28
Case 2
Myrst.Fields("FromDate") = Me.ApptDate + (PdRec("Report1weeks") * 7)
Myrst.Fields("ToDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks")) * 7) '- 1
Myrst.Fields("DueDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks")) * 7) - 1 - 14
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks")) * 7) - 1 - 28
Case 3
Myrst.Fields("FromDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks")) * 7)
Myrst.Fields("ToDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks")) * 7) '- 1
Myrst.Fields("DueDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks")) * 7) - 1 - 14
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks")) * 7) - 1 - 28
Case 4
Myrst.Fields("FromDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks")) * 7)
Myrst.Fields("ToDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks")) * 7) '- 1
Myrst.Fields("DueDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks")) * 7) - 1 - 14
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks")) * 7) - 1 - 28
Case 5
Myrst.Fields("FromDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks")) * 7)
Myrst.Fields("ToDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks")) * 7) '- 1
Myrst.Fields("DueDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks")) * 7) - 1 - 14
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks")) * 7) - 1 - 28
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks")) * 7) - 1 - 42
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks")) * 7) - 1 - 56
Case 6
Myrst.Fields("FromDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks")) * 7)
Myrst.Fields("ToDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) '- 1
Myrst.Fields("DueDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) - 1 - 14
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) - 1 - 28
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) - 1 - 42
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) - 1 - 56
Case 7
Myrst.Fields("FromDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks")) * 7)
Myrst.Fields("ToDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) '- 1
Myrst.Fields("DueDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) - 1 - 14
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) - 1 - 28
Myrst.Fields("SentDate") = Me.ApptDate + ((PdRec("Report1weeks") + PdRec("Report2weeks") + PdRec("Report3weeks") + PdRec("Report4weeks") + PdRec("Report5weeks") + PdRec("Report6weeks")) * 7) - 1 - 56
End Select
Myrst.Fields("Received") = False
Myrst.Update
'End With
Next ThisReport
End If
'set up tracking manually
t.Comment = "Build New Schedule"
t.FieldName = "LineNo"
t.ItemID = Me.LineNo
t.NewValue = "New Schedule Built"
t.OldValue = ""
t.TableName = "tblProbationReports"
t.TrackingType = TR_TYPE_NEW
SaveTrans t
Myrst.Close
PdRec.Close
'Myfrm.SetFocus
Me.Recalc
MsgBox ("Probation dates created")
Exit Sub
ErrCond:
EventLogging AppSession.UserName,MSG_TYPE_ERROR,Err.Number,Err.Description,MOD_NAME & "." & SUB_NAME,AppSession.AppSilent
End Sub
前几个块是检查正确格式的员工 ID 和活动状态。
然后应用程序应该根据试用期(各种案例陈述)和就业日期建立新的时间表。
但是当代码下降到 .Update 时,它会失败并显示“ODBC 调用失败”。
以下是迄今为止的注意事项和故障排除的概要:
-
与 BE 的连接没有问题。我能够毫无问题地创建、更新和删除员工记录。通过 Access FE 打开时,我可以看到表中的数据。我可以运行报告。
-
“试用报告”表没有主键,我需要添加主键才能在 SSMS 中创建审计触发器(我知道表应该有主键,但我不是原始开发人员)。
-
我在“Probation Reports”表中创建了“RecordID”主键并将其设为“Identity”,以便自动增加唯一标识符。
-
在 SSMS 中使 RecordID“Identity”按顺序递增时,Access 在 Recordset.Open of“Probation Reports”上出错......“具有身份的表需要 dbSeeChanges on Recordset”
-
尝试 Recordset.Open ("name",dbSeeChanges) 仍然出错,“具有标识的表在打开 Recordset 时需要 dbSeeChanges”。 Access 未读取“dbSeeChanges”选项值
-
我已经尝试了 Open "Type" docs.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/database-openrecordset-method-dao(甚至那些没有意义的)。这是 .Update 因“ODBC 连接失败”而中断的地方
我不知道该去哪里...
UPDATE - 根据评论中的反馈,我尝试直接向表中添加值并收到以下错误(截图)
解决方法
定义记录集(在访问中和使用 sql server 时)。
Dim rst AS DAO.Reocdset
你可以省略 DAO。但你不应该。
对于任何链接的 sql server 表?
该表必须定义一个 PK。如果您在设计模式下打开访问链接表(忽略仅就绪警告),则检查两件事:
首先,如果不是 200% 确定您看到定义的 PK,则为 100%。
第二:在此期间,检查日期时间列的数据类型。如果它们是代替日期时间的文本,您必须立即停止并解决该问题。
如果日期时间列被视为文本,那么您有两种选择:
将 sql server 列数据类型从 datetime2(新的默认值)更改为 datetime,然后重新链接表。现在按照 aobve 再次检查设计中的表 - 检查列数据类型。
您还可以考虑安装较新的 ODBC Native 11 或更高版本的驱动程序 - 它们支持 datetime2 - 内置的传统 ODBC 驱动程序不支持!!! - 它将这些列视为文本。但是,缺点是您必须在每个工作站上安装本机 11(或更高版本的驱动程序 - 现在版本 17)。因此,这取决于您哪个更省事(在每个工作站上安装本机驱动程序,或者将 sql server 列时间翻转回 datetime 而不是使用 datetime2)。
下一期。
访问打开表:
Dim rst AS DAO.RecordSet
set rst = currentdb.OpenReocrdSet(" table name or sql goes here")
Access 打开一个链接表到 sql server。
Dim rst As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT * FROM tblInvoice where InvoiceNum = " & InvoiceNumber
Set rst = CurrentDb.OpenRecordset(strSQL,dbOpenDynaset,dbSeeChanges)
所以,你总是包含 dbOpenDynaset、dbSeeChanges
如果你刚刚做了一个访问sql server的迁移?然后我在一个相对较大的应用程序中找到了 EVEN,使用全局搜索和替换,(在我的粘贴缓冲区中使用,dbSeeChanges?它不应该花更多的时间说大约 5 分钟的时间。所以去更改现在运行的所有 VBA reocrdset 代码在链接表上。
因此,您必须像这样在打开的记录集上添加/拥有/包含两个额外的参数:
Set rst = CurrentDb.OpenRecordset(strSQL,dbSeeChanges)
还有几个是你的
在 sql server 表设计中,所有位字段都必须为 false 设置一个默认值(比如 0)。
如果您收到可怕的“其他人已更新”记录错误?然后您需要向该表添加一个时间戳列(不要将时间戳与日期时间混淆 - 时间戳就是我们所说的行版本列 - 与日期时间为零,并且您永远不会触摸或编辑或更改那个行版本列。