Strange Behaviour when Setting a Date UDF from Button Script

SOLVED

Hi,

I am setting a Date UDF from a Button Script for the line that currently has the Focus in the GD_Lines. I tried setting through SetValue as well as InvokeChange. With both methods the date shows as YYYYMMDD in the UI until I refresh the grid or move to another tab and come back. I tried stuffing the date as MM/DD/YYYY with InvokeChange, but it doesn't make a difference.

Does anyone have an idea how I can get the UI to properly show the date for the user?

As a workaround: How do I get the focus back to the line I was on after I refresh the grid? Sage puts me on the first line. I tried .LoadKey and .SetKey on oLines, but that doesn't change the focus in the UI.

Best,

B.

  • 0

    Working As Designed. This was discussed in a session of Custom Office a few years ago at the Sage Summit. No work around.

  • 0

    Odd, InvokeChange usually works to make sure the UI stays in sync and looks correct. 

    You could try using the ui object's ShowRow method but you have to know the row number you are on which depending on the script event, it could be tricky. If you are using any of the column level validation events, you should be able to check if oScript.UIObj <> 0, if it is not equal to zero, then set it as an object handle and first use GetControlProperty "GD_Lines", "Ctl", variable1, then make sure to check that the variable's value is numeric and if it is, use CLng on it.  Then repeat it but change the second argument to CurrentRow, like this, GetControlProperty "GD_Lines", "CurrentRow", variable2.  Again, check that it is numeric and if it is, use CLng on it. 

    You can then use ShowRow variable1, variable2

    If oScript.UIObj > 0 Then
    	Set oUIObject = oSession.AsObject(oScript.UIObj)
    	oUIObject.InvokeChange "YourField$", "20201228", "GD_Lines"
    	nGD_Lines_Ctl = 0 : oUIObject.GetControlProperty "GD_Lines", "Ctl", nGD_Lines_Ctl : If IsNumeric(nGD_Lines_Ctl) Then nGD_Lines_Ctl = CLng(nGD_Lines_Ctl) Else nGD_Lines_Ctl = 0
    	nGD_Lines_CurrentRow = 0 : oUIObject.GetControlProperty "GD_Lines", "CurrentRow", nGD_Lines_CurrentRow : If IsNumeric(nGD_Lines_CurrentRow) Then nGD_Lines_CurrentRow = CLng(nGD_Lines_CurrentRow) Else nGD_Lines_CurrentRow = 0
    	If nGD_Lines_Ctl <> 0 And nGD_Lines_CurrentRow > 0 Then oUIObject.ShowRow nGD_Lines_Ctl, nGD_Lines_CurrentRow
    	Set oUIObject = Nothing
    End If

    If that doesn't work and you are forced to reload the grid and want to go back to the row you were on, you still need to do both GetControlProperty steps to get the Ctl value of the primary grid and the current row of it but you will instead follow them with SetVar "cSelectedLine", variable2 followed by SetStartingRow variable1

    If oScript.UIObj > 0 Then
    	Set oUIObject = oSession.AsObject(oScript.UIObj)
    	oUIObject.InvokeChange "YourField$", "20201228", "GD_Lines"
    	nGD_Lines_Ctl = 0 : oUIObject.GetControlProperty "GD_Lines", "Ctl", nGD_Lines_Ctl : If IsNumeric(nGD_Lines_Ctl) Then nGD_Lines_Ctl = CLng(nGD_Lines_Ctl) Else nGD_Lines_Ctl = 0
    	nGD_Lines_CurrentRow = 0 : oUIObject.GetControlProperty "GD_Lines", "CurrentRow", nGD_Lines_CurrentRow : If IsNumeric(nGD_Lines_CurrentRow) Then nGD_Lines_CurrentRow = CLng(nGD_Lines_CurrentRow) Else nGD_Lines_CurrentRow = 0
    	If nGD_Lines_Ctl <> 0 And nGD_Lines_CurrentRow > 0 Then 
    		oUIObject.SetVar "cSelectedLine", nGD_Lines_CurrentRow
    		oUIObject.SetStartingRow nGD_Lines_Ctl
    	End If
    	Set oUIObject = Nothing
    End If

    You could also try the GoToRow method.

    If oScript.UIObj > 0 Then
    	Set oUIObject = oSession.AsObject(oScript.UIObj)
    	oUIObject.InvokeChange "YourField$", "20201228", "GD_Lines"
    	nGD_Lines_Ctl = 0 : oUIObject.GetControlProperty "GD_Lines", "Ctl", nGD_Lines_Ctl : If IsNumeric(nGD_Lines_Ctl) Then nGD_Lines_Ctl = CLng(nGD_Lines_Ctl) Else nGD_Lines_Ctl = 0
    	nGD_Lines_CurrentRow = 0 : oUIObject.GetControlProperty "GD_Lines", "CurrentRow", nGD_Lines_CurrentRow : If IsNumeric(nGD_Lines_CurrentRow) Then nGD_Lines_CurrentRow = CLng(nGD_Lines_CurrentRow) Else nGD_Lines_CurrentRow = 0
    	If nGD_Lines_Ctl <> 0 And nGD_Lines_CurrentRow > 0 Then 
    		oUIObject.GoToRow nGD_Lines_Ctl, nGD_Lines_CurrentRow
    	End If
    	Set oUIObject = Nothing
    End If

  • +1 in reply to David Speck
    verified answer

    So i tested myself and found that ShowRow by itself doesn't accomplish what you need however, using ShowRow before FormatRow does so the following worked for me.

    If oScript.UIObj > 0 Then
    	Set oUIObject = oSession.AsObject(oScript.UIObj)
    	oUIObject.InvokeChange "PromiseDate$", "20201228", "GD_Lines"
    	nGD_Lines_Ctl = 0 : oUIObject.GetControlProperty "GD_Lines", "Ctl", nGD_Lines_Ctl : If IsNumeric(nGD_Lines_Ctl) Then nGD_Lines_Ctl = CLng(nGD_Lines_Ctl) Else nGD_Lines_Ctl = 0
    	nGD_Lines_CurrentRow = 0 : oUIObject.GetControlProperty "GD_Lines", "CurrentRow", nGD_Lines_CurrentRow : If IsNumeric(nGD_Lines_CurrentRow) Then nGD_Lines_CurrentRow = CLng(nGD_Lines_CurrentRow) Else nGD_Lines_CurrentRow = 0
    	If nGD_Lines_Ctl <> 0 And nGD_Lines_CurrentRow > 0 Then 
    		oUIObject.ShowRow nGD_Lines_Ctl, nGD_Lines_CurrentRow
    		oUIObject.FormatRow nGD_Lines_Ctl, nGD_Lines_CurrentRow
    	End If
    	Set oUIObject = Nothing
    End If

  • 0 in reply to David Speck

    David, 

    That is amazing. Thank you so much. I just tried it, and it works like a charm. You have a few of your code lines in one line, that might be hard to read for some. Here is my working example with the code lines broken down (it is the same code that David provided, just differently formatted and with my own InvokeChange line in place.

    If oScript.UIObj > 0 Then
    	Set oUIObject = oSession.AsObject(oScript.UIObj)
    	oUIObject.InvokeChange "UDF_Last_Date$", sLastPurchaseDate, "GD_Lines"
    	nGD_Lines_Ctl = 0
    	oUIObject.GetControlProperty "GD_Lines", "Ctl", nGD_Lines_Ctl
    
    	If IsNumeric(nGD_Lines_Ctl) Then
    		nGD_Lines_Ctl = CLng(nGD_Lines_Ctl)
    	Else
    		nGD_Lines_Ctl = 0
    	End If
    
    	nGD_Lines_CurrentRow = 0
    	oUIObject.GetControlProperty "GD_Lines", "CurrentRow", nGD_Lines_CurrentRow
    
    	If IsNumeric(nGD_Lines_CurrentRow) Then
    		nGD_Lines_CurrentRow = CLng(nGD_Lines_CurrentRow)
    	Else	
    		nGD_Lines_CurrentRow = 0
    	End If
    
    	If nGD_Lines_Ctl <> 0 And nGD_Lines_CurrentRow > 0 Then
    		oUIObject.ShowRow nGD_Lines_Ctl, nGD_Lines_CurrentRow
    		oUIObject.FormatRow nGD_Lines_Ctl, nGD_Lines_CurrentRow
    	End If
    
    	Set oUIObject = Nothing
    
    End If

  • 0 in reply to BigLouie

    BigLouie, thanks for the reply. David's response below works in case you need it for anything.

    Did they mention at Sage Summit why it would be designed like this?

  • 0 in reply to BillyVanilli

    i don't think the current "design" resulting in the behavior we are seeing is intentional, perhaps it is more likely an oversight.

  • 0 in reply to BillyVanilli

    I combine my variable initializations with the method they are used for on the same line to be sure that the target variable is properly initialized for the method. Since it is important that the variable type is correct when passed to the ShowRow and FormatRow methods, i also combine the necessary conversions on the same line just to be sure everything related to that variable is exactly the way i need it. Doing so also condenses the code quite a bit. Not really a big deal with small scripts like this but i guess i just got used to doing it that way.

  • 0 in reply to BillyVanilli

    At the Sage Summit in the Custom Office class it was pointed out that is you use a UDF with a date field then the format will be different and you would need to go to the totals tab and then back to the lines tab to show up correctly. They demoed this as a way of explaining to everyone that while the format looked different the underlying data was the same. They didn't explain why it was like that.  No one treated it as anything earthshaking.