MS Access 2010:VBA代码多次运行

时间:2017-12-16 13:23:35

标签: sql-server vba ms-access stored-procedures

我有一个以前从未遇到的问题,我看不出任何错误。

在表单上是一个按钮 cmdCreateOrder ,它对SQL Server运行传递查询并执行存储过程,此查询返回一个值到Access。

按钮 cmdCreateOrder

Private Sub cmdCreateOrder_Click()
Dim strsql As String
Dim intNumberProducts As Integer

If MsgBox("Want to create an order?" & vbCrLf & vbCrLf _
        & "Click 'Yes' to create", vbQuestion + vbYesNo, "Question") = vbNo Then
        Exit Sub
End If

    strsql = "exec dbo.spCreateOrder 'CreateOrdersKd', 1, " & Me.OfferID & ", " & Me.KdID & ", " & TempVars!intUser
    Debug.Print strsql
    Call SQL_PT(strsql, "PT_LookupWerte")

    intNumberProducts = DLookup("NumberProducts", "PT_LookupWerte")

    Me.Bestelldatum = Date
end Sub

函数 SQL_PT

Function SQL_PT(ByVal SQL As String, Optional QueryName As String)  
Dim qdf As QueryDef

On Error GoTo ErrHandler

'if no query name then create temp qry
If Len(QueryName) = 0 Then 'temp Abfrage

    Set qdf = CurrentDb.CreateQueryDef("")
    With qdf
        .Connect = TempVars!ConnectionString
        .SQL = SQL
        .ReturnsRecords = False  'Wenn kein QueryName angeliefert wird, dann ergibt .ReturnsRecords = 0 und die Abfrage wird einfach ausgeführt
        .Execute
    End With

Else  'if a qry name provided, then run qry which returns values
    Set qdf = CurrentDb.QueryDefs(QueryName)
    qdf.SQL = SQL
End If

qdf.Close
Set qdf = Nothing

ExitHere:
    Exit Function

ErrHandler:
    Resume ExitHere
End Function

我在这个项目中使用了很多像这样的代码,所有代码都能正常工作。但是,此按钮单击运行EXEC至少3次,并创建3(或更多)订单。

访问VBA调试测试

更奇怪的是,因为我只在立即窗口中获得一行。 当我在PT查询(Debug.Print)中使用exec dbo.spCreateOrder 'CreateOrdersKd', 1, 8, 2001, 1结果(例如PT_LookupWerte)时,它正如预期的那样正常工作,只有 ONE 顺序。

SQL Server存储过程测试

当我在SQL Server上运行存储过程时:exec dbo.spCreateOrder 'CreateOrdersKd', 1, 8, 2001, 1它只创建一个订单并且它正确运行。

仅在单击Access中的按钮时才会多次运行。

我压缩并修复和反编译数据库。现在我不知道问题是什么。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

使用DAO执行存储过程(就像你的#include<stdio.h> main() { int a[10]; for(i=0;i<=100;i++) { a[i]=i; } } 那样)是一个糟糕的计划。

将存储过程存储在QueryDef中并使用SQL_PT而不是DLookUp.Execute执行它们是一个糟糕的计划。

一个简单的解决方法是将.OpenRecordset替换为intNumberProducts = DLookup("NumberProducts", "PT_LookupWerte")

更好的解决方法是将存储过程代码移动到ADO,并使用命令对象和参数来执行存储过程。