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!

Error inserting invoice with COM API 2

Status
Not open for further replies.

JoeAtWork

Programmer
Jul 31, 2005
2,285
CA
I've written a macro for importing a series of invoices one at a time. It works for the first invoice, but in the next iteration I get "error -2147417848. Automation error. The object invoked has disconnected from its clients." This occurs on the line:

vwOrder.Insert

I figure I must not be initializing the view correctly for starting to add a second new record, but I don't know the correct methods I should call to do that.

What makes the error worse is it doesn't get trapped by my error handler, the macro just stops responding and have to kill the process.


Code:
Private Sub ImportInvoices()
'This subroutine imports the invoices to AccPac.  The code is adapted from a recorded macro
'that followed these manual steps:
'1. Create the Order
'2. Post it - had to override credit limit check by providing the appropriate username password
'3. Pressed "Ship All" so that the "Create Invoice" checkbox would appear
'4. On the Totals tab, entered the Invoice Number, left the Shipment Number as it was,
'   i.e. "*** NEW ***"
'5. Post it

On Error GoTo ACCPACErrorHandler

Dim objInvoice As clsInvoice
Dim objDetail As clsInvoiceDetail
Dim bolProcessCheckCredit As Boolean

Dim temp As Boolean
Dim vwOrder As AccpacCOMAPI.AccpacView
Dim vwOrderFields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0520", vwOrder
Set vwOrderFields = vwOrder.Fields

Dim vwDetails As AccpacCOMAPI.AccpacView
Dim vwDetailsFields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0500", vwDetails
Set vwDetailsFields = vwDetails.Fields

Dim OEORD1detail2 As AccpacCOMAPI.AccpacView
Dim OEORD1detail2Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0740", OEORD1detail2
Set OEORD1detail2Fields = OEORD1detail2.Fields

Dim OEORD1detail3 As AccpacCOMAPI.AccpacView
Dim OEORD1detail3Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0180", OEORD1detail3
Set OEORD1detail3Fields = OEORD1detail3.Fields

Dim OEORD1detail4 As AccpacCOMAPI.AccpacView
Dim OEORD1detail4Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0680", OEORD1detail4
Set OEORD1detail4Fields = OEORD1detail4.Fields

Dim OEORD1detail5 As AccpacCOMAPI.AccpacView
Dim OEORD1detail5Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0526", OEORD1detail5
Set OEORD1detail5Fields = OEORD1detail5.Fields

Dim OEORD1detail6 As AccpacCOMAPI.AccpacView
Dim OEORD1detail6Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0522", OEORD1detail6
Set OEORD1detail6Fields = OEORD1detail6.Fields

Dim OEORD1detail7 As AccpacCOMAPI.AccpacView
Dim OEORD1detail7Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0501", OEORD1detail7
Set OEORD1detail7Fields = OEORD1detail7.Fields

Dim OEORD1detail8 As AccpacCOMAPI.AccpacView
Dim OEORD1detail8Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0502", OEORD1detail8
Set OEORD1detail8Fields = OEORD1detail8.Fields

Dim OEORD1detail9 As AccpacCOMAPI.AccpacView
Dim OEORD1detail9Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0504", OEORD1detail9
Set OEORD1detail9Fields = OEORD1detail9.Fields

Dim vwDetails0 As AccpacCOMAPI.AccpacView
Dim vwDetails0Fields As AccpacCOMAPI.AccpacViewFields
m_DBLinkWrite.OpenView "OE0503", vwDetails0
Set vwDetails0Fields = vwDetails0.Fields

vwOrder.Compose Array(vwDetails, OEORD1detail4, OEORD1detail3, OEORD1detail2, OEORD1detail5, OEORD1detail6)

vwDetails.Compose Array(vwOrder, OEORD1detail7, vwDetails0, OEORD1detail8)

OEORD1detail2.Compose Array(vwOrder)

OEORD1detail3.Compose Array(vwOrder, vwDetails)

OEORD1detail4.Compose Array(vwOrder, vwDetails)

OEORD1detail5.Compose Array(vwOrder)

OEORD1detail6.Compose Array(vwOrder)

OEORD1detail7.Compose Array(vwDetails)

OEORD1detail8.Compose Array(vwDetails, OEORD1detail9)

OEORD1detail9.Compose Array(OEORD1detail8)

vwDetails0.Compose Array(vwDetails)


'Loop through all invoices for the current customer
For Each objInvoice In m_Customer.Invoices

    ' ?????????? Do I need to call vwOrder.RecordGenerate ?????????????
    'vwOrder.RecordGenerate False
    ' When I had this enabled I used to get error
    ' "Order. Record already exists." on the first iteration.

    vwOrder.Init
    
    InsertFieldValue vwOrderFields("ORDNUMBER"), objInvoice.OrderNo     ' Order Number
    
    vwOrderFields("CUSTOMER").Value = m_Customer.CustNo                 ' Customer Number
    
    vwOrderFields("PROCESSCMD").PutWithoutVerification ("1")            ' Process Command
    
    vwOrderFields("SHIPTO").Value = m_Customer.ShipToNo                 ' Ship-To Location Code
    vwOrderFields("GOFCALCTAX").PutWithoutVerification ("1")            ' Perform Forced Tax Calculation
    InsertFieldValue vwOrderFields("PONUMBER"), objInvoice.PONumber     ' Purchase Order Number
    
    'Enter Location - if not supplied, uses a default
    InsertFieldValue vwOrderFields("LOCATION"), objInvoice.Location
    
    'Loop through invoice details
    For Each objDetail In objInvoice.Details
        vwDetails.RecordGenerate False
        
        vwDetailsFields("ITEM").Value = objDetail.Item                  ' Item
        
        vwDetailsFields("QTYORDERED").Value = objDetail.QtyOrdered      ' Quantity Ordered
        vwDetailsFields("PRIUNTPRC").Value = objDetail.UnitPrice
        vwDetails.Insert
    Next
    '
        
    vwOrderFields("GOCALCTAX").PutWithoutVerification ("1")             ' Perform Tax Calculation
    InsertFieldValue vwOrderFields("REFERENCE"), objInvoice.Reference   ' Order Reference
    InsertFieldValue vwOrderFields("DESC"), objInvoice.Description      ' Order Description
    
    vwOrderFields("APPROVEBY").Value = m_OverrideUserName               ' Authorizing User ID
    ' User Can Approve Credit Lift
    vwOrderFields("GOAPPROSEC").Value = "1"
    ' Authorizing User Password
    vwOrderFields("APPPASSWRD").PutWithoutVerification (m_OverrideUserPassword)
    
    vwOrder.Process     'First place where a Process command is required
    
    vwOrderFields("GOCHKCRDT").Value = "1"                          ' Perform Credit Limit Check
    bolProcessCheckCredit = True
    vwOrder.Process    'Causes automation error, but seems to be necessary
    bolProcessCheckCredit = False
    
    vwOrderFields("GOSHIPALL").PutWithoutVerification ("1")         ' Perform Ship All
    
    vwOrder.Process
    
    vwOrderFields("INVPRODUCE").Value = "1"                         ' Invoice Will Be Produced
    
    vwDetails.Read
    vwOrderFields("GOCALCTAX").PutWithoutVerification ("1")         ' Perform Tax Calculation
    vwOrder.Process
    
    vwOrderFields("INVNUMBER").Value = objInvoice.InvoiceNo         ' Invoice Number
    
    'Date fields need to be converted from their XML format of "yyyy-mm-dd" to make sure
    'month/day are interpreted correctly
    If IsDate(objInvoice.OrderDate) Then
        vwOrderFields("ORDDATE").Value = ConvertXMLDate(objInvoice.OrderDate)
    End If
    If IsDate(objInvoice.InvoiceDate) Then
        vwOrderFields("INVDATE").Value = ConvertXMLDate(objInvoice.InvoiceDate)
    End If
[COLOR=green]
    'Error is here, on the second iteration[/color]
[COLOR=red]
    vwOrder.Insert[/color]
Next


Exit Sub

ACCPACErrorHandler:
    Dim strError As String
    Dim lCount As Long
    Dim lIndex As Long
    Dim strInvoiceNo As String
    
    '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 = "Error # " & Err.Number & ": " & Err.Description
        If Not (objInvoice Is Nothing) Then
           strInvoiceNo = objInvoice.InvoiceNo
        End If
         WriteToLog Now, "FAIL", "Import Invoice", strError, m_Customer.CustNo, _
          m_Customer.ShipToNo, strInvoiceNo
    Else
        lCount = Errors.Count
        
        If Not (objInvoice Is Nothing) Then
           strInvoiceNo = objInvoice.InvoiceNo
        End If

        If lCount = 0 Then
            strError = "Error # " & Err.Number & ": " & Err.Description
            WriteToLog Now, "FAIL", "Import Invoice", strError, m_Customer.CustNo, _
             m_Customer.ShipToNo, strInvoiceNo
        Else
            strError = "AccPac errors:"
            
            For lIndex = 0 To lCount - 1
                strError = strError & " " & (lIndex + 1) & ". " & Errors.Item(lIndex) & ";"
            Next
            
            WriteToLog Now, "FAIL", "Import Invoice", strError, m_Customer.CustNo, _
             m_Customer.ShipToNo, strInvoiceNo
            
            Errors.Clear
        End If
    
    End If

End Sub

Private Sub InsertFieldValue(viewField As AccpacViewField, StringValue As String)
'Purpose:   Inserts a value in an AccPac field if the value is not a zero-length string
    If Len(StringValue) > 0 Then
        viewField.PutWithoutVerification StringValue
    End If
End Sub

 
Here is a simplified macro to generate 2 OE invoices in OE 5.4

Note: to create a new order you need the following 3 lines:
OEheader.Order = 0
OEheader.Fields("ORDUNIQ") = 0
OEheader.Init

Code:
Dim mDBLinkCmpRW As AccpacCOMAPI.AccpacDBLink
Dim OEheader As AccpacCOMAPI.AccpacView
Dim OEdetail1 As AccpacCOMAPI.AccpacView
Dim OEdetail2 As AccpacCOMAPI.AccpacView
Dim OEdetail3 As AccpacCOMAPI.AccpacView
Dim OEdetail4 As AccpacCOMAPI.AccpacView
Dim OEdetail5 As AccpacCOMAPI.AccpacView
Dim OEdetail6 As AccpacCOMAPI.AccpacView
Dim OEdetail7 As AccpacCOMAPI.AccpacView
Dim OEdetail8 As AccpacCOMAPI.AccpacView
Dim OEdetail9 As AccpacCOMAPI.AccpacView
Dim OEdetail10 As AccpacCOMAPI.AccpacView

Set mDBLinkCmpRW = OpenDBLink(DBLINK_COMPANY, DBLINK_FLG_READWRITE)
mDBLinkCmpRW.OpenView "OE0520", OEheader
mDBLinkCmpRW.OpenView "OE0500", OEdetail1
mDBLinkCmpRW.OpenView "OE0740", OEdetail2
mDBLinkCmpRW.OpenView "OE0180", OEdetail3
mDBLinkCmpRW.OpenView "OE0680", OEdetail4
mDBLinkCmpRW.OpenView "OE0526", OEdetail5
mDBLinkCmpRW.OpenView "OE0522", OEdetail6
mDBLinkCmpRW.OpenView "OE0501", OEdetail7
mDBLinkCmpRW.OpenView "OE0502", OEdetail8
mDBLinkCmpRW.OpenView "OE0504", OEdetail9
mDBLinkCmpRW.OpenView "OE0503", OEdetail10

OEheader.Compose Array(OEdetail1, OEdetail4, OEdetail3, OEdetail2, OEdetail5, OEdetail6)
OEdetail1.Compose Array(OEheader, OEdetail7, OEdetail10, OEdetail8)
OEdetail2.Compose Array(OEheader)
OEdetail3.Compose Array(OEheader, OEdetail1)
OEdetail4.Compose Array(OEheader, OEdetail1)
OEdetail5.Compose Array(OEheader)
OEdetail6.Compose Array(OEheader)
OEdetail7.Compose Array(OEdetail1)
OEdetail8.Compose Array(OEdetail1, OEdetail9)
OEdetail9.Compose Array(OEdetail8)
OEdetail10.Compose Array(OEdetail1)

'First invoice
OEheader.Order = 0
OEheader.Fields("ORDUNIQ") = 0
OEheader.Init
OEheader.Fields("CUSTOMER").Value = "1200"
OEheader.Fields("PROCESSCMD").PutWithoutVerification 1
OEheader.Process

OEdetail1.RecordCreate 0
OEdetail1.Fields("ITEM").Value = "A11030"
OEdetail1.Fields("PROCESSCMD").PutWithoutVerification 1
OEdetail1.Process
OEdetail1.Fields("QTYORDERED").Value = 1
OEdetail1.Fields("QTYSHIPPED").Value = 1
OEdetail1.Insert

OEheader.Fields("INVPRODUCE").Value = 1
OEheader.Fields("GOCALCTAX").PutWithoutVerification 1
OEheader.Process
'OEheader.Fields("INVNUMBER").Value = "INV1234"
OEheader.Fields("OECOMMAND").Value = 4
OEheader.Process
OEheader.Insert

'Second invoice
OEheader.Order = 0
OEheader.Fields("ORDUNIQ") = 0
OEheader.Init
OEheader.Fields("CUSTOMER").Value = "1500"
OEheader.Fields("PROCESSCMD").PutWithoutVerification 1
OEheader.Process

OEdetail1.RecordCreate 0
OEdetail1.Fields("ITEM").Value = "A11050"
OEdetail1.Fields("PROCESSCMD").PutWithoutVerification 1
OEdetail1.Process
OEdetail1.Fields("QTYORDERED").Value = 1
OEdetail1.Fields("QTYSHIPPED").Value = 1
OEdetail1.Insert

OEheader.Fields("GOCALCTAX").PutWithoutVerification 1
OEheader.Process
OEheader.Fields("INVPRODUCE").Value = 1
'OEheader.Fields("INVNUMBER").Value = "INV1235"
OEheader.Fields("OECOMMAND").Value = 4
OEheader.Process
OEheader.Insert
 
You can try to .cancel the order view after the .insert and therefore clear it before the next .init.

And/or replace the .init with a .recordclear and .recordgenerate.



zemp
 
Ettienne and Zemp, your help is appreciated. I've been on the road all day, so I probably won't be able to try out your solutions until tomorrow.

I wish I had time to really understand the COM API. Right now I just record macros and then fiddle with them until they seem to do what I want.

I would like to understand the proper sequence of methods to call when using a View to add/edit/delete records. The same way I understand an ADO recordset, for example.

Alas I have at least four urgent projects right after this one. Who has time to sit back and just learn these days! :)

Cheers


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top