【问题标题】:Using Muiltiple DAO Recordsets in MS Access在 MS Access 中使用多个 DAO 记录集
【发布时间】:2012-09-04 15:44:06
【问题描述】:

第一次发帖,所以尽可能温柔! :)

我正在 Access 中创建一个新数据库来更新我们的电子商务软件(也基于 Access)。

我们收到来自供应商的 3 个提要,所有 CSV 文件的格式略有不同。我已经使用链接表成功导入了提要,并且可以(我认为)根据需要以编程方式刷新文件中的数据。

我创建了一个“CurrentProducts”表,其中包括目前我们网站上的所有产品。

我想依次从 CurrentProducts 表中获取每个产品代码,在每个供应商提要中查找它,根据我们的购买价格计算我们的售价,找出哪个供应商提供最便宜的价格,然后更新 CurrentProducts相应的表格。

我以前经常在 Excel 中将 VBA 用于宏目的,但我从未真正接触过 Access 中的 DAO 记录集,所以我承认我真的不知道自己在做什么!

到目前为止,我已经得到了下面的代码。 CurrentProducts 表中有大约 17,900 条记录,“Ingram”表中有近 51,000 条记录,ScanSource 表中有近 15,000 条记录,Varlink 表中有大约 3,000 条记录。

我已经让代码运行了 5 到 10 分钟,虽然代码看起来确实可以运行,但运行速度非常慢。我只能假设必须有一种比我目前正在做的更快/更简单的方法来访问记录集中的数据。

那么交给你们了,我是应该把这一切都扔掉重新开始,还是可以从这里调整?

谢谢。

Private Sub Command0_Click()

Dim var As DAO.Recordset
Dim ing As DAO.Recordset
Dim scan As DAO.Recordset
Dim curr As DAO.Recordset
Dim filtvar As DAO.Recordset
Dim filtscan As DAO.Recordset
Dim filting As DAO.Recordset
Dim db As Database
Dim varSQL As String, ingSQL As String, scanSQL As String, currSQL As String
Dim prodcode As String
Dim varPrice As Double, ingPrice As Double, scanPrice As Double, currPrice As Double

DoCmd.Hourglass True

Set db = CurrentDb

currSQL = "select ProductCode, Price from CurrentProducts"
varSQL = "select ProductCode, (Price*1.25) as CalcPrice from Varlink"
ingSQL = "select ProductCode, (Price*1.25) as CalcPrice from Ingram"
scanSQL = "select ProductCode, (Price*1.25) as CalcPrice from ScanSource"

Set curr = db.OpenRecordset(currSQL)
Set var = db.OpenRecordset(varSQL)
Set ing = db.OpenRecordset(ingSQL)
Set scan = db.OpenRecordset(scanSQL)

curr.MoveLast 'Needed to get the accurate number of records

'Show the progress bar
SysCmd acSysCmdInitMeter, "Working...", curr.RecordCount

curr.MoveFirst

Do While Not curr.EOF
prodcode = curr!ProductCode

var.Filter = "[ProductCode] = " & "'" & prodcode & "'"
Set filtvar = var.OpenRecordset

ing.Filter = "[ProductCode] = " & "'" & prodcode & "'"
Set filting = ing.OpenRecordset

scan.Filter = "[ProductCode] = " & "'" & prodcode & "'"
Set filtscan = scan.OpenRecordset

usevarprice = 0
useingprice = 0
usescanprice = 0

If filtvar.EOF And filtvar.BOF Then
Else
    varPrice = filtvar!CalcPrice
    varPrice = Round(varPrice, 0)
    usevarprice = 1
End If

If filting.EOF And filting.BOF Then
Else
    ingPrice = filting!CalcPrice
    ingPrice = Round(ingPrice, 0)
    useingprice = 1
End If

If filtscan.EOF And filtscan.BOF Then
Else
    scanPrice = filtscan!CalcPrice
    scanPrice = Round(scanPrice, 0)
    usescanprice = 1
End If

If usevarprice = 1 And useingprice = 1 And usescanprice = 1 Then
    If varPrice < ingPrice And varPrice < scanPrice Then
        newPrice = varPrice
    ElseIf ingPrice < varPrice And ingPrice < scanPrice Then
        newPrice = ingPrice
    Else
        newPrice = scanPrice
    End If
ElseIf usevarprice = 1 And useingprice = 1 And usescanprice = 0 Then
    If varPrice < ingPrice Then
        newPrice = varPrice
    Else
        newPrice = ingPrice
    End If
ElseIf usevarprice = 1 And useingprice = 0 And usescanprice = 1 Then
    If varPrice < scanPrice Then
        newPrice = varPrice
    Else
        newPrice = scanPrice
    End If
ElseIf usevarprice = 0 And useingprice = 1 And usescanprice = 1 Then
    If scanPrice < ingPrice Then
        newPrice = scanPrice
    Else
        newPrice = ingPrice
    End If
Else
    If usevarprice = 1 Then
        newPrice = varPrice
    ElseIf useingprice = 1 Then
        newPrice = ingPrice
    ElseIf usescanprice = 1 Then
        newPrice = scanPrice
    End If
End If

curr.Edit
curr!Price = newPrice
curr.Update

curr.MoveNext

n = n + 1

'Update the progress bar
SysCmd acSysCmdUpdateMeter, n

'Keep the application responding (optional)
DoEvents
Loop

curr.Close: Set curr = Nothing
var.Close: Set var = Nothing
ing.Close: Set ing = Nothing
scann.Close: Set scan = Nothing

'Remove the progress bar
SysCmd acSysCmdRemoveMeter

'Show the normal cursor again
DoCmd.Hourglass False

End Sub

【问题讨论】:

    标签: vba dao


    【解决方案1】:

    考虑这个查询,使用它只需剪切并粘贴到查询设计窗口的 SQL 视图中。

    SELECT c.productcode,
           c.price,
           s.supfile,
           s.calcprice
    FROM   currentproducts c
           LEFT JOIN (SELECT "varlink"        AS supfile,
                             productcode,
                             ( price * 1.25 ) AS CalcPrice
                      FROM   varlink
                      UNION ALL
                      SELECT "ingram"         AS supfile,
                             productcode,
                             ( price * 1.25 ) AS CalcPrice
                      FROM   ingram
                      UNION ALL
                      SELECT "scansource"     AS supfile,
                             productcode,
                             ( price * 1.25 ) AS CalcPrice
                      FROM   scansource) AS s
                  ON c.productcode = s.productcode 
    

    如果查询显示您感兴趣的数据,您只需从联合表中获取每个产品代码的最小值。这在 SQL 中并不太难。

    例如,您可以将联合查询保存为查询,然后对数据进行操作。

    SELECT u.supfile,
           u.productcode,
           u.calcprice
    FROM   MyUnion u
    WHERE  (( ( u.calcprice ) IN (SELECT TOP 1 calcprice
                                     FROM   MyUnion b
                                     WHERE  b.productcode = u.productcode
                                     ORDER  BY calcprice) )); 
    

    此查询也可以作为派生表包含,与上面查询的方式相同,因此您可以将各种低价格与当前价格进行比较,但是当两个供应商的价格相同时,此查询会给出重复.

    决策过程可能不像更新价格最低的地方那么简单,但是,如果不出意外,使用 sql 和 vba 将大大减少处理时间和记录集的数量。

    【讨论】:

    • 嗨 Remou,谢谢!因此,如果我理解正确,查询会显示产品代码和当前价格。我不太确定如何,但查询是否显示所有 3 个供应商中哪个价格最便宜(以及相关供应商)?这与我失踪的工会有关吗?只是想了解,所以我不必打扰你:)
    • 它还没有显示最便宜的,我需要在进入下一阶段之前找出显示的数据是相关的,因为我没有任何示例数据。它应该向您显示产品、当前价格、供应商文件名和 calcprice,我们可以从中选择最低 calcprice,但我想获取一些示例数据。
    • 你好Remou,样本数据不用担心,我应该怎么发给你?
    • 编辑您的帖子,然后将每个表格中的一些信息剪切并粘贴到您上面的帖子中。不要太担心布局是否准确。您可以乱七八糟地隐藏任何真实信息。它主要是关于字段及其包含的数据类型。
    • 你好Remou,我的帖子后面的字符太多了,所以我希望你可以在这里使用它。
    【解决方案2】:

    我最终使用了一个临时表 (temp_prod),并将所有 3 个供应商的所有产品都转储到表中。然后我使用了这个查询:

    SELECT a.productcode, a.buyprice, a.listprice, a.source FROM temp_prod AS a WHERE a.buyprice in (Select top 1 buyprice from temp_prod b where a.productcode = b.productcode order by buyprice)
    

    打开包含每个产品代码的最便宜价格的记录集。然后我遍历记录集,用新的销售价格(从购买价格计算)更新产品导出表,瞧。非常感谢 Remou 的帮助!

    【讨论】:

      猜你喜欢
      • 2016-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多