优化迭代两个不同数据表的 VBA 过程
Optimising a VBA procedure that iterates over two different tables of data
我有两个 sql tables
pricetbl
和 paymenttbl
。由于商品价格每天都在变化,我需要用正确时间的价格更新 paymenttbl
。如果在商品价格date-effective
之后成交,则paymenttbl
的成交价格与最新商品价格相同(只要生效日期小于成交日期) .我不仅想在这里限制自己,我还想遍历整个 table 以更改数据,以便每笔交易都有正确的价格。
PriceTbl
pID| Price| Date Effective
---------------------------
1 | 10 | 01-12-2014
2 | 20 | 01-02-2015
3 | 20 | 02-12-2014
2 | 40 | 20-03-2015
1 | 50 | 02-03-2015
4 | 34 | 20-02-2015
1 | 40 | 25-05-2015
PaymentTbl
payID | pID | transDate | Price
--------------------------------
1 | 1 | 02-12-2014| 05
2 | 1 | 04-03-2015| 10
3 | 2 | 21-04-2015| 35
4 | 3 | 03-12-2014| 15
预期 table paymenttbl
在 运行 查询
之后
payID | pID | transDate | Price
--------------------------------
1 | 1 | 02-12-2014| 10
2 | 1 | 04-03-2015| 50
3 | 2 | 21-04-2015| 40
4 | 3 | 03-12-2014| 20
检索和更新数据最快最简单的方法是什么?我目前的方式最多需要 30 分钟来更新 table,因为我遍历 paymenttbl 然后我遍历 pricetbl 并将其与 paymenttbl 中的每个项目进行比较。
我的代码:
Function updateWorktoDateEff()
Dim rt As DAO.Recordset
Dim wt As DAO.Recordset
Dim db As DAO.Database
Dim sqlrt As String
Dim sqlwt As String
Set db = CurrentDb
sqlrt = "select * from pricetbl where (dailyrate IS NOT NULL) and (dateeffective is not null) order by id, dailyrate"
sqlwt = "select * from paymenttbl where (id > 0) order by id, date"
Set rt = db.OpenRecordset(sqlrt)
Set wt = db.OpenRecordset(sqlwt)
Do While Not wt.EOF
Do While Not ratetable.EOF
If rt!ID = wt!ID Then
If rt <= wt!Date Then
wt.Edit
wt!Rate = ratetable!dailyrate
wt.Update
End If
ElseIf ratetable!ID > worktable!ID Then
Exit Do
End If
rt.MoveNext
Loop
rt.MoveFirst
wt.MoveNext 'move to the next worktbl record
Loop
End Function
只是 iterating/retrieving 数据做不到。我还需要能够改变它。
执行此更新的最有效方法不是使用记录集并逐行进行,而是使用 SQL 进行基于集合的更新。我尝试编写一个更新查询来到达那里,但是 MS-Access 对查询不可更新很挑剔,所以我写了两个查询:一个写入临时 table (tempNewPrices) 和一个更新 PaymentTbl使用那个临时 table.
这是创建包含新列 NewPrice 的临时 table 的第一个查询:
SELECT PaymentTbl.payID, PaymentTbl.pID, PaymentTbl.transDate, PaymentTbl.Price,
(
SELECT [Price]
FROM PriceTbl pr
WHERE pr.pID = PaymentTbl.pID
AND pr.[Date Effective] = (
SELECT Max([Date Effective])
FROM PriceTbl pr2
WHERE pr2.pID = pr.pID
AND pr2.[Date Effective]< PaymentTbl.[transDate]
)
) AS NewPrice INTO tempNewPrices
FROM PaymentTbl;
这是更改 PaymentTbl 中价格值的更新查询:
UPDATE tempNewPrices
INNER JOIN PaymentTbl ON tempNewPrices.payID = PaymentTbl.payID
SET PaymentTbl.Price = [NewPrice];
这应该比遍历记录集更有效。
我有两个 sql tables
pricetbl
和 paymenttbl
。由于商品价格每天都在变化,我需要用正确时间的价格更新 paymenttbl
。如果在商品价格date-effective
之后成交,则paymenttbl
的成交价格与最新商品价格相同(只要生效日期小于成交日期) .我不仅想在这里限制自己,我还想遍历整个 table 以更改数据,以便每笔交易都有正确的价格。
PriceTbl
pID| Price| Date Effective
---------------------------
1 | 10 | 01-12-2014
2 | 20 | 01-02-2015
3 | 20 | 02-12-2014
2 | 40 | 20-03-2015
1 | 50 | 02-03-2015
4 | 34 | 20-02-2015
1 | 40 | 25-05-2015
PaymentTbl
payID | pID | transDate | Price
--------------------------------
1 | 1 | 02-12-2014| 05
2 | 1 | 04-03-2015| 10
3 | 2 | 21-04-2015| 35
4 | 3 | 03-12-2014| 15
预期 table paymenttbl
在 运行 查询
payID | pID | transDate | Price
--------------------------------
1 | 1 | 02-12-2014| 10
2 | 1 | 04-03-2015| 50
3 | 2 | 21-04-2015| 40
4 | 3 | 03-12-2014| 20
检索和更新数据最快最简单的方法是什么?我目前的方式最多需要 30 分钟来更新 table,因为我遍历 paymenttbl 然后我遍历 pricetbl 并将其与 paymenttbl 中的每个项目进行比较。
我的代码:
Function updateWorktoDateEff()
Dim rt As DAO.Recordset
Dim wt As DAO.Recordset
Dim db As DAO.Database
Dim sqlrt As String
Dim sqlwt As String
Set db = CurrentDb
sqlrt = "select * from pricetbl where (dailyrate IS NOT NULL) and (dateeffective is not null) order by id, dailyrate"
sqlwt = "select * from paymenttbl where (id > 0) order by id, date"
Set rt = db.OpenRecordset(sqlrt)
Set wt = db.OpenRecordset(sqlwt)
Do While Not wt.EOF
Do While Not ratetable.EOF
If rt!ID = wt!ID Then
If rt <= wt!Date Then
wt.Edit
wt!Rate = ratetable!dailyrate
wt.Update
End If
ElseIf ratetable!ID > worktable!ID Then
Exit Do
End If
rt.MoveNext
Loop
rt.MoveFirst
wt.MoveNext 'move to the next worktbl record
Loop
End Function
只是 iterating/retrieving 数据做不到。我还需要能够改变它。
执行此更新的最有效方法不是使用记录集并逐行进行,而是使用 SQL 进行基于集合的更新。我尝试编写一个更新查询来到达那里,但是 MS-Access 对查询不可更新很挑剔,所以我写了两个查询:一个写入临时 table (tempNewPrices) 和一个更新 PaymentTbl使用那个临时 table.
这是创建包含新列 NewPrice 的临时 table 的第一个查询:
SELECT PaymentTbl.payID, PaymentTbl.pID, PaymentTbl.transDate, PaymentTbl.Price,
(
SELECT [Price]
FROM PriceTbl pr
WHERE pr.pID = PaymentTbl.pID
AND pr.[Date Effective] = (
SELECT Max([Date Effective])
FROM PriceTbl pr2
WHERE pr2.pID = pr.pID
AND pr2.[Date Effective]< PaymentTbl.[transDate]
)
) AS NewPrice INTO tempNewPrices
FROM PaymentTbl;
这是更改 PaymentTbl 中价格值的更新查询:
UPDATE tempNewPrices
INNER JOIN PaymentTbl ON tempNewPrices.payID = PaymentTbl.payID
SET PaymentTbl.Price = [NewPrice];
这应该比遍历记录集更有效。