Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reset Back Orders - Is this Macro Inefficient 2

Status
Not open for further replies.

JoeAtWork

Programmer
Jul 31, 2005
2,285
CA
Sage Accpac 500 ERP (Version 5.5A)
SQL Server 2005

I created a macro that is supposed to cancel any back orders. The client tells me it takes 35 minutes for the macro to run through one day's worth of back orders (manually it takes them 2.5 hours).

If I test with only 5 back orders, they get processed in one second flat. I've asked for their log files (that my macro creates) to get an idea how big their dataset is, but it must be much larger considering how long it takes them to do the updates manually.

Anyways, can you take a look and see anything that looks inefficient, or recommend a better way of doing this:
Code:
Private Function APResetBackorders(StartDate As Date, EndDate As Date) As Boolean
    
    On Error GoTo ErrHandler
    
    Dim FUNCTION_NAME As String
    FUNCTION_NAME = "APResetBackorders"
    
    Dim mDBLinkCmpRW As AccpacCOMAPI.AccpacDBLink
    Set mDBLinkCmpRW = OpenDBLink(DBLINK_COMPANY, DBLINK_FLG_READWRITE)
     
    Dim strFilter As String
    Dim strOrdNumber As String
    Dim strOrdUniq As String
    Dim strItemID As String
    Dim strLineNum As String
    Dim dblQty As Double
    Dim bolErrors As Boolean
    Dim temp As Boolean
    Dim bolDetailsUpdated As Boolean
    Dim vwHeader As AccpacCOMAPI.AccpacView
    Dim vwHeaderFields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0520", vwHeader
    Set vwHeaderFields = vwHeader.Fields
    
    Dim vwDetail As AccpacCOMAPI.AccpacView
    Dim vwDetailFields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0500", vwDetail
    Set vwDetailFields = vwDetail.Fields
    
    Dim OEORD1detail2 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail2Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0740", OEORD1detail2
    Set OEORD1detail2Fields = OEORD1detail2.Fields
    
    Dim OEORD1detail3 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail3Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0180", OEORD1detail3
    Set OEORD1detail3Fields = OEORD1detail3.Fields
    
    Dim OEORD1detail4 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail4Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0680", OEORD1detail4
    Set OEORD1detail4Fields = OEORD1detail4.Fields
    
    Dim OEORD1detail5 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail5Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0526", OEORD1detail5
    Set OEORD1detail5Fields = OEORD1detail5.Fields
    
    Dim OEORD1detail6 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail6Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0522", OEORD1detail6
    Set OEORD1detail6Fields = OEORD1detail6.Fields
    
    Dim OEORD1detail7 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail7Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0501", OEORD1detail7
    Set OEORD1detail7Fields = OEORD1detail7.Fields
    
    Dim OEORD1detail8 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail8Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0502", OEORD1detail8
    Set OEORD1detail8Fields = OEORD1detail8.Fields
    
    Dim OEORD1detail9 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail9Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0504", OEORD1detail9
    Set OEORD1detail9Fields = OEORD1detail9.Fields
    
    Dim OEORD1detail10 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail10Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0503", OEORD1detail10
    Set OEORD1detail10Fields = OEORD1detail10.Fields
    
    vwHeader.Compose Array(vwDetail, OEORD1detail4, OEORD1detail3, OEORD1detail2, OEORD1detail5, OEORD1detail6)
    
    vwDetail.Compose Array(vwHeader, OEORD1detail7, OEORD1detail10, OEORD1detail8)
    
    OEORD1detail2.Compose Array(vwHeader)
    
    OEORD1detail3.Compose Array(vwHeader, vwDetail)
    
    OEORD1detail4.Compose Array(vwHeader, vwDetail)
    
    OEORD1detail5.Compose Array(vwHeader)
    
    OEORD1detail6.Compose Array(vwHeader)
    
    OEORD1detail7.Compose Array(vwDetail)
    
    OEORD1detail8.Compose Array(vwDetail, OEORD1detail9)
    
    OEORD1detail9.Compose Array(OEORD1detail8)
    
    OEORD1detail10.Compose Array(vwDetail)
    
    'Filter for orders within the date range and have shipments
    strFilter = "OrdDate >= " & Format(StartDate, "YYYYMMDD") & " AND OrdDate <= " & Format(EndDate, "YYYYMMDD") & _
     " AND NumShpMent > 0"
     
    '**Debug test
    'strFilter = "NumShpMent > 0"

    vwHeader.Browse strFilter, True
     
    Do While vwHeader.Fetch
        strOrdNumber = vwHeader.Fields("OrdNumber").Value
        strOrdUniq = vwHeader.Fields("OrdUniq").Value
        
        bolDetailsUpdated = False
        
        'Filter for details that have back orders and are LineType "Item"
        strFilter = "QtyBackOrd > 0 AND LineType = 1"
        vwDetail.Browse strFilter, 1
        Do While vwDetail.Fetch
            'Double-check that this is within the Order of the outer loop
            If vwDetail.Fields("OrdUniq").Value = strOrdUniq Then
                strLineNum = vwDetail.Fields("LineNum").Value
                strItemID = vwDetail.Fields("Item").Value
                dblQty = vwDetail.Fields("QtyBackOrd").Value
                
                vwDetail.Fields("QTYORDERED").Value = "0.0000"
                vwDetail.Fields("COMPLETE").Value = "1"
                vwDetail.Update
                
                'Write to log
                WriteToBackLog strOrdNumber, strLineNum, strItemID, CStr(dblQty)
                
                bolDetailsUpdated = True
            End If
        Loop
        
        '** Possibly may need following two lines of code
'        vwHeaderFields("OECOMMAND").Value = "4"                           ' Process O/E Command
'        vwHeader.Process

        If bolDetailsUpdated Then
            vwHeader.Update
        End If
    Loop
    
End_Function:

    APResetBackorders = Not bolErrors
    
    Exit Function
    
ErrHandler:
    Dim strError As String
    Dim lCount As Long
    Dim lIndex As Long
    Dim lErrNo As Long
    
    
    If Errors Is Nothing Then
        strError = Err.Description

        If Erl <> 0 Then
            strError = strError & " LINE " & Erl
        End If

        WriteToErrorLog FUNCTION_NAME, Err.Number, strError
        
    Else
        lCount = Errors.Count

        If lCount = 0 Then
            strError = Err.Description

            If Erl <> 0 Then
                strError = strError & " LINE " & Erl
            End If

            WriteToErrorLog FUNCTION_NAME, Err.Number, strError
            
        Else
            strError = "AccPac errors:"

            lErrNo = 0
            For lIndex = 0 To lCount - 1
                lErrNo = lErrNo + 1
                strError = strError & " " & lErrNo & ". " & Errors.Item(lIndex) & ";"
            Next

            If Erl <> 0 Then
                strError = strError & " LINE " & Erl
            End If

            WriteToErrorLog FUNCTION_NAME, 0, strError

            Errors.Clear
        End If

    End If
    
    bolErrors = True
    
    Resume End_Function
    
End Function
 
Make your outer loop with an ADO SQL statement (or use the CS0120 view), then update each order in a separate function that you call by order number.
 
tuba2007 said:
then update each order in a separate function that you call by order number.

Would I open all the same views with the same compositions as my current macro?
 
I just got the log file back, it updated 5387 records! I had no idea their database was so large (I'm subcontracting from the main AccPac consultant).

Off to do my changes.
 
Just a short update, I recently found out that the macro now takes about 60 seconds to run (huge improvement over the 2.5 hours of manual input and 35 minutes of my first version). This is after implementing Tuba's suggestion.

Thanks again Tuba!
 
I'm goinng to have to reopen this thread because I found out the macro is not working 100% on the customer site.

They reported that a third of the records were not getting updated. When I added debug logging, I found what was happening was that the "vwHeader.Fetch" was often returning False.

When there are a small number of orders to update, it seems to work fine. We tested with a result set of 41 orders and it worked perfectly. But normally this would run against several thousand orders, and then the problem appears.

It is probably my interpreation of Tuba's advice where I went wrong. I did this part:
Tuba said:
Make your outer loop with an ADO SQL statement

But not this:
Tuba said:
then update each order in a separate function that you call by order number.
The reason I didn't was because it seemed it would be the exact same code whether it was in the main procedure or separate. I.e. either way I would call vwHeader.Browse and then vwHeader.Fetch (I assume he meant I would publicly dim vwHeader and then open it in the main procedure, call the secondary procedure in a loop, and close vwHeader in the main procedure - perhaps he meant I should keep opening and closing vwHeader in the secondary function).

This is my current code:
Code:
Private Function APResetBackorders(StartDate As Date, EndDate As Date) As Boolean
    
    On Error GoTo ErrHandler
    
    Dim FUNCTION_NAME As String
    FUNCTION_NAME = "APResetBackorders"
    
    Dim bolProcessCheckCredit As Boolean
    Dim rsHeaders As ADODB.Recordset
    
    Dim mDBLinkCmpRW As AccpacCOMAPI.AccpacDBLink
    Set mDBLinkCmpRW = OpenDBLink(DBLINK_COMPANY, DBLINK_FLG_READWRITE)
     
    Dim bolUpdatingHeader As Boolean
    Dim bolUpdatingDetails As Boolean
    
    Dim strFilter As String
    Dim strOrdNumber As String
    Dim strOrdUniq As String
    Dim strItemID As String
    Dim strLineOrdUniq As String
    Dim strLineNum As String
    Dim dblQty As Double
    Dim bolErrors As Boolean
    Dim temp As Boolean
    Dim bolDetailsUpdated As Boolean
    Dim bolLineUpdated As Boolean
    Dim strLogEntry As String
    Dim lngLineType As Long
    Dim bolHeaderFound As Boolean
    Dim lngHeaderCount As Long
    
    Dim vwHeader As AccpacCOMAPI.AccpacView
    Dim vwHeaderFields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0520", vwHeader
    Set vwHeaderFields = vwHeader.Fields
    
    Dim vwDetail As AccpacCOMAPI.AccpacView
    Dim vwDetailFields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0500", vwDetail
    Set vwDetailFields = vwDetail.Fields
    
    Dim OEORD1detail2 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail2Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0740", OEORD1detail2
    Set OEORD1detail2Fields = OEORD1detail2.Fields
    
    Dim OEORD1detail3 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail3Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0180", OEORD1detail3
    Set OEORD1detail3Fields = OEORD1detail3.Fields
    
    Dim OEORD1detail4 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail4Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0680", OEORD1detail4
    Set OEORD1detail4Fields = OEORD1detail4.Fields
    
    Dim OEORD1detail5 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail5Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0526", OEORD1detail5
    Set OEORD1detail5Fields = OEORD1detail5.Fields
    
    Dim OEORD1detail6 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail6Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0522", OEORD1detail6
    Set OEORD1detail6Fields = OEORD1detail6.Fields
    
    Dim OEORD1detail7 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail7Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0501", OEORD1detail7
    Set OEORD1detail7Fields = OEORD1detail7.Fields
    
    Dim OEORD1detail8 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail8Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0502", OEORD1detail8
    Set OEORD1detail8Fields = OEORD1detail8.Fields
    
    Dim OEORD1detail9 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail9Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0504", OEORD1detail9
    Set OEORD1detail9Fields = OEORD1detail9.Fields
    
    Dim OEORD1detail10 As AccpacCOMAPI.AccpacView
    Dim OEORD1detail10Fields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "OE0503", OEORD1detail10
    Set OEORD1detail10Fields = OEORD1detail10.Fields
    
    vwHeader.Compose Array(vwDetail, OEORD1detail4, OEORD1detail3, OEORD1detail2, OEORD1detail5, OEORD1detail6)
    
    vwDetail.Compose Array(vwHeader, OEORD1detail7, OEORD1detail10, OEORD1detail8)
    
    OEORD1detail2.Compose Array(vwHeader)
    
    OEORD1detail3.Compose Array(vwHeader, vwDetail)
    
    OEORD1detail4.Compose Array(vwHeader, vwDetail)
    
    OEORD1detail5.Compose Array(vwHeader)
    
    OEORD1detail6.Compose Array(vwHeader)
    
    OEORD1detail7.Compose Array(vwDetail)
    
    OEORD1detail8.Compose Array(vwDetail, OEORD1detail9)
    
    OEORD1detail9.Compose Array(OEORD1detail8)
    
    OEORD1detail10.Compose Array(vwDetail)
    
    'Filter for orders within the date range and have shipments
'    strFilter = "OrdDate >= " & Format(StartDate, "YYYYMMDD") & " AND OrdDate <= " & Format(EndDate, "YYYYMMDD") & _
'     " AND NumShpMent > 0"
'    vwHeader.Browse strFilter, True
    If GetBackOrdersRS(StartDate, EndDate, rsHeaders) = False Then
        Exit Function    'There was an error retrieving order headers from the database
    End If
    
    If rsHeaders.BOF And rsHeaders.EOF Then
        WriteToErrorLog "APResetBackOrders", 0, "NOTE - no header records were retrieved."
        Exit Function
    End If
    
    If m_bolDebugLog Then
        strLogEntry = "DEBUG: APResetBackOrders - START ####################"
        
        WriteToErrorLog FUNCTION_NAME, 0, strLogEntry
    End If
    
    'Do While vwHeader.Fetch
    Do While Not rsHeaders.EOF
        
'        strOrdNumber = vwHeader.Fields("ORDNUMBER").Value
'        strOrdUniq = vwHeader.Fields("ORDUNIQ").Value
        strOrdNumber = rsHeaders("ORDNUMBER")
        strOrdUniq = rsHeaders("ORDUNIQ")
       
        '* April 6, 2010 - the Fetch is sometimes failing on the Customer site, so try using ORDNUMBER instead
        'vwHeader.Browse "ORDUNIQ=" & strOrdUniq, True
        vwHeader.Browse "ORDNUMBER=""" & strOrdNumber & """", True
        
        '* March 21, 2010 - log whether he Browse actually found the record
        'vwHeader.Fetch
        bolHeaderFound = vwHeader.Fetch
        lngHeaderCount = lngHeaderCount + 1
        
        If m_bolDebugLog Then
            strLogEntry = "DEBUG: Header Rec # " & lngHeaderCount & "; OrdNumber=" & strOrdNumber & "; OrdUniq=" & strOrdUniq & _
             "; Fetch=" & bolHeaderFound
             
            WriteToErrorLog FUNCTION_NAME, 0, strLogEntry
            
        End If
        
        bolUpdatingHeader = True
        bolDetailsUpdated = False
        
        'Filter for details that have back orders and are LineType "Item"
        '* March 21, 2010 - because current macro is skipping many orders, try not using Browse
        'strFilter = "QtyBackOrd > 0 AND LineType = 1 AND ORDUNIQ=" & strOrdUniq
        strFilter = ""
        
        '* April 6, 2010 - test if we don't need any Browse at all on the detail (i.e. it's automatically filtered by the Header)
        'vwDetail.Browse strFilter, 1
        
        '* April 6, 2010 - if the Fetch for the header failed, go on to the next header
        If bolHeaderFound = False Then
            If m_bolDebugLog Then
                strLogEntry = "DEBUG: Header Record # " & lngHeaderCount & " was NOT UPDATED because the Fetch failed to retrieve the header record"
                
                WriteToErrorLog FUNCTION_NAME, 0, strLogEntry
                
                GoTo NextHeader
            End If
        End If
        '*
        
        Do While vwDetail.Fetch
            strLineNum = ""
            strItemID = ""
            dblQty = 0
            strLineOrdUniq = ""
            bolLineUpdated = False
            
            bolUpdatingDetails = True
            
            'Double-check that this is within the Order of the outer loop
            '* March 21, 2010 - instead of using Browse, check if details match the filter
            'If vwDetail.Fields("ORDUNIQ").Value = strOrdUniq And UCase(vwDetail.Fields("PRICELIST").Value) = UCase(m_strPriceList) Then
                strLineNum = vwDetail.Fields("LineNum").Value
                strItemID = vwDetail.Fields("Item").Value
                dblQty = vwDetail.Fields("QtyBackOrd").Value
                lngLineType = vwDetail.Fields("LineType").Value
                strLineOrdUniq = vwDetail.Fields("ORDUNIQ").Value
                
                '* March 21, 2010 - check if detail meets filter requirements
                If strLineOrdUniq = strOrdUniq And UCase(vwDetail.Fields("PRICELIST").Value) = UCase(m_strPriceList) And _
                 dblQty > 0 And lngLineType = 1 Then
                
                    '* Original code
                    vwDetail.Fields("QTYORDERED").Value = "0.0000"
                    vwDetail.Fields("COMPLETE").Value = "1"
                    vwDetail.Update
                    
                    'Write to log
                    WriteToBackLog strOrdNumber, strLineNum, strItemID, CStr(dblQty)
                
                    bolDetailsUpdated = True    'At least one of the details was updated
                    bolLineUpdated = True       'This particular line was updated
                    '*
                Else
                    bolLineUpdated = False
                End If
            'End If
            
            If m_bolDebugLog Then
                strLogEntry = "DEBUG: " & "LineNum=" & strLineNum & "; OrdUniq=" & strLineOrdUniq & "; Item=" & strItemID & _
                 "; QtyBackOrd=" & dblQty & "; LineType=" & lngLineType & "; UPDATED=" & bolLineUpdated
                 
                WriteToErrorLog FUNCTION_NAME, 0, strLogEntry
            End If
NextDetail:

        Loop
        
        bolUpdatingDetails = False

        If bolDetailsUpdated Then
            vwHeaderFields("APPROVEBY").Value = m_strUserName               ' Authorizing User ID
            ' User Can Approve Credit Lift
            vwHeaderFields("GOAPPROSEC").Value = "1"
            ' Authorizing User Password
            vwHeaderFields("APPPASSWRD").PutWithoutVerification (m_strPassword)

            vwHeader.Process     'First place where a Process command is required

            vwHeaderFields("GOCHKCRDT").Value = "1"                          ' Perform Credit Limit Check
            bolProcessCheckCredit = True
            vwHeader.Process    'Causes automation error, but seems to be necessary
            bolProcessCheckCredit = False

            vwHeader.Update
            
            If m_bolDebugLog Then
                strLogEntry = "DEBUG: Header Record # " & lngHeaderCount & " was UPDATED"
                
                WriteToErrorLog FUNCTION_NAME, 0, strLogEntry
            End If
        Else
        
            If m_bolDebugLog Then
                strLogEntry = "DEBUG: Header Record # " & lngHeaderCount & " was NOT UPDATED"
                
                WriteToErrorLog FUNCTION_NAME, 0, strLogEntry
            End If
            
        End If
        
NextHeader:
        rsHeaders.MoveNext
       
    Loop
    
    If m_bolDebugLog Then
        strLogEntry = "DEBUG: APResetBackOrders - END - Total Header Records = " & lngHeaderCount & "####################'"
        
        WriteToErrorLog FUNCTION_NAME, 0, strLogEntry
    End If
    
End_Function:

    On Error Resume Next
    rsHeaders.Close
    APResetBackorders = Not bolErrors
    
    Exit Function
    
ErrHandler:
    Dim strError As String
    Dim lCount As Long
    Dim lIndex As Long
    Dim lErrNo As Long
    
    'If error occurred when processing the "Check customer credit limit", just clear the Errors
    'collection and proceed.  Testing has shown that an "automation" error always appears but it
    'does not seem to be valid, and the invoice still gets created if we resume the code.
    If bolProcessCheckCredit Then
        Errors.Clear
        Resume Next
    ElseIf Errors Is Nothing Then
        strError = Err.Description

        If Erl <> 0 Then
            strError = strError & " LINE " & Erl
        End If

        WriteToErrorLog FUNCTION_NAME, Err.Number, strError
        
    Else
        lCount = Errors.Count

        If lCount = 0 Then
            strError = Err.Description

            If Erl <> 0 Then
                strError = strError & " LINE " & Erl
            End If

            WriteToErrorLog FUNCTION_NAME, Err.Number, strError
            
        Else
            strError = "AccPac errors:"

            lErrNo = 0
            For lIndex = 0 To lCount - 1
                lErrNo = lErrNo + 1
                strError = strError & " " & lErrNo & ". " & Errors.Item(lIndex) & ";"
            Next

            If Erl <> 0 Then
                strError = strError & " LINE " & Erl
            End If

            WriteToErrorLog FUNCTION_NAME, 0, strError

            Errors.Clear
        End If

    End If
    
    bolErrors = True
    
    If bolUpdatingDetails Then
        strError = "Error on Order # " & strOrdNumber & ", Detail Line #" & strLineNum & ", Item #" & strItemID & _
         "Qty=" & dblQty
         
        WriteToErrorLog FUNCTION_NAME, 0, strError
        
        Resume NextDetail
    ElseIf bolUpdatingHeader Then
        strError = "Error on Order # " & strOrdNumber

        WriteToErrorLog FUNCTION_NAME, 0, strError
        
        Resume NextHeader
    Else
        Resume End_Function
    End If
    
End Function

Private Function GetBackOrdersRS(StartDate As Date, EndDate As Date, ByRef rsOrders As ADODB.Recordset) As Boolean
    Dim adoConn As ADODB.Connection
    Dim SQL As String
    Dim bolConnectionOpened As Boolean
    Dim strStartDate As String
    Dim strEndDate As String
    Dim strMonth As String
    Dim strDay As String
    
    On Error GoTo ErrHandler
    
    bolConnectionOpened = False
    
    Set adoConn = New ADODB.Connection
    adoConn.ConnectionString = "Provider=SQLNCLI;Server=" & m_strDBServer & ";Database=" & m_strDatabase & ";Uid=" & _
     m_strDBLogin & "; Pwd=" & m_strDBPassword & ";"
    adoConn.Open
    
    bolConnectionOpened = True
    
    Set rsOrders = New ADODB.Recordset
    
    strMonth = Month(StartDate)
    If Len(strMonth) = 1 Then strMonth = "0" & strMonth
    strDay = Day(StartDate)
    If Len(strDay) = 1 Then strDay = "0" & strDay
    strStartDate = Year(StartDate) & strMonth & strDay
    
    strMonth = Month(EndDate)
    If Len(strMonth) = 1 Then strMonth = "0" & strMonth
    strDay = Day(EndDate)
    If Len(strDay) = 1 Then strDay = "0" & strDay
    strEndDate = Year(EndDate) & strMonth & strDay
    
    SQL = "SELECT OEORDH.ORDUNIQ, OEORDH.ORDNUMBER FROM OEORDH INNER JOIN " & _
           "OEORDH1 ON OEORDH.ORDUNIQ = OEORDH1.ORDUNIQ WHERE OEORDH.ORDDATE >= " & strStartDate & _
           " AND OEORDH.ORDDATE <=" & strEndDate & " AND OEORDH1.NUMSHPMENT > 0"
           
    rsOrders.Open SQL, adoConn, adOpenStatic, adLockOptimistic, adCmdText
    
    GetBackOrdersRS = True
    
    Exit Function
    
ErrHandler:
    Dim lngErrNo As Long
    Dim strErrDesc As String
    Dim strMsg As String
    Dim strTitle As String
    
    lngErrNo = Err.Number
    strErrDesc = Err.Description
    
    If bolConnectionOpened = False Then
        strTitle = "Error Opening Database Connection"
        strMsg = "Error connecting to the database, ERROR #" & lngErrNo & ": " & strErrDesc
    Else
        strTitle = "Error Retrieving Records"
        strMsg = "Error retrieving order header records, ERROR #" & lngErrNo & ": " & strErrDesc
    End If
    
    MsgBox strMsg, vbExclamation, strTitle
    
    WriteToErrorLog "GetBackOrdersRS", lngErrNo, strMsg
    
    If bolConnectionOpened Then
        On Error Resume Next
        adoConn.Close
    End If
    
    GetBackOrdersRS = False
    
    
End Function
 
You don't need to open and close the view, just do vwheader.Cancel before every .Browse and .Fetch.

Pseudocode:

vwHeaderSearch.Browse "ORDDATE >= XXXX AND ORDDATE <= YYYY", True
Do while vwHeaderSearch.Fetch
vwHeader.Cancel
vwHeader.browse "Orduniq = " & vwheadersearch.fields("ORDDATE"),True
if vwheader.Fetch then
{update stuff here}
end if
loop

Open vwHeaderSearch with a read-only link and no compositions, it will run faster
 
Thanks for the continued feedback.

However, I think my recordset already accomplishes what vwHeaderSearch does.

My bottle-neck is this:


vwHeader.Browse "ORDUNIQ=" & strOrdUniq, True
vwHeader.Fetch


My logging tells me that the very first Browse/Fetch takes 20-30 minutes. What I find strange is that every subsequent Browse/Fetch is just a second. What makes the first one take so long?

I'll try to do the Cancel to see if it fixes the problem with the Header/Detail not staying in sync.



 
If you have the ORDUNIQ value then do something like:
Code:
vwHeader.Fields("ORDUNIQ").value = rsHeaders("ORDUNIQ")
vwHeader.Read

That should be a superfast read.
The only reason I can see why your .Browse is taking so long would be if you changed vwHeader.Order to something other than 0.
 
Actually there was no .Order so I added the code:

vwHeader.Init
vwHeader.Order = 0

Also, I finally reproduced the Fetch=False error, and I found that adding the .Cancel above the Browse/Fetch as Tuba suggested fixed that.

Thankyou both for your generous help. I hope this works now on the client's system.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top