Script for overriding AccountKey in JC Job Posting Entry

SOLVED

v2018 (so scripting in JC is possible).

I'm writing a script to override the GL account for Job Posting Entry lines. (Detail PreWrite event).

I can get the override to work, with a SetValue but the grid does not refresh with the new value.

retSet = oBusObj.SetValue("AccountKey$", sNewAccount,"kACCOUNT")

When I try to use InvokeChange, nothing happens.

retSet = oUIObj.InvokeChange("AccountKey", sNewAccount, "GD_Lines")

LastErrorMessage indicates "The  - is invalid" which doesn't make sense... I can type in the exact same value, so InvokeChange should work (with my assumption that InvokeChange is just supposed to mimic user data entry).

When I InvokeChange on the CommentField, an odd second line is created, which is not what I want at all.  This tells me that oUIObj is created properly, but perhaps something is not right with the row handling?

Any tips?  Is there a way to refresh GD_Lines on this screen so changes made by SetValue are displayed properly?  I know I can drag the field into the secondary grid and everything will be fine, but I'm thinking the customer may not like that too much.

Top Replies

  • +1
    verified answer

    Hello ,

    The problem you are encountering is because InvokeChange() was never really designed to be run from a business object event, it was meant to be run from a button script.  InvokeChange() is using a property called "CurrentRow" to determine which row to change in the grid, the problem is with the script being attached to a Pre-Write event, is the current row in all probability is no longer the row you changed, because the write is usually triggered by exiting the row you changed.  

    You may want to consider only doing this for new lines?  Not sure your use case.

    So you can try the following:

    retVal = oBusObj.SetValue("AccountKey$", sNewAccount, "kACCOUNT")

    ' check for UI
    If (IsObject(oUIObj)) Then
        ' This is either a UI Event Script or a Button link script
        ' – because oUIObj is directly available.
        MASUI = True
    Else
        MASUI = CBool(oScript.UIObj)
        If (MASUI) Then
            Set oUIObj = oSession.AsObject(oScript.UIObj)
        End If
    End If

    ' update the grid if there is a UI
    If MASUI Then
        Set oUIObj = oSession.AsObject(oScript.UIObj)

        chgRow = 0

        ' this is the row that changed, I don't usually recommend retrieving Sage working variables, but you need to in this case
        retVal = oUIObj.GetValue("cChangedRow", chgRow) 

        newAcct = ""

        ' the actual UI variable has been updated by the SetValue() just not re-displayed
        retVal = oUIObj.GetValue("ML_AccountKey$", newAcct)    

        retVal = oUIObj.SetControlProperty("GD_Lines", "Row", chgRow)
        retVal = oUIObj.SetControlProperty("GD_Lines", "Column$", "ML_AccountKey$")
        retVal = oUIObj.SetControlProperty("GD_Lines", "Value$", newAcct)
    End If

    Give this a try, I will make a note, that we really should have a mechanism to refresh an existing row in a grid, or be able to specify the row on the InovkeChange().  I'll add it to my pile.

    Eliott

  • 0 in reply to jepritch

    Kevin,

    You probably should check whether that column is in the primary grid before you try to update it also.  You can do this, thusly:

    gridCtl = 0
    retVal = oUIObj.GetControlProperty("GD_Lines", "Ctl", gridCtl) ' get identifier for the grid

    colInGrid = 0
    colInGrid = oUIObj.IsColumnInGrid(CInt(gridCtl), "ML_AccountKey$")

    If CBool(colInGrid) Then 

    ...

    End if

  • 0 in reply to jepritch

    Thanks  !!!

    Here's what I ended up with (after the SetValue).

    ' update the grid if there is a UI
    If retSet = 1 and CBool(oScript.UIObj) Then
        Set oUIObj = oSession.AsObject(oScript.UIObj)
        chgRow = 0
        ' this is the row that changed, for use below with SetControlProperty
        retVal = oUIObj.GetValue("cChangedRow", chgRow)

        newAcct = ""
        gridCtl = 0
        ' check to be sure the AccountKey column is in the GD_Lines grid
        retVal = oUIObj.GetControlProperty("GD_Lines", "Ctl", gridCtl) ' get identifier for the grid
        colInGrid = 0
        colInGrid = oUIObj.IsColumnInGrid(CInt(gridCtl), "ML_AccountKey$")

        If CBool(colInGrid) Then ' set the value in the grid so if refreshes properly.
            retVal = oUIObj.GetValue("ML_AccountKey$", newAcct)    
            retVal = oUIObj.SetControlProperty("GD_Lines", "Row", chgRow)
            retVal = oUIObj.SetControlProperty("GD_Lines", "Column", "ML_AccountKey$")
            retVal = oUIObj.SetControlProperty("GD_Lines", "Value$", newAcct)

        End if
    End If

    Edit: it is "Column" not "Column$" in the SetControlProperty line.

  • 0 in reply to jepritch

    Eliott,

    I'm working on a script and have a similar (grid data refresh) problem. 

    SO post-write line script to add a discount line. Line A qualifies for a special discount, so Line B is added for that discount.  For the update I am trying to script, if Line B already exists, update the Line B values to align with refreshed calculated quantity and discount unit price.

    The added discount line is linked through a UDF (for the parent linekey), and I have the search loop and SetValue working... but the grid does not show the new values when I update values on Line B.  cChangedRow is the parent line item (Line A), not the discount line (B) I want refreshed, so the method above doesn't work.

    retVal = oUIObj.GetValue("cChangedRow", chgRow)

    How do I find a specific row# in grid data, when I already have the associated oBusObj line open?

  • 0 in reply to Kevin M

    Hey

    The short answer is not easily.  I really need to implement something to "update" a particular row.

    So would it be true to say that Line B would always be Line A + 1?  Or is Line B always a particular item code?

    Elliott

  • 0 in reply to jepritch

    Thanks for the reply Elliott,

    Under most circumstances Line B should be Line A+1 but I can't guarantee that, since there could be multiple different discount lines added per parent line.  The Line B item code is based on a UDT lookup.  (Complicated business logic... different types of discounts get posted to different GL accounts, which is why this is done by script).

    If I wanted to try something like invoking a different tab button (to force the grid refresh a different way), could I set the selected row back to the cChangedRow value after loading the Lines tab again?

  • 0 in reply to Kevin M

    Have you tried just setting the 'LinesAdded = 1 as a trigger?  This should reload the grid I think.  Follow it with a oUIObj.HandleScriptUI()

    That should hopefully, reload your grid.  If not we may have to do something else.

    Then you can use your 'cChangeRow' value or whatever row value you want to set focus back to where you want.

    retVal = oUIObj.GetControlProperty("GD_Lines", "Ctl", gridCtl) ' get identifier for the grid
    retVal = oUIObj.GotoCell(CInt(gridCtl), chgRow, "ItemCode$")

    This should work.

    Let me know how you make out.

    Elliott

  • 0 in reply to jepritch

    LinesAdded works perfectly when adding a line, but does not refresh data for existing lines updated by script.

    I'll try the GoToCell code when I pass some other script hurdles along the way.  Thanks again for your assistance!!!

  • 0 in reply to Kevin M

    retVal = oScript.InvokeButton("fldr.pHeader")
    retVal = oScript.InvokeButton("fldr.pLines")

    This does nothing.  The first line alone forces me to the Header tab, but both together has no effect, so my "plan B" is ineffective too.

    Disappointed

  • 0 in reply to Kevin M

    You could try just re-loading the grid manually, using.

    retVal = oUIObj.GetControlProperty("GD_Lines", "Ctl", gridCtl) ' get identifier for the grid
    retVal = oUIObj.LoadGrid(CInt(gridCtl))

    then resetting your cell focus

    retVal = oUIObj.GotoCell(CInt(gridCtL), row, "ItemCode$")

    Let me know how you make out with this.

    E