UDF week date Calculation using a VB Script

SUGGESTED

Hi, 

I've been working on a VB Script that allows the Date field to auto populate based on a customers lead time and return a valid weekday date. The lead time is established in a separate UDF field were the days are selected from a list-box (field is numeric). i.e Todays Date + 10 day Lead time= valid weekday date.

When validating the script, the system says "Syntax Check Passed" but when i add the field to our SO_Entry Header. It freezes the screen and i receive error 88.

Error 88_Invalid/unknown property name

O/S Error_Illegal assignment: 'Date' (err/ret=2/0)

Program_SY_Maint.pvc

I'm not sure if i missed a table i should be adding this script under other then SO Header... Below is the script 

Date=" "

Lead=0

newDate=(d()+ "UDF_Calc_Days")

d=weekday(Date)

Select Case d

Case 1

document.write("Monday")

Case 2

document.write("Tuesday")

Case 3

document.write("Wednesday")

Case 4

document.write("Thursday")

Case 5

document.write("Friday")

End Select

retVal=oBusObj.GetValue("UDF_Calculated_Date$",Date)

retVal=oBusObj.GetValue("UDF_Calc_Days$",Lead)

retVal=oSession.FormatDate(Date,newDate,"%M/%D/%Y")

newDate=DateAdd("D",Lead,newDate)

newDate=oSession.GetFormattedDate(CStr(newDate))

retVal=oBusObj.SetValue("UDF_Calculated_Date$",newDate)

Any advise would be appreciated, thank you!

Parents
  • +1
    SUGGESTED

    I believe 'Date' is a reserved vbscript method and you're trying to assign a value to it.  Try using a different variable name like 'dt' or something like that.

  • 0 in reply to Justin K

    Thank you for your response! I went through my script and changed 'Date' to dt. i got a syntax check passed when verifying the script.When i added the field back to SO Entry I received Error 88 but this time with "Type Mismatch 'd'. 

    Would that be an error with my weekday script? d=weekday(dt)  

  • 0 in reply to NmZ C.

    What are you trying to do with this line?

    newDate=(d()+ "UDF_Calc_Days")

    You are getting the error because of the d() in the above line, in your statement, d is a variable, not a valid function and so it should not have the () proceeding after it.

    If you are going to get into VBScript, and not just for sage 100, i recommend looking for best practices for VBScript.

    I also recommend getting a decent code editor that has syntax highlighting. I use Notepad++ and VbsEdit, the former is freeware and the latter has a free version that you can evaluate indefinitely. I typically use Notepad++ for write the bulk of the code and then paste it into VbsEdit to reformat the code, this is useful for adding tab indents to certain structures making it easier to read.

    A good resource for getting started with scripting for sage 100 is this document.

    https://www.sagecity.com/support_communities/sage100_erp/f/sage-100-personalization-customization-and-productivity-tools/98736/scripting-helper-documentation

    https://support.na.sage.com/selfservice/viewdocument.do?noCount=true&externalId=43033&sliceId=1&cmd=&ViewedDocsListHelper=com.kanisa.apps.common.BaseViewedDocsListHelperImpl&noCount=true

    You can also use this online resource for documentation on the various objects and their properties and methods. You can substitute the year in the URL with your target year. Expand the Object Reference to drill down into a specific module and object or use the search.

    http://help-sage100.na.sage.com/2019/FLOR/

    Now, back to your script. What is the purpose of the document.write lines? are you wanting to output to a "console" or do you want to display a message to the user? Regardless, those lines are likely going to produce an error as well because there is no inherit document object in a event or button script.

    If you want to output to a "console", your best bet is

    oScript.DebugPrint "Output"

    If you want to display a message, your best bet is 

    oSession.AsObject(oSession.UI).MessageBox "", "Your Message"

    Any time you have a variable that will interact with a sage 100 object's method or property, it is very important that you make sure the variable has first had the intended data type set to the variable. The sage 100 objects are very picky about data types, typically, you will only ever need to worry about numbers, strings, and objects. 

    An important distinction between a event script or button script and an externally executed script is that scripts executed externally must have the proper prefix in the property or method name unlike the internal event or button scripts.

    For example, externally you would have the following.

    nDocumentTotal = 0

    sDefaultWarehouseCode = ""

    Set oMyLinesObj = oBusObj.oLines

    nDocumentTotal = oBusObj.nDocumentTotal

    sDefaultWarehouseCode = oBusObj.sDefaultWarehouseCode 

     

    Now internally, you would have the following.

    nDocumentTotal = 0

    sDefaultWarehouseCode = ""

    Set oMyLinesObj = oSession.AsObject(oBusObj.Lines)

    nDocumentTotal = oBusObj.DocumentTotal

    sDefaultWarehouseCode = oBusObj.DefaultWarehouseCode 

    You'll notice that i also prefix my variable names with a letter to represent their intended data type.

    s for String

    n for Number

    o for Object

    a for Array

    d for Date

    It also does not hurt to have descriptive and informative variable names to indicate the purpose of the variable, it will make troubleshooting down the road far easier when you know what its intended and expected purpose is vs having to scan every line of a script to figure out where, when and what "d" is for. I tend to name the variable exactly the same as the column name.

    In my above examples, i placed the variables being set with their intended values before everything else, which is quite common. You can however reduce the lines by combining the statements onto a single line like this.

    nDocumentTotal = 0 : nDocumentTotal = oBusObj.DocumentTotal

    sSalesOrderNo = "" : oBusObj.GetValue "SalesOrderNo$", sSalesOrderNo

    nFreightAmt = 0 : oBusObj.GetValue "FreightAmt", nFreightAmt

    This always makes sure you have established what the target data is before having the variable interact with a sage 100 property or method.

    Along the lines of distinguishing the data type, any time you use GetValue or SetValue, the first parameter/argument that you pass in is the target column and you specify a numeric column by just passing the column name, a string (and date column since sage 100 stores dates as a string value represented in YYYYMMDD format) by passing the column name with the dollar sign suffix, you can see this illustrated in the three lines above. The second parameter/argument you pass in is the variable that will hold the value retrieved from the target column using GetValue. In the case of SetValue, the second parameter/argument can be literal string or numeric value or variable where the value matches the target column's data type.

    You'll notice that i did not use RetVal in any of my methods, my reason for this is because i do not see any reason to return the value returned by the GetValue methods and VBScript has a funny quirk about calling a method that has more than one parameter/argument and using parenthesis to surround the parameters/arguments so i have gotten into the habit of only using parenthesis surrounding them if i am returning the value returned by the method into a variable and the same data type thing applies when the variable is interacting with a sage 100 object's method.

    For example, GetValue and SetValue return a numeric value that can be evaluated to determine whether the method succeeded (1), failed (0), or triggered a warning (-1). Refer to the Object Reference to determine what data type a method returns.

    In the case of a GetValue, the only reason it would fail would be if you misspelled the column name (including the suffix) so i rarely have a need to evaluate the returned value from it. SetValue and Write on the other hand are examples of methods where you would want to check the returned value and if it isn't 1, then you can check the LastErrorMsg and LastErrorNum properties of the object that called the method.

    Hope this helps.

Reply
  • 0 in reply to NmZ C.

    What are you trying to do with this line?

    newDate=(d()+ "UDF_Calc_Days")

    You are getting the error because of the d() in the above line, in your statement, d is a variable, not a valid function and so it should not have the () proceeding after it.

    If you are going to get into VBScript, and not just for sage 100, i recommend looking for best practices for VBScript.

    I also recommend getting a decent code editor that has syntax highlighting. I use Notepad++ and VbsEdit, the former is freeware and the latter has a free version that you can evaluate indefinitely. I typically use Notepad++ for write the bulk of the code and then paste it into VbsEdit to reformat the code, this is useful for adding tab indents to certain structures making it easier to read.

    A good resource for getting started with scripting for sage 100 is this document.

    https://www.sagecity.com/support_communities/sage100_erp/f/sage-100-personalization-customization-and-productivity-tools/98736/scripting-helper-documentation

    https://support.na.sage.com/selfservice/viewdocument.do?noCount=true&externalId=43033&sliceId=1&cmd=&ViewedDocsListHelper=com.kanisa.apps.common.BaseViewedDocsListHelperImpl&noCount=true

    You can also use this online resource for documentation on the various objects and their properties and methods. You can substitute the year in the URL with your target year. Expand the Object Reference to drill down into a specific module and object or use the search.

    http://help-sage100.na.sage.com/2019/FLOR/

    Now, back to your script. What is the purpose of the document.write lines? are you wanting to output to a "console" or do you want to display a message to the user? Regardless, those lines are likely going to produce an error as well because there is no inherit document object in a event or button script.

    If you want to output to a "console", your best bet is

    oScript.DebugPrint "Output"

    If you want to display a message, your best bet is 

    oSession.AsObject(oSession.UI).MessageBox "", "Your Message"

    Any time you have a variable that will interact with a sage 100 object's method or property, it is very important that you make sure the variable has first had the intended data type set to the variable. The sage 100 objects are very picky about data types, typically, you will only ever need to worry about numbers, strings, and objects. 

    An important distinction between a event script or button script and an externally executed script is that scripts executed externally must have the proper prefix in the property or method name unlike the internal event or button scripts.

    For example, externally you would have the following.

    nDocumentTotal = 0

    sDefaultWarehouseCode = ""

    Set oMyLinesObj = oBusObj.oLines

    nDocumentTotal = oBusObj.nDocumentTotal

    sDefaultWarehouseCode = oBusObj.sDefaultWarehouseCode 

     

    Now internally, you would have the following.

    nDocumentTotal = 0

    sDefaultWarehouseCode = ""

    Set oMyLinesObj = oSession.AsObject(oBusObj.Lines)

    nDocumentTotal = oBusObj.DocumentTotal

    sDefaultWarehouseCode = oBusObj.DefaultWarehouseCode 

    You'll notice that i also prefix my variable names with a letter to represent their intended data type.

    s for String

    n for Number

    o for Object

    a for Array

    d for Date

    It also does not hurt to have descriptive and informative variable names to indicate the purpose of the variable, it will make troubleshooting down the road far easier when you know what its intended and expected purpose is vs having to scan every line of a script to figure out where, when and what "d" is for. I tend to name the variable exactly the same as the column name.

    In my above examples, i placed the variables being set with their intended values before everything else, which is quite common. You can however reduce the lines by combining the statements onto a single line like this.

    nDocumentTotal = 0 : nDocumentTotal = oBusObj.DocumentTotal

    sSalesOrderNo = "" : oBusObj.GetValue "SalesOrderNo$", sSalesOrderNo

    nFreightAmt = 0 : oBusObj.GetValue "FreightAmt", nFreightAmt

    This always makes sure you have established what the target data is before having the variable interact with a sage 100 property or method.

    Along the lines of distinguishing the data type, any time you use GetValue or SetValue, the first parameter/argument that you pass in is the target column and you specify a numeric column by just passing the column name, a string (and date column since sage 100 stores dates as a string value represented in YYYYMMDD format) by passing the column name with the dollar sign suffix, you can see this illustrated in the three lines above. The second parameter/argument you pass in is the variable that will hold the value retrieved from the target column using GetValue. In the case of SetValue, the second parameter/argument can be literal string or numeric value or variable where the value matches the target column's data type.

    You'll notice that i did not use RetVal in any of my methods, my reason for this is because i do not see any reason to return the value returned by the GetValue methods and VBScript has a funny quirk about calling a method that has more than one parameter/argument and using parenthesis to surround the parameters/arguments so i have gotten into the habit of only using parenthesis surrounding them if i am returning the value returned by the method into a variable and the same data type thing applies when the variable is interacting with a sage 100 object's method.

    For example, GetValue and SetValue return a numeric value that can be evaluated to determine whether the method succeeded (1), failed (0), or triggered a warning (-1). Refer to the Object Reference to determine what data type a method returns.

    In the case of a GetValue, the only reason it would fail would be if you misspelled the column name (including the suffix) so i rarely have a need to evaluate the returned value from it. SetValue and Write on the other hand are examples of methods where you would want to check the returned value and if it isn't 1, then you can check the LastErrorMsg and LastErrorNum properties of the object that called the method.

    Hope this helps.

Children
No Data