1

I have a C# console application that connects to a SAP server to get data from some of its tables.

Sometimes this error pops up when I try to copy a value from a field in a SAP table called SOHEADER to a string variable.

Here's the stack trace:

SAP.Middleware.Connector.RfcInvalidParameterException: Table line 0 out of range: table is empty en SAP.Middleware.Connector.RfcTable.get_Item(Int32 lineIndex) en ExportarPedidosSAP.Program.ControlFacturasRemitosNotasCreditos(RfcDestination rfcDest, String& nroerror) en C:\Users\USER\Source\repos\BSCPY\BSCPY\ExportarPedidosSAP\Program.cs:línea 1220 en ExportarPedidosSAP.Program.ConnSAPNotasCreditos() en C:\Users\USER\Source\repos\BSCPY\BSCPY\ExportarPedidosSAP\Program.cs:línea 936

Here is the ControlFacturasRemitosNotasCreditos function:

    static void ControlFacturasRemitosNotasCreditos(RfcDestination rfcDest, out string nroerror)
    {

        Console.WriteLine("**  Controlando remitos... ");
        nroerror = "";

        using (SqlBriefcaseCropScience db = new SqlBriefcaseCropScience())
        {
            using (var transaction = new TransactionScope(TransactionScopeOption.Required,
            new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot }))
            {
                List<NotaCreditoCabecera> lstpedidos = new List<NotaCreditoCabecera>();
                List<NotaCreditoItem> lstItemProducto = new List<NotaCreditoItem>();
                IQueryable<NotaCreditoCabecera> ilstpedidos = null;
                IQueryable<Compania> ilstcompanias = null;
                List<NotaCreditoItem> lstprod = null;
                NotaCreditoItem itProd = null;
                int statuscode = 0;
                decimal FKIMG = 0;
                string ProdCode = "";
                string statusdesc = "";
                string status_doc = "";
                string LEGALNUMBER = "";
                string LEGALNUMBER_DEL = "";
                bool savecabecera = false;
                bool nolegalnumber = false;
                bool itemfacturado = false;
                bool pedidofacturado = false;
                List<string> List_LEGALNUMBER_DEL = new List<string>();
                List<string> List_LEGALNUMBER = new List<string>();

                ilstcompanias = db.Compania;

                DateTime unmes = Helpers.GetCurrentDateTime().AddMonths(1);

                if (ilstcompanias != null)
                {
                    foreach (Compania comp in ilstcompanias.ToList())
                    {
                        ilstpedidos = db.NotaCreditoCabecera.Where(c => c.CodigoCompania == comp.Codigo &&
                            (c.CodigoEstado == 5 || c.CodigoEstado == 11 && (DbFunctions.TruncateTime(c.FechaEstado) <= DbFunctions.TruncateTime(unmes))));

                        if (ilstpedidos != null)
                        {
                            lstpedidos = ilstpedidos.ToList<NotaCreditoCabecera>();
                            if (lstpedidos.Count() > 0)
                            {
                                RfcRepository rfcRep = rfcDest.Repository;
                                var funcionStatus = ConfigurationManager.AppSettings["SAP-RFC-Status"];

                                foreach (NotaCreditoCabecera cabecera in lstpedidos.ToList())
                                {
                                    lstprod = db.NotaCreditoItem.Where(c => c.CodigoCompania == comp.Codigo && c.NroPedido == cabecera.NroPedido).ToList();

                                    IRfcFunction functionStatus = rfcRep.CreateFunction(funcionStatus);
                                    functionStatus.SetValue("SEL_ORDERSTATUS", "X");
                                    functionStatus.SetValue("P_VKORG", cabecera.SalesOrg);
                                    functionStatus.SetValue("P_BRIEFDOC", cabecera.NroPedido);

                                    IRfcTable tableHstatus = functionStatus.GetTable(ConfigurationManager.AppSettings["SAP-TablaH-Status"]);
                                    IRfcTable tableIstatus = functionStatus.GetTable(ConfigurationManager.AppSettings["SAP-TablaI-Status"]);
                                    IRfcTable tablaEstatus = functionStatus.GetTable(ConfigurationManager.AppSettings["SAP-TablaE"]);
                                    functionStatus.Invoke(rfcDest);

                                    status_doc = Convert.ToString(tableHstatus[0].GetValue("GBSTK")).ToUpper();

                                    itemfacturado = false;
                                    pedidofacturado = false;
                                    nolegalnumber = false;

                                    if (tableIstatus.RowCount > 0)
                                    {
                                        for (int e = 0; e < tableIstatus.RowCount; e++)
                                        {
                                            if (Convert.ToString(tableIstatus[e].GetValue("NETWR")) != "")
                                            {
                                                ProdCode = Convert.ToString(tableIstatus[e].GetValue("MATERIAL"));
                                                itProd = lstprod.FirstOrDefault(i => i.CodigoProducto == ProdCode);

                                                if (itProd != null)
                                                {
                                                    //Num Factura
                                                    LEGALNUMBER = Convert.ToString(tableIstatus[e].GetValue("LEGALNUMBER")).Trim();
                                                    if (!String.IsNullOrEmpty(LEGALNUMBER))
                                                    {
                                                        itemfacturado = true;

                                                        //Num Remito
                                                        LEGALNUMBER_DEL = Convert.ToString(tableIstatus[e].GetValue("LEGALNUMBER_DEL")).Trim();

                                                        //Cantidad
                                                        FKIMG = (decimal.TryParse(Convert.ToString(tableIstatus[e].GetValue("FKIMG")), out FKIMG) == true) ?
                                                           Convert.ToDecimal(Convert.ToString(tableIstatus[e].GetValue("FKIMG"))) : 0;

                                                        //Si algun item no esta completamente facturado se considera el pedido no facturado
                                                        if ((LEGALNUMBER != "" && LEGALNUMBER_DEL != "") && (itProd.CantidadDevolucion == Convert.ToDecimal(FKIMG)) && (nolegalnumber == false))
                                                        {
                                                            pedidofacturado = true;
                                                        }
                                                        else
                                                        {
                                                            pedidofacturado = false;
                                                            break;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        nolegalnumber = true;
                                                    }
                                                }
                                            }
                                        }
                                        //statuscode = 0;
                                        //if (itemfacturado == true)
                                        //{
                                        //    if (pedidofacturado == true)
                                        //    {
                                        //        statuscode = 12;
                                        //    }                                                
                                        //}

                                        //if (statuscode > 0)
                                        //{
                                        //    statusdesc = repositorioAdm.CEstado(cabecera.IdTipoOrden, statuscode);
                                        //    int reslog = ALogAutorizacion(db, transaction, cabecera.CodigoCompania,
                                        //        cabecera.SalesOrg, cabecera.CodigoDivision,
                                        //        cabecera.IdTipoOrden, cabecera.TipoOrden,
                                        //        cabecera.NroPedido.ToString(),
                                        //        cabecera.CodigoEstado.ToString(), cabecera.Estado,
                                        //        statuscode.ToString(), statusdesc, "inter", "");

                                        //    cabecera.CodigoEstado = statuscode;
                                        //    cabecera.Estado = statusdesc;
                                        //    cabecera.FechaEstado = Helpers.GetCurrentDateTime();

                                        //    savecabecera = true;

                                        //}
                                    }

                                    //Tabla de Error
                                    if (tablaEstatus.RowCount > 0)
                                    {
                                        //Obtengo el Estado
                                        statuscode = 9;
                                        cabecera.CodigoEstado = statuscode;
                                        statusdesc = repositorioAdm.CEstado(cabecera.IdTipoOrden, statuscode);
                                        cabecera.Estado = statusdesc;
                                        cabecera.FechaEstado = Helpers.GetCurrentDateTime();
                                        savecabecera = true;

                                        int reslog = ALogAutorizacion(db, transaction, cabecera.CodigoCompania,
                                            cabecera.SalesOrg, cabecera.CodigoDivision,
                                            cabecera.IdTipoOrden, cabecera.TipoOrden,
                                            cabecera.NroPedido.ToString(),
                                            cabecera.CodigoEstado.ToString(),
                                            cabecera.Estado,
                                            statuscode.ToString(),
                                            statusdesc, "inter", "");
                                    }
                                }
                            }
                        }
                        if (savecabecera)
                        {
                            db.Configuration.ValidateOnSaveEnabled = false;
                            db.SaveChanges();
                        }

                        transaction.Complete();
                    }
                }


            }
        }
    }

Line 1220 inside ControlFacturasRemitosNotasCreditos:

status_doc = Convert.ToString(tableHstatus[0].GetValue("GBSTK")).ToUpper();

Line 936 inside ConnSAPNotasCreditos that calls the ControlFacturasRemitosNotasCreditos function:

ControlFacturasRemitosNotasCreditos(rfcDest, out nroerror);

Can somebodoy tell me what could be the issue here? Could it be that the field comes empty from the SAP table and if i try to copy it somewhere the whole thing crashes? Is there a safe way to check if the field is null before trying to copy it?

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
FranciscoFJM
  • 119
  • 1
  • 10

1 Answers1

1

in your line

status_doc = Convert.ToString(tableHstatus[0].GetValue("GBSTK")).ToUpper();

you are adressing the IRfcTable tableHstatus with index 0, which means you're trying to read the first entry from that table object. That only works if the table has entries. You should first check whether the table contains any rows and only then continue. After invoking the RFC function, check property RowCount of your IRfcTable.

functionStatus.Invoke(rfcDest);
if (tableHstatus.RowCount > 0) {
    status_doc = Convert.ToString(tableHstatus[0].GetValue("GBSTK")).ToUpper();
}

there's a number of reasons why a RFC function might return an empty table. It could be standard behavior in some cases, or it could be because some query parameter was wrong and no data was found, or because an error occurred in the function. Standard SAP BAPIs usually return a status structure or table (often of type BAPIRETURN or BAPIRET2) that contains additional information about error codes, messages etc.

Dirk Trilsbeek
  • 5,873
  • 2
  • 25
  • 23