Error: 0 in Method SETKEYVALUE

Hi Forum,

I am getting an error 0 in Method SETKEYVALUE trying to set the key for Sales Order Lines.

Below is the code i have.  I can read the key of the Sales Order Header but i cannot read the Lines.

'Get Sales Order Header

retVal = o.nSetKeyValue("SalesOrderNo$", strOrderNo)
retHdrKey = o.nFind(strOrderNo)

If retHdrKey = 0 Then
MsgBox(o.sLastErrorMsg & strOrderNo & vbCRLF & "SO Header")
End If

r = o.nGetValue("ARDivisionNo$", sDiv)
r = o.nGetValue("CustomerNo$", CustNo)
r = o.nGetValue("CustomerPONo$", strcustPO)

msgbox "SO #: " & strOrderNo & " Customer #: " & CustNo

'Get Sales Order Detail
retVal = 0
retVal = o.oLines.nSetKeyValue("SalesOrderNo$", strOrderNo) *** here is where i get the error.
retVal = o.oLines.nSetKeyValue("LineKey$", sLine_Key)
retKey = o.oLines.nFind()

If retKey = 0 Then
MsgBox(o.sLastErrorMsg & vbCRLF & "SO Detail")
Else
msgbox "Found SO : " & strOrderNo
End If

I cannot figure out what is wrong.  I copied this code from another script that is working.

What am I missing ?

Any suggestions ?

Regards,

Manuel

Parents Reply Children
  • in reply to Kevin M

    Set oLines = oSession.AsObject(oBusObj.Lines)
    retVal = oLines.MoveFirst()
    do until oLines.EoF 
    	' do stuff…
    	retVal = oLines.MoveNext()
    loop ' oLines

  • in reply to Kevin M

    I've tried,

    retVal = oLines.nMoveFirst()

    and

    retVal = o.oLines.nMoveFirst()

    Same error, now in method MOVEFIRST, below are the objects..

    ' Instantiate a Sales Order business object
    oSEC = oSS.nSetProgram(oSS.nLookupTask("SO_SalesOrder_ui"))
    Set o = oScript.NewObject("SO_SalesOrder_bus", oSS)
    Set oLines = oScript.NewObject("SO_SalesOrder_bus", oSS)
    'Set oLines = o.oLines

    Still nothing,

    Regards,

    Manuel

  • in reply to mroman

    Remove this line completely.

    Set oLines = oScript.NewObject("SO_SalesOrder_bus", oSS)

  • in reply to Kevin M

    Agreed.

    Since this is an external script, it is fine to use o.oLines.* without first setting the Lines property into an object variable.

    As Kevin, jepritch, and I said before, there is no reason to start another instance of the "SO_SalesOrder_bus" object.

  • in reply to David Speck

    I've tried no instance and with instance...

    when i tried this 

    retVal = oLines.nMoveFirst()

    I get a message "Object required: oLines"

    when i try ...

    retVal = o.oLines.nMoveFirst()

    I get ,message "Error: 0 in Method MOVEFIRST

    Regards,

    Manuel

  • in reply to mroman

    We're telling you that creating two instances of SO_SalesOrder_bus isn't going to accomplish what you want.

    As for the object required, you can either use o.oLines or first set o.oLines into another variable.

    Something you are missing is that the header is not filtering the lines automatically for you when using the header's Find method (the filtering of the lines is done automatically if you use SetKey).  If you continue using Find, you need to follow it up with SetCurrentKey which requires the full header key to be passed to it.  You can use GetKeyPadded() to get the full key.  

    I did a little testing with the Lines' SetKeyValue and found that it return zero and the following message in the LastErrorMsg property when used on SalesOrderNo$ and ItemCode$.

    In order to EditLine, SetKey, or Find against a detail record, you need the fully padded key including the LineSeqNo, so for SO_SalesOrderDetail, it should be SalesOrderNo$ + LineSeqNo$ + LineKey$ which you can use the Lines' GetEditKey method for this in which you pass it the LineKey that you are after.  Its returned value can be used with EditLine, SetKey, or Find, however, GetEditKey only works for saved detail records which shouldn't be an issue in this case since this is an external script.

    Now I've attempted to change the index used by the detail object to the "KPRIMARY" index so i would just have to use the padded SalesOrderNo$ + LineKey$ with SetKey or Find but it still didn't like that.

    Short of looping through the lines use MoveFirst, MoveNext with EoF and checking the LineKey, the only other ways that I'm aware of is to use GetResultSets or set the browse filter using the kPrimary index and then set the browse filter to the header key fully padded plus the LineKey (you should be able to check the return value when calling SetBrowseFilter, if a 1, then a record met your filter) and then test the MoveFirst method, if it returns a 1, then it was able to navigate to a record matching your browse filter.

    EDIT: As Elliot pointed out, you cannot change the Lines object's index because it uses a *Memory* instead of the physical table.

  • in reply to David Speck

    What is the primary purpose of your script?  Are you trying to edit the line for which you have a LineKey value?  Are you looking to loop through all the lines for the order?

    The way the line entry paradigm was designed is as such.   Using the business object of the header, in our case SO_SalesOrder_bus.

    1. r = o.SetKey( { order number } ) - this will prepare the order for editting as well as load all the detail lines for the order from the physical detail table and put them into a memory table.  (Btw, David the memory table does not respect changing the indexes).  If you use Find() it will NOT filter the lines, Find is used for read-only functions on the primary table in this case SO_SalesOrderHeader and does not fire off the other components such as SetCurrentKey() that David mentioned.

    2. If you know the line key of the order you are looking for then use the method David mention above.  editKey = o.oLines.sGetEditKey( { line key } )  The reason we need to use this method is the memory table used above has one key and that is the kDISPLAY key, which is order + lineSeqNo + lineKey.  So we need the key in that format to edit it.

    2a. If you receive a value back then the key exists, if that's all you want to know then you're done.  If you want to edit that line, then use r = o.oLines.nEditLine(editKey) or r=o.oLInes.nSetKey(editKey).  The return value will be '1' if line exists and '2' if it does not exist (new line)

    3. To make changes to the values in that line, you use r = o.oLines.nSetValue( {field}, {value})

    4. To write change to the detail line r = o.oLines.nWrite() NOTE: this updates the values in the memory table, this does NOT update the physical table yet.

    5. To commit all change to the physical files, write the header, using  r = o.nWrite()

    If you are looping for some other reason, then use a movefirst(), movenext() approach looking for EOF.

    Hope this helps

    E

  • in reply to jepritch

    Thanks for the reminder about the index against the memory table, I now vaguely recall finding that out a while back while trying something else.

  • in reply to jepritch

    What i need to do is to read the Sales Order Header an Lines to compare the lines in a External shipping file to create invoices in Sage.

    I do not need to update/edit any columns i just want to read the SO tables.

    Regards,

    Manuel

  • in reply to David Speck

    Thanks David, i will give it a try.  Although i am sure i tried that becaus ei have the same code in another script.

    Anyways, I will try and see what happens.  

    Regards,

    Manuel