最小化VBA访问功能的执行时间 [英] Minimize execution time of an VBA-Access function

查看:160
本文介绍了最小化VBA访问功能的执行时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Access中的AutoExec宏上运行以下函数。

I am running the following function on a AutoExec macro in Access.

问题是运行它大约需要40秒

The issue is that it takes approximately 40 sec (!!!) to run it which is way too long for roughly 200 records.

任何人都可以提出任何方法来最小化这个运行时间。

Can anyone suggest any way to minimize this runtime ?

的代码基本上是检查 RefreshedDatas表中的每个记录,如果其中一个多个值PartNo字段中的值存在于其他的两个可能字段中(请参阅结构在图片:我必须检查是否SparPartNo字段SerialPartNo字段包含该值)。如果是,我将在 WPRC Part 字段中输入YES,否则输入NO。

The GOAL of this code is basically to check for each record in the RefreshedDatas table if one of the values in the multiple values' PartNo field exists in 2 possible fields from other table (see structure in picture : I have to check if either SparPartNo field either SerialPartNo field contain the value). If it is, I would write YES in a WPRC Part field, otherwise NO.

例如,

我检查并意识到代码的第5部分是39秒,前4个大约需要1秒。

I checked and realized that the part 5) of the code is the one taking 39 secs while the first 4 parts take about 1 sec.

Function PopulationOfWPRCField()

'1) Create an access to the PartNo field (=Recordset) and store all its values in an array called arrayPartNo
    Dim conn As New ADODB.Connection
    Dim connStr As String
    Dim rs As ADODB.Recordset
    Dim PartNoSQL As String
    Dim arrayPartNo() As Variant

    connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & "PathtoMyAccessDatabase\" & "NewVersion.accdb" & ";"
    conn.ConnectionString = connStr
    conn.Open
    Set rs = New ADODB.Recordset
    PartNoSQL = "SELECT PartNo FROM RefreshedDatas" '"SELECT PartNo FROM 12Dec"
    rs.Open PartNoSQL, conn, adOpenStatic, adLockReadOnly, adCmdText

    If Not rs.EOF Then
        arrayPartNo = rs.GetRows
    End If
    'Set rs = Nothing


'2) Same with fields SerialPartNo and SparePartNo from the WPRC_List (+ShipmentID for the 4th part of this code)
    Dim arraySerialPartNo() As Variant
    Dim arraySparePartNo() As Variant
    Dim arrayShipmentID() As Variant
    Dim SerialPartNoSQL As String
    Dim SparePartNoSQL As String
    Dim ShipmentIDSQL As String

    'For SpartNo

        Set rs = New ADODB.Recordset
        SparePartNoSQL = "SELECT SparePartNo FROM WPRC_Parts_List"
        rs.Open SparePartNoSQL, conn, adOpenStatic, adLockReadOnly, adCmdText
        If Not rs.EOF Then
            arraySparePartNo = rs.GetRows
        End If
        'For i = 0 To UBound(arraySparePartNo, 2)
        '    Debug.Print arraySparePartNo(0, i)
        'Next i
        Set rs = Nothing

    'For SerialNo

        Set rs = New ADODB.Recordset
        SerialPartNoSQL = "SELECT SerialPartNo FROM WPRC_Parts_List"
        rs.Open SerialPartNoSQL, conn, adOpenStatic, adLockReadOnly, adCmdText
        If Not rs.EOF Then
            arraySerialPartNo = rs.GetRows
        End If
        'For i = 0 To UBound(arraySerialPartNo, 2)
         '   Debug.Print arraySerialPartNo(0, i)
        'Next i
        Set rs = Nothing

    'For ShipmentID

    Set rs = New ADODB.Recordset
        ShipmentIDSQL = "SELECT [Shipment ID] FROM RefreshedDatas"  
        rs.Open ShipmentIDSQL, conn, adOpenStatic, adLockReadOnly, adCmdText
        If Not rs.EOF Then
            arrayShipmentID = rs.GetRows
        End If
        'For i = 0 To UBound(arrayShipmentID, 2)
         '   Debug.Print arrayShipmentID(0, i)
        'Next i
        Set rs = Nothing

        Set conn = Nothing

'3) We calculate the size of the GoodArray() we'll declare later on so that we can declare it properly
    Dim h As Integer
    Dim longest As Integer
    longest = 0
    For h = 0 To UBound(arrayPartNo, 2) ' in this loop we search for the longest character in arrayPartNo and store its size in "longest"
        If Len(arrayPartNo(0, h)) > longest Then longest = Len(arrayPartNo(0, h))
    Next h
    'MsgBox longest '63 in this case
    h = (longest + 1) / 8 ' since h was only used in the loop above we reuse it to store this = 8 -> size of the 2nd dimension of GoodArray() , it represents the biggest number of PartNo a cell in arrayPartNo contains
    longest = UBound(arrayPartNo, 2) ' same here, we just reuse the variable to store this -> size of the 1st dimension of GoodArray () , it represents the number of cells(=records) in arrayPartNo ( in the MainForm)



'4) Declaration of the 2-dimensional array GoodArray() and population of it
    Dim NumberOfPartNo As Integer ' Number of PartNo in a specific row
    Dim length As Integer ' length of a correct PartNo
    Dim i As Integer
    Dim GoodArray() As Variant ' this is a 2 dimensional array where 1st dimension contains UBound(arrayPartNo, 2) cells and 2nd dimension contains the number of PartNo (=NumberOfPartNo) for the row determined by the 1st dimension)
    ' reason for (longest+1)/8 : we have the following equation : x*7 + (x-1)= longest where x is the number of PartNo( but for the record which has the most PartNo) and (x-1) is the number of ";" separating all those PartNo, the total gives the number of character of the record (= longest for the record with the most PartNo)
   ReDim Preserve GoodArray(longest, h)
For i = 0 To UBound(arrayPartNo, 2)

    length = 7
    NumberOfPartNo = 0
    If Len(arrayPartNo(0, i)) > 0 Then
            Do
                GoodArray(i, NumberOfPartNo) = Mid(arrayPartNo(0, i), length + 1 - 7, 7)
                NumberOfPartNo = NumberOfPartNo + 1
                length = length + 8

            Loop While Len(arrayPartNo(0, i)) >= length ' since we use such a loop it allows any PartNo to go through it even if it has less than 6 characters
        End If
Next i

'5) Comparison of the arrays : For each element contained in GoodArray() check if it is included in arraySerialPartNo or arraySparePartNo
Dim j As Integer
Dim k As Integer
'Dim OnList As Boolean
For i = 0 To UBound(GoodArray, 1)
    k = 0
    'OnList = False
    Do Until GoodArray(i, k) = ""
        For j = 0 To UBound(arraySerialPartNo, 2)
            If arraySerialPartNo(0, j) = GoodArray(i, k) Then
                DoCmd.RunSQL "UPDATE RefreshedDatas Set [WPRC Part] = 'Yes' WHERE [Shipment ID] = " & arrayShipmentID(0, i)
                'OnList = True
                GoTo Prochain
            End If
        Next j

        For j = 0 To UBound(arraySparePartNo, 2)
            If arraySparePartNo(0, j) = GoodArray(i, k) Then
                DoCmd.RunSQL "UPDATE RefreshedDatas Set [WPRC Part] = 'Yes' WHERE [Shipment ID] = " & arrayShipmentID(0, i)                   
                'OnList = True
                GoTo Prochain
            End If
        Next j

        k = k + 1
    Loop

    DoCmd.RunSQL "UPDATE RefreshedDatas Set [WPRC Part] = 'No' WHERE [Shipment ID] = " & arrayShipmentID(0, i)        
Prochain:

Next i

End Function


推荐答案


这个代码的目标基本上是检查
RefreshedDatas表中的每个记录,如果一个在多个值中的值
PartNo字段存在于来自其他表的2个可能的字段中(参见
结构的图片:我必须检查SparPartNo字段
是否包含SerialPartNo字段)。如果是,我将在WPRC部分字段中写入
YES,否则为$。

The GOAL of this code is basically to check for each record in the RefreshedDatas table if one of the values in the multiple values' PartNo field exists in 2 possible fields from other table (see structure in picture : I have to check if either SparPartNo field either SerialPartNo field contain the value). If it is, I would write YES in a WPRC Part field, otherwise NO.

,你需要这个..

UPDATE  RefreshedDatas
SET WPRC = "NO"; // Everything is set to no.

现在测试这个sql,它将列出所有零件,如果在partno集合中找到任何零件。 PartNo.Value是访问多个值字段中的项目的方式。

now test this sql, which will list all parts and if any parts found in the partno collection. PartNo.Value is the way to access items in a multiple value field.

Select
R.SparePartNo
R.SerialPartNo
iif(isnull(R2.PartNo.value),"No", "Yes") as [Part found]
FROM RefreshedDatas as R left join RefreshedDatas as R2
    ON (R.SparePArtNo = R2.PartNo.Value OR R.SerialPartNo = R2.PArtNo.Value);

备份您的表格,并尝试此更新。类似于连接表,您还可以使用子查询从另一个表或同一个表中选择和查找值。

Backup your tables and try this update. Similar to join the tables, you can also use a sub query to select and find the values from another table or same table.

UPDATE RefreshedDatas
SET WPRC = "YES"
WHERE 
//if SparePartNo is available in the PartNo collection
    RefreshedDatas.SparePartNo in (SELECT P.PartNo.Value from RefreshedDatas as P WHERE P.ID = RefreshedDatas.ID)
// or if the SerialPartNo is available in the partNo Collection.
OR RefreshedDatas.SerialPartNo (SELECT S.PartNo.Value from RefreshedDatas as S WHERE S.ID = RefreshedDatas.ID)

没有办法测试代码,但你应该得到一些想法如何在SQL中工作。
如果要在整个PartNo集合中搜索零件号而不是在同一行中搜索零件号,请删除P WHERE P.ID = RefreshedDatas.ID。

have no means to test the code but you should get some idea how this works in SQL. Remove the "P WHERE P.ID = RefreshedDatas.ID" if you want to search for a part number in entire PartNo collection and not in the same row

这篇关于最小化VBA访问功能的执行时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆