Running asynchronous query in MS Access
I'm trying to run some heavy queries asynchronously, but can't figure out how to do it for an .mdb file.
This is what I have so far:
Dim wrksp As Workspace, qdf As QueryDef, rst As Recordset
Dim cnn As Connection, strCon开发者_如何学Cnect As String
Set wrksp = CreateWorkspace("ODBCDirect", "Admin", "", dbUseODBC)
strConnect = "ODBC;Driver={Microsoft Access Driver (*.mdb)};Database=F:\Databank\webshop_ingrid.mde;Uid=;Pwd=;"
Set cnn = wrksp.OpenConnection("", dbDriverNoPrompt, False, _
strConnect)
Dim rs As Recordset
Dim strQuery As String
strQuery = "UPDATE ((((((tblSkuActueel LEFT JOIN qryStockSkuMetLaatsteDatumSubQuery ON tblSkuActueel.sku = qryStockSkuMetLaatsteDatumSubQuery.sku) LEFT JOIN " & _
"qrySkuCapNieuwste ON tblSkuActueel.sku = qrySkuCapNieuwste.sku) LEFT JOIN qrySkuListNieuwste ON tblSkuActueel.sku = qrySkuListNieuwste.sku) LEFT JOIN " & _
"qrySkuPPDNieuwste ON tblSkuActueel.sku = qrySkuPPDNieuwste.sku) INNER JOIN qrySkuApexNieuwsteMetBtw ON tblSkuActueel.sku = qrySkuApexNieuwsteMetBtw.sku) " & _
"LEFT JOIN qrySkuSpecialNieuwsteDS ON tblSkuActueel.sku = qrySkuSpecialNieuwsteDS.sku) LEFT JOIN qrySkuSpecialNieuwsteNB ON tblSkuActueel.sku = " & _
"qrySkuSpecialNieuwsteNB.sku SET tblSkuActueel.stock = qryStockSkuMetLaatsteDatumSubQuery.aantal, tblSkuActueel.apex = qrySkuApexNieuwsteMetBtw.apex, " & _
"tblSkuActueel.cap = qrySkuCapNieuwste.cap, tblSkuActueel.listprice = qrySkuListNieuwste.listprice, tblSkuActueel.ppd = qrySkuPPDNieuwste.ppd, " & _
"tblSkuActueel.procent = qrySkuApexNieuwsteMetBtw.procent, tblSkuActueel.apin = Round(qrySkuApexNieuwsteMetBtw.apex*qrySkuApexNieuwsteMetBtw.procent,2), " & _
"tblSkuActueel.BtwId = qrySkuApexNieuwsteMetBtw.btwid, tblSkuActueel.specialpricenb = [qryskuspecialnieuwstenb].[specialprice], " & _
"tblSkuActueel.specialpriceds = [qryskuspecialnieuwsteds].[specialprice]"
Set rs = Object.OpenRecordset(strQuery, dbOpenDynaset, dbSeeChanges + dbRunAsync)
That won't even open a connection as the connection string seems to be wrong.
Your first 5 (non-blank) lines are doing nothing in your example. Those lines are attempting to open a connection, but your later code that is dealing with the update query is not using that connection.
You should be aware that the Round() function that you are using may not return what you expect. The Round() function in VBA uses "Bankers Rounding" or "round half to even" logic. Both Round(15.665,2) and Round(15.675,2) will return 15.67.
Your final line is attempting to open a recordset from your update statement. The update statement does not return records, so there is no recordset to return. If it were to return a recordset, you would want to use something like "CurrentDB.OpenRecordset" rather than "Object.OpenRecordset".
Regarding asynchronous running of this query, you may not be able to get what you want. MS Access is going to process the query on the local computer. I do not know of a way to run a query asynchronously if it is using a JET (MS Access) database. I suspect that even if there is a command to run the query asynchronously through your VBA code, it would still be running in the context of your application and bog it down.
If you are trying to let your application be responsive while the query is running I would suggest moving the update to a separate process, for example a VBScript file.
Save the following code in a file with a name like UpdateActueel.vbs
strQuery = "UPDATE ((((((tblSkuActueel LEFT JOIN qryStockSkuMetLaatsteDatumSubQuery ON tblSkuActueel.sku = qryStockSkuMetLaatsteDatumSubQuery.sku) LEFT JOIN " & _
"qrySkuCapNieuwste ON tblSkuActueel.sku = qrySkuCapNieuwste.sku) LEFT JOIN qrySkuListNieuwste ON tblSkuActueel.sku = qrySkuListNieuwste.sku) LEFT JOIN " & _
"qrySkuPPDNieuwste ON tblSkuActueel.sku = qrySkuPPDNieuwste.sku) INNER JOIN qrySkuApexNieuwsteMetBtw ON tblSkuActueel.sku = qrySkuApexNieuwsteMetBtw.sku) " & _
"LEFT JOIN qrySkuSpecialNieuwsteDS ON tblSkuActueel.sku = qrySkuSpecialNieuwsteDS.sku) LEFT JOIN qrySkuSpecialNieuwsteNB ON tblSkuActueel.sku = " & _
"qrySkuSpecialNieuwsteNB.sku SET tblSkuActueel.stock = qryStockSkuMetLaatsteDatumSubQuery.aantal, tblSkuActueel.apex = qrySkuApexNieuwsteMetBtw.apex, " & _
"tblSkuActueel.cap = qrySkuCapNieuwste.cap, tblSkuActueel.listprice = qrySkuListNieuwste.listprice, tblSkuActueel.ppd = qrySkuPPDNieuwste.ppd, " & _
"tblSkuActueel.procent = qrySkuApexNieuwsteMetBtw.procent, tblSkuActueel.apin = Round(qrySkuApexNieuwsteMetBtw.apex*qrySkuApexNieuwsteMetBtw.procent,2), " & _
"tblSkuActueel.BtwId = qrySkuApexNieuwsteMetBtw.btwid, tblSkuActueel.specialpricenb = [qryskuspecialnieuwstenb].[specialprice], " & _
"tblSkuActueel.specialpriceds = [qryskuspecialnieuwsteds].[specialprice]"
Set DB = GetObject("F:\Databank\webshop_ingrid.mde")
DB.Execute strQuery
And in your VBA code, use the following line to run the script.
Shell "wscript ""C:\<Path to file>\UpdateActueel.vbs"""
I can speak about executing this things against a JET data source however I have used this against SQL server so it should work. The trick is to use ADO and fire the execute statement with the option adAsyncExecute. I don’t have the exact code to hand but here is a rough version off the top of my head
Dim DbCon as ADODB.Connection
Dim dbCmd as ADODB.Command
DbCon.ConnectionString=”Your connection string”
With dbCmd
.commandtype= adCmdText.commandtext=”Your long SQL update statement”
.ActiveConnection=dbcon.Execute , , adAsyncExecute
End With
精彩评论