IM_ItemWarehouse_bus object returns '0' for QuantityOnHand when using ItemCode/WarehouseCode Combination

SOLVED

Hello,

I have used many of the BOI objects without any issues, but when retrieving inventory value with IM_ItemWarehouse_bus, none of the quantity is fetching correctly. It always returns 0 value, I am using ItemCode/WarehouseCode combination to set the lookup. My code snippet is given below.

oSS.InvokeMethod(ref errorLog, "nLogon";
oSS.InvokeMethod(ref errorLog, "nSetUser", new object[] { "XXXXXXXXX", "XXXXXXXXX"});
oSS.InvokeMethod(ref errorLog, "nSetCompany", "XXX");
oSS.InvokeMethod(ref errorLog, "nSetDate", "C/I", DateTime.Now.ToString("SageInputDateFormat".AppSetting()));
oSS.InvokeMethod(ref errorLog, "nSetModule", "C/I";

// Get the Task ID for the IM_Item_ui program
int TaskID = (int)oSS.InvokeMethod(ref errorLog, "nLookupTask", "IM_Item_ui";
oSS.InvokeMethod(ref errorLog, "nSetProgram", TaskID);

int resultVal = 0;
// Creating Item Warehouse business object
using (DispatchObject inventory = new DispatchObject(pvx.InvokeMethod(ref errorLog, "NewObject", "IM_ItemWarehouse_bus", oSS.GetObject())))
{

resultVal = (int)inventory.InvokeMethod(ref errorLog, "nSetKeyValue", "ItemCode$", "TEST001";
resultVal = (int)inventory.InvokeMethod(ref errorLog, "nSetKeyValue", "WarehouseCode$", "000";
resultVal = (int)inventory.InvokeMethod(ref errorLog, "nSetKey";

object[] arr1Results = new object[] { "BINLOCATION$", "" };
resultVal = (int)inventory.InvokeMethodByRef(ref errorLog, "nGetValue", arr1Results);//Giving correct value

object[] arr2Results = new object[] { "QUANTITYONHAND$", "" };
resultVal = (int)inventory.InvokeMethodByRef(ref errorLog, "nGetValue", arr2Results);

object[] arr3Results = new object[] { "TOTALWAREHOUSEVALUE$", "" };
resultVal = (int)inventory.InvokeMethodByRef(ref errorLog, "nGetValue", arr3Results);

....

Except for BINLOCATION and REORDERMETHOD, every other inventory quantities are returned '0'.

  • 0
    SUGGESTED

    Numeric fields do not require the "$" suffix, change 

    object[] arr2Results = new object[] { "QUANTITYONHAND$", "" };
    to 
    object[] arr2Results = new object[] { "QUANTITYONHAND", "" };

  • 0 in reply to David Speck

    Hi David,

    I tried your suggestion but I still do not get any value back. No error.

    In one of the post here, there is a VB example where they used STR() function of ProvideX for numeric fields. I tried that but it doesn't work either. Is there an C# equivalent of it?

    Here is the post: www.sagecity.com/.../advanced-getresultsets

    Sample code:

    using (DispatchObject pvx = new DispatchObject("ProvideX.Script"))
    {
        //Initialize the connection for local sage db
        pvx.InvokeMethod(ref errorLog, "Init", "MAS90Path".AppSetting());
    
        // Create a new Session object and initialize the session
        using (DispatchObject oSS = new DispatchObject(pvx.InvokeMethod(ref errorLog, "NewObject", "SY_Session")))
        {
            // by setting the user, company, date and module
            oSS.InvokeMethod(ref errorLog, "nLogon");
            oSS.InvokeMethod(ref errorLog, "nSetUser", new object[] { "SageUserName".AppSetting(), "SageUserPassword".AppSetting() });
            oSS.InvokeMethod(ref errorLog, "nSetCompany", "CompanyCode".AppSetting());
            oSS.InvokeMethod(ref errorLog, "nSetDate", "C/I", DateTime.Now.ToString("SageInputDateFormat".AppSetting()));
            oSS.InvokeMethod(ref errorLog, "nSetModule", "C/I");
            
            // Get the Task ID for the IM_Item_ui program
            int TaskID = (int)oSS.InvokeMethod(ref errorLog, "nLookupTask", "IM_Item_ui");
            oSS.InvokeMethod(ref errorLog, "nSetProgram", TaskID);
    
    
            // Creating Item Warehouse business object
            using (DispatchObject inventory = new DispatchObject(pvx.InvokeMethod(ref errorLog, "NewObject", "IM_ItemWarehouse_bus", oSS.GetObject())))
            {
            
                // Returns nothing
                object[] arr2Results = new object[] { "QUANTITYONHAND", "" };
                inventory.InvokeMethodByRef(ref errorLog, "nGetValue", arr2Results);
    
                using (TextWriter tw = new StreamWriter(@"C:\Services\Sage100\Logs\ItemQty.txt"))
                {
                    foreach (var s in arr2Results)
                        tw.WriteLine(s);
                }
                
                //define required columns to get the data from sage
                List<string> colsList = new List<string>() { "ITEMCODE$", "BINLOCATION$", "WAREHOUSECODE$", "QUANTITYONHAND" };
    
                object[] getResultSetParams1 = new object[] { string.Join("+\"|\"+", colsList), colsList.First(), "", "", "", "", "" };
    
                // Get Result Set ------------------ THROWS ERROR IF $ suffix is not used.
                var res = (int) inventory.InvokeMethodByRef(ref errorLog, "nGetResultSets", getResultSetParams1);
                
                // ERROR is thrown: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: <Error: 0 in Method GETRESULTSETS>
                
                //Item parsing from sage result set
                List<SageInventoryItem> responseItemList = new List<SageInventoryItem>();
                var itemLines = getResultSetParams1[2].ToString().Trim().Trim('Š').Split('Š').ToList();
                
                // Temporary Raw Inventory Data Save
                using (TextWriter tw = new StreamWriter(@"C:\Services\Sage100\Logs\Inventory.txt"))
                {
                    foreach (String s in itemLines)
                        tw.WriteLine(s);
                }
                
                // Code to parse result.
                
            }
        }
    }

  • 0 in reply to Cityon

    That is a different method entirely.

    I don't quite understand the code syntax you are using but in VBScript, any variables passed to a BOI method that will be used to hold the value returned must have a type set as the default value. VBScript's default type for a new variable is Variant which is not supported by ProvideX which is what the BOI uses. ProvideX expects variables to be either a string or numeric. String variables are identified by the "$" suffix. So in VBScript, to the value from a numeric column, you would use the following.

    nQuantityOnHand = 0
    oIM_ItemWarehouse_Bus.GetValue "QuantityOnHand", nQuantityOnHand

    It looks look you are trying to pass a array to the method to have the value returned in an array element but i don't think that is going to work well. You may have to first declare a numeric variable, pass that to the method and then you can set the value in the variable in your array.

    On another note, is there a specific reason you are using IM_ItemWarehouse_Bus vs IM_ItemWarehouse_Svc? If you are only reading information it is generally recommended to use the SVC objects unless dealing with a Header and Detail table relationship in which case you must use the Header table's BUS object.

  • 0 in reply to David Speck

    Thank you for the quick response. I am giving this a shot at this since OP is gone for the day. I will refer the OP to your post about the usage of Bus vs Svc.

    You suggestion of defining integer variable worked. I am getting the value back now for a single item using the below code. I am going fix the other code to get entire inventory.

     int qty = 0;
     object[] arr2Results = new object[] { "QUANTITYONHAND", qty };
     inventory.InvokeMethodByRef(ref errorLog, "nGetValue", arr2Results);

    Thank you again!

  • +1 in reply to Cityon
    verified answer

    Keep in mind that most numeric fields in sage 100 not of the Integer data type, you should use the Double data type instead to avoid losing numbers to the right of the decimal.

    For object handles, you can use the Long data type if needed.