2016 - 2020 First oScript.SetError Method doesn't trigger an error message in Lot/Serial Number Distribution

SOLVED

This UDS is a Column Pre-Validate on QuantityShipped against the SO Sales Order Tier Distribution table at version 2016 Std through 2020 Advanced. The SetError doesn't always trigger the error message, but it does fail (i.e. clear) the distribution number entered. The error message appears in the TraceWindow, but not to the user. The code is simple and an Exit Sub is used immediately afterwards (also tried excluding the Exit Sub to allow a normal exit - same result). I always see the same entry in the TraceWindow "SCRIPT/CallScript - VB Run Error: <<message to user>>" whether or not the message is presented. The following three line script reproduces the problem. If a second SetError is run (with the test script just enter a quantity on the same row) then it will present its message. The behavior repeats on a new row.

retVal = oScript.DebugPrint("About to Test")
retVal = oScript.SetError("Test")

Exit Sub

You may also see the Pre-Validation script run twice in the trace which is another issue.

  • 0

    Any add-ons?

    Is it just the Sales Order Tier Distribution or others like SO Invoice, PO Receipt, IM Transfer, etc?

  • 0 in reply to David Speck

    The SO Invoice Tier Distribution Column Pre-Validation event on QuantityShipped triggers 2 times before the error message is displayed.
    The PO Receipt of Goods Column Pre-Validation event on QuantityReceived triggers 4 times before the error message is displayed.
    The IM Transfer Column Pre-Validation event on TransactionQty triggers 4 times before the error message is displayed.

    The message-less Pre-Validation events trigger immediately after the selecting a Lot Number as if the SetError commands are being triggered because the quantity field is cleared as if done so by the SetError instead of being the amount from the Item's line entry. The SetError error message is received when a quantity is put in the Lot's Distribute field.

  • 0 in reply to connex

    can you filter by the value variable not being equal to zero or use GetValue on the quantity field and then filter it by not being equal to zero?

  • 0 in reply to David Speck

    Adding a line to the script I display the value that is fed into the script and it is always the quantity value from the detail record. I assume that the SetError's are clearing the value before the screen updates. The screen shot below is immediately after selecting a Lot Number in SO Invoice data entry. The Distribute value is zero (clear by the SetError) b/c the "value" on entry shows to have been a "1" with both triggers. If I enter a value at this point I will get the error message with the SetError and the value will be cleared again.

  • 0 in reply to connex

    So what is the end goal?

  • 0 in reply to David Speck

    To validate the lot numbers entered and reject them if they don't pass.

    At this point I'm trying to work around the duplicate Pre-Validation events by ignoring them and the lack of a message (by using MessageBox), but it makes for a confusing (and long) script that I suspect will have to be changed in the near future.

  • +1 in reply to connex
    verified answer

    The tier distribution objects are tricky.

    I tried testing by clearing the line on a post read event script if a certain lot was entered/selected by using the UI objects' BT_RowDel method and the business' object's Delete, Clear, ClearLine, CancelDistribution, ResetLine, etc methods but they all resulted in a message saying the sales order number is required followed by the prompt asking if i want to delete the line because it is not distributed, followed by the distribution window closing on its own and forcefully returning to the Lines tab.  Even trying to use oScript.InvokeButton "BT_RowDel" didn't work.

    I found two ways to prevent the lot number from being saved.

    Method one is by using the following on a post read event script of the tier distribution table.

    LotSerialNo = "" : oBusObj.GetValue "LotSerialNo$", LotSerialNo
    If oBusObj.EditState = 2 Then
    	If LotSerialNo = "200827ABC0103" Then
    		If oScript.UIObj <> 0 Then 
    			oSession.AsObject(oScript.UIObj).SetVar "CMD_STR$", "X _obj'BT_RowDel(); %SYS_SS'UI'MessageBox$("""", """ & """""" & LotSerialNo & """""" & " is not a valid lot number."")"
    		End If
    	End If
    End If

    Method two is by setting up a script on a pre validate event of any available column of the tier distribution table.  Then open CM_ScriptSettings with DFDM, locate the pre validate event you set up and change the column value to LotSerialNo, when prompted to remove the old key, click yes.  Make sure to recompile the business event scripts.  You can now use the oScript.SetError method.  I did notice though that this did stop the repeated events however, the message was not displayed as expected so i ended up having to use MessageBox as well.

    LotSerialNo = "" : oBusObj.GetValue "LotSerialNo$", LotSerialNo
    If LotSerialNo = "200827ABC0103" Then
    	oScript.SetError """" & LotSerialNo & """ is not a valid lot number."
    	oSession.AsObject(oSession.UI).MessageBox "", "" & oScript.GetError()
    End If

  • 0 in reply to David Speck

    So i just observed that the EditState property only appears to be set during the post read event and only during a columns pre validate event when the user enters a value.  If you output it to the trace window, you should see that when the event fires immediately after entering/selecting a lot, when the event is for a column's pre validate, the EditState property is 0.  So this should allow you to filter on that so you can pick up when the user actually keys in a quantity.  This is working for me on the pre validate event of the quantity ordered column in the SO tier distribution table.

    LotSerialNo = "" : oBusObj.GetValue "LotSerialNo$", LotSerialNo
    If oBusObj.EditState = 2 Then
    	If LotSerialNo = "200827ABC0103" Then
    		oScript.SetError """" & LotSerialNo & """ is not a valid lot number."
    	End If
    End If

    You can optionally follow the SetError in the above script by checking if the oScript.UIObj is not equal to zero and use the UI object's BT_RowDel or BT_RowReset methods to clear the lot number from the grid.

    LotSerialNo = "" : oBusObj.GetValue "LotSerialNo$", LotSerialNo
    If oBusObj.EditState = 2 Then
    	If LotSerialNo = "200827ABC0103" Then
    		oScript.SetError """" & LotSerialNo & """ is not a valid lot number."
    		' If oScript.UIObj <> 0 Then oSession.AsObject(oScript.UIObj).BT_RowDel
    		' OR
    		' If oScript.UIObj <> 0 Then oSession.AsObject(oScript.UIObj).BT_RowReset
    	End If
    End If

  • 0 in reply to David Speck

    I'll take method number one! This works well in that one doesn't have to wait until the user enters a number. That is not normally what they would have to do. The number normally auto-populates from the sales order detail quantity if there is enough quantity with the selected Lot Number.

    Two things I find amazing about your suggestions:

    1. How did you learn how to use the SetVar for "CMD_STR$" with "X _obj'BT_RowDel() and then add to that the MessageBox. Where do I sign up for that class?
    2. How do you know when to add the "$" after a field name for a string field using GetValue? I know I've run into issues without it.

    Thank you for your efforts here. I very much appreciate them.

  • 0 in reply to connex
    1. Learned this by reading ProvideX manuals and a whole lot of tinkering.  Basically, if there is a value in the CMD_STR$ variable, nomads will attempt to execute the statement.  The semi colon separate multiple statements much like the colon separates statements in VBScript.  I believe every sage 100 program class uses the locally scoped _obj variable for the class' object handle so in this case, _obj refers to the SO_SalesOrderTierDistribution_UI class.  Another thing about using CMD_STR$ is that the execution of the code appears to be deferred, which makes it great for achieving what you needed since it doesn't execute immediately during the table event script.  When using CMD_STR$, the first character determines how the code is processed, if it is an X, the code is executed, if it is a P, the code is performed, if it is a C, the code is called.  There are a few other characters recognized but there are the three i typically use if i have to resort to this approach.  Also, this only works when setting CMD_STR$ using a UI object's SetVar method, i don't believe i have ever gotten it to work with business object's SetValue or SetValueNoValidate methods.  In other words, the CMD_STR$ variable has to be set in the local scope of the UI object.
    2. I believe you are referring to the fact that i made a typo in the previous script examples in this thread where i was missing the $ suffix for the LotSerialNo field specified in the GetValue methods.  This was an accident and if the field is a string field, you should ALWAYS have the $ suffix to avoid inconsistencies.  I have since corrected all of the examples in this thread.