In Visual Integrator is there a way to select records within a number of days?

SOLVED

I'm running SAGE 100 v2018 and am trying to create a VI Export job based on historical PO Receipt records within 60 days of the Receipt Date.  I can add a hard-coded date range for the Selection option but I was hoping to find a way to have a specific number of days rather than using an actual date.

  • 0

    When extracting records from Sage 100 it is generally better to pull with an external application such as Access, Excel or Crystal Reports. It gives you greater control and options and even Sage will tell you this.

  • 0 in reply to BigLouie

    I appreciate the suggestion, BigLouie, but I'm trying to accomplish this within VI based on external factors.

  • 0

    First, as BigLouie as said, ODBC is usually the best way to do this, whether through a Crystal Report, Excel, Access, etc but if you must use VI Export, then you may consider the following.

    You can't do this easily using the Export Job Maintenance as is but you can leverage the perform logic option to either dynamically set the select statement using the "On Execution" event or compare each record at the record level using the "Before Write" event.

    If you use the "On Execution" event, you need to overwrite the "cSelectStatement$" variable with a proper statement that can be evaluated against each record and will in turn set the "selected" variable to either a 1 or a 0 which determines whether or not it is export.

    If you use the "Before Write" event, you need to evaluate the record yourself and then set the "selected" variable to a 1 if you want it exported or a 0 if you don't want it exported.

    Take the following VI job for example. 

    With that configuration on the "Select" tab, it produces the following select statement.

    cSelectStatement$="IF UCS(CI_Item01.ItemCode$)=""BOARD-04220-66"" { selected = isTRUE } ELSE { selected = isFALSE }"

    If you don't have anything configured on the "Select" tab, it produces the following select statement.

    cSelectStatement$="selected = isTRUE"

    To set up the perform logic, you click the Perform button on the Configuration tab, select your event, and then provide a relative path to a text file containing your perform logic.  In both examples below, I'm using the same file name but specifying an entry label.  You would omit the entry label by only having the path to the file.  I'm using .pl as the file's extension but you can use .txt.

    ..\CM\Script\TestUDS_Procedures.pl;Change_Export_Criteria

    ..\CM\Script\TestUDS_Procedures.pl;Select_Record

    You only need to use one or the other, not both, if you use "On Execution", you need to escape your double quotes unlike the "Before Write" where you would just use straight ProvideX to specify an IF statement.

    Here is the contents of the file referenced above.  Both will make it so items containing "BOARD" in the item code will be selected.

     Change_Export_Criteria:
     cSelectStatement$="IF POS(UCS(""BOARD"")=UCS(CI_Item01.ItemCode$)) <> 0 { selected = isTRUE } ELSE { selected = isFALSE }"
     EXIT 
     ! 
     Select_Record:
     IF POS(UCS("BOARD")=UCS(CI_Item01.ItemCode$)) <> 0 { selected = isTRUE } ELSE { selected = isFALSE }
     EXIT

    Now, you did say you want to select by date so since Sage 100 stores dates as a string in the YYYYMMDD format, you need to make sure you are selecting them in that manner as well.  You also need to make sure your field name is correct.  Take note of the number that appears in parentheses after the table name on the Data tab.  You need to add that exact number to the field name's variable referenced by your selection criteria.  You can see this in the above code how the ItemCode field is referenced by CI_Item01.ItemCode$.

    I don't exactly understand your selection criteria so I can't give you any guidance at the moment on how exactly to set the selection criteria.

  • 0

    ODBC is absolutely better than VI for exports.  I'll write VBScripts if I have to.

    But... have you tried a runtime prompt on tab 3?

  • 0 in reply to Kevin M

    I currently have that as the option.  However, the idea is to run this as a scheduled task without user input.

  • 0 in reply to Paul Smith - Bretthauer

    If you can write VBScript and use ADO to query the data you need, you can schedule the VBScript file to be ran using Windows Task Scheduler.

    If you want to leverage Crystal Reports to handle the querying and exporting, you can use the samples in this post, https://www.sagecity.com/support_communities/sage100_erp/f/sage-100-business-object-interface/131553/error-attempting-to-open-crystal-reports-via-script/351224#351224, to set up a VBScript file that can run and export a report that has been added to the Sage 100 menu.  This can be scheduled using Windows Task Scheduler as well.

    Another alternative is using PowerShell if available, I believe it had a pretty nice record set to delimited file command.  You should be able to find ODBC samples online.

  • 0 in reply to David Speck

    Thank you for the information, David.  I understand the concept of creating a *.pl file and adding it as a Perform for "On Execution" but I'm not following the details.  My Select criteria is on two data fields:  InvoiceNo and OrderDate, both of which are located in the PO_ReceiptHistoryHeader table.  What I'm trying to do is only select transactions that do not have an invoice number (InvoiceNo = blank) AND transactions with an OrderDate between the current date and 14 days prior to the current date.

    My band-aid is having a User Input for OrderDate.  The selection statement is greater than.  So, whatever the user enters as a date, the system should select any records that don't have an invoice and have an order date greater than the date the user entered.

    Ideally, they would like to have a non-user input that will just go out 14 days so it can be added as a scheduled task.  However, the OrderDate select property doesn't allow for an option such as Greater than 14 days...it's greater than a specific Date.

  • FormerMember
    0 FormerMember

    What are you exporting your 100 data to?

    I have a couple ScriptBasic examples using Its C based ODBC extension module on the OpenSage.org forum that might make this simple and fast for you.

    ScriptBasic uses julian date math which should make your request very simple. Do you want this sent to a CSV file or Excel spreadsheet. I'll see if I can put together a quick example for you. This can run as a standalone .exe with the Windows scheduler

  • +1 in reply to Paul Smith - Bretthauer
    verified answer

    Set up the file to contain the perform logic and add the following to it and then point the VI Export job to it on the "On Execution" perform type.

    cSelectStatement$="IF PO_ReceiptHistoryHeader01.InvoiceNo$ = """" AND PO_ReceiptHistoryHeader01.OrderDate$ >= DTE(JUL(DTE(0)) - 14:""%Y%Mz%Dz"") AND PO_ReceiptHistoryHeader01.OrderDate$ <= DTE(JUL(DTE(0)):""%Y%Mz%Dz"") { selected = isTRUE } ELSE { selected = isFALSE }"

    If the main table selected is not PO_ReceiptHistoryHeader then you need to look on the Data tab and check the number in parenthesis for the PO_ReceiptHistoryHeader table and use that number in place of "01" in the code above.

    The code above is overriding the value in the "cSelectStatement$" variable.  It makes it so it checks that the InvoiceNo$ field is not blank AND the OrderDate is greater than or equal to 14 days prior to the current date AND the OrderDate is less than or equal to the current date.

    The prior date is calculated by using the JUL function to convert the current date string returned by DTE(0) then 14 is substracted from the Julian date value which is then formatted to the Sage 100 date format using the DTE function with the "%Y%Mz%Dz" mask (YYYYMMDD).

    The current date could also be retrieved by the coSession'SystemDate$ property but since I was already using DTE(0), I just decided to place the mask in that function to keep things uniformed.

  • FormerMember
    0 FormerMember in reply to FormerMember

    Strange!

    The following ODBC SQL statement doesn't return any rows.

    SELECT * FROM PO_ReceiptHistoryHeader WHERE InvoiceNo = ''

    This WHERE statement works fine.

    SELECT * FROM PO_ReceiptHistoryHeader WHERE InvoiceNo <> ''

    I'm seeing NULL (undefined) values for blank InvoiceNo columns.

    Can someone else give their ODBC interface a try and see if the ProvideX ODBC driver is returning blank InvoiceNo rows with a WHERE?

    If I try the same statement with  the same table in Postgres SQL, it works as expected. 

    Unfortunately the ProvideX ODBC driver doesn't support the NULL or IS NULL SQL syntax. I tried NOT but it also didn't return any rows.