Setting table parameter in BAPI fails - c#

So, this is my first time doing this and sending an structure to a BAPI that was created by someone else, the BAPI works, Ive tried it in SAP, but now, we need our master system to use it.
This is the structure:
The in values has 3 values...
Ok, so I can connect correctly and get the information, but I am getting an error, and I think this is due to the structure being prepared before being sent...
Here is the code:
public string SendASFEmail(string id, string tipo, string correo)
{
string idCompuesto = "0000" + id;
SAPConnection sapConnection = new SAPConnection();
RfcDestination rfcDes = sapConnection.getRfcDestination(sapConnection);
RfcRepository rfcRep = rfcDes.Repository;
IRfcFunction fun = rfcRep.CreateFunction("ZSLCM_UPDATE_EMAIL");
//Create the structure with id, tipo and correo
IRfcTable tablaEntrada = fun.GetTable("T_CORREOS_IN");
//Assign parameters
RfcStructureMetadata stru = rfcRep.GetStructureMetadata("T_CORREOS_IN");
IRfcStructure datos = stru.CreateStructure();
datos.SetValue("ZFKK_FAM", idCompuesto);
datos.SetValue("BPKI", tipo);
datos.SetValue("SMTP_ADDR", correo);
tablaEntrada.Append(datos);
fun.SetValue("T_CORREOS_IN", tablaEntrada);
// RUN
fun.Invoke(rfcDes);
//Success and get the out table which contains the same parameters plus message in column #4
IRfcTable tablaSalida = fun.GetTable("T_CORREOS_OUT");
DataTable dtMessages = GetDataTableFromRFCTable(tablaSalida); //this is to take the out structure and just get the string
string respuesta = dtMessages.Rows[0][3].ToString();
return respuesta;
}
And I keep getting the error:
Additional information: metadata for StructureOnly T_CORREOS_IN not available: NOT_FOUND: No active nametab exists for T_CORREOS_IN

Your problem is in the statement:
RfcStructureMetadata stru = rfcRep.GetStructureMetadata("T_CORREOS_IN");
API function GetStructureMetadata( ) reads SAP repository (!) structure and not parameters of RFC module, hence is the error.
For filling RFC table you need smth like this:
IRfcFunction fn = repo.CreateFunction("ZSLCM_UPDATE_EMAIL");
var correos = fn.GetTable("T_CORREOS_IN");
foreach (ListViewItem lvi in correos.Items)
{
//Create new correos row
correos.Append();
//Populate current row with data from list
correos.SetValue("ZFFK_FAM", lvi.SubItems[0].Text);
correos.SetValue("BKPI", lvi.SubItems[1].Text);
correos.SetValue("SMTP_ADDR", lvi.SubItems[2].Text);
}
Here is the reference answer also with .Net dataTable type sample.
Read official Help about NCo functions.

Related

Why am I obtaining a "string;" text before the value of a SharePoint List field when I retrieve it?

I am pretty new in**.NET** and moreover in SharePoint and I have the following problem working on a SharePoint 2013 project.
Into my code I do:
for (int i = 0; i < eitchettaCorrenteList.Items.Count; i++)
{
string valoreColonnaIniziativaInternalName = eitchettaCorrenteList.Fields[nomeColonna].InternalName;
string valore = eitchettaCorrenteList.Items[i][valoreColonnaIniziativaInternalName].ToString();
}
I am iterating on a SharePoint list named etichettaCorrentList and, for each row, retrieving the value of a specific field.
It works bu the problem is that this line:
string valore = eitchettaCorrenteList.Items[i][valoreColonnaIniziativaInternalName].ToString();
returns a strange value that contains the expected value (the one contained in my list) preceded by a code that is not part of the value of the selected field, something like: string;#S01-INIZIATIVA EUROPA 1 TEST
What is this string;? Why am I retrieving it? How can I correctly remove or not obtain this string; before the desired information? What is wrong? What am I missing?
Use this link.
Here exists answer to your question.
Your field type is SPFieldCalculated.
Use such code:
var item = eitchettaCorrenteList.Items[i];
var field = eitchettaCorrenteList.Fields[nomeColonna];
string valoreColonnaIniziativaInternalName = field.InternalName;
if (field.Type.Equals(SPFieldType.Calculated)) {
}
SPFieldCalculated cf = (SPFieldCalculated)field;
string valore = cf.GetFieldValueForEdit(item[valoreColonnaIniziativaInternalName ]);
// or
// string valore = cf.GetFieldValueAsText(item[valoreColonnaIniziativaInternalName ]);
}
else {
string valore = item[valoreColonnaIniziativaInternalName].ToString();
}
Or may be this will work correctly with all cases:
var item = eitchettaCorrenteList.Items[i];
var field = eitchettaCorrenteList.Fields[nomeColonna];
var value = field.GetFieldValueAsText(item[field.InternalName]);

How to update multiple entities with file import in mvc5

I have a table with user data. I call it 'clients'.
I want to import an excel file where I have more data for them, phone number address etc.
My controller looks like this:
foreach (DataRow row in table.Rows)
{
string email = row["email"].ToString();
Clients clients = db.Clients.Find(email);
var lea = this.db.Clients.Find(email.ToString());
clients.PromoCode = row["AFF"].ToString();
clients.workerId = Convert.ToInt16(row["workersid"]);
clients.Rentetiion = Convert.ToInt16(row["Rentetiion"]);
clients.Contof = row["login"].ToString();
clients.Company = row["Company"].ToString();
clients.Phone = row["Phone"].ToString();
db.Entry(clients).State = EntityState.Modified;
}
db.savechanges
I want to filter by email and update the data on the database, but I get this error:
The argument types 'Edm.Int32' and 'Edm.String' are incompatible for this operation. Near WHERE predicate
Any ideas?

EF - For an already created entity: Cannot insert the value NULL into column 'Id', table 'Languages'; column does not allow nulls

I'm receiving that error when trying to insert a new item but when linking it with an already created(Language) record:
var languageRepository = RepositoryFactory.CreateReadOnly<Language>();
_defaultLanguage = languageRepository.FirstOrDefault(l => l.IsDefault);
(...)
newItem.Images = new List<Image>
{
new Image
{
FileName = filename,
Language = _defaultLanguage
}
};
In this case _defaultLanguage already exists in the database, then I don't know why it is trying to insert it as a new record instead of just linking to the already existent Id.
The content of _defaultLanguage:
Any idea that could help?
CreateReadOnly looks suspicious.
Try changing the below, to a normal extraction.
var languageRepository = RepositoryFactory.CreateReadOnly<Language>();
I believe it Detach(Untracked) the entries extracted.

Is there a way to access the columns in a Dapper FastExpando via string or index?

I am pulling in a Dapper FastExpando object and want to be able to reference the column names dynamically at run time rather than at design/compile time. So I want to be able to do the following:
var testdata = conn.Query("select * from Ride Where RiderNum = 21457");
I want to be able to do the following:
foreach( var row in testdata) {
var Value = row["PropertyA"];
}
I understand that I can do:
var Value = row.PropertyA;
but I can't do that since the name of the property i'm going to need won't be known until runtime.
The answer from this SO Question doesn't work. I still get the same Target Invocation exception. So...
Is there any way to do what I want to do with a Dapper FastExpando?
Sure, it is actually way easier than that:
var sql = "select 1 A, 'two' B";
var row = (IDictionary<string, object>)connection.Query(sql).First();
row["A"].IsEqualTo(1);
row["B"].IsEqualTo("two");
Regarding the portion of the title "or index?" - I needed to access results by index since the column names being returned changed sometimes, so you can use a variation of Sam Saffron's answer like this:
var sql = "select 1, 'two'";
var row = (IDictionary<string, object>)connection.Query(sql).First();
row.Values.ElementAt(0).IsEqualTo(1);
row.Values.ElementAt(1).IsEqualTo("two");
There a simple way to access fields direct below sample
string strConexao = WebConfigurationManager.ConnectionStrings["connection"].ConnectionString;
conexaoBD = new SqlConnection(strConexao);
conexaoBD.Open();
var result = conexaoBD.Query("Select Field1,Field2 from Table").First();
//access field value result.Field1
//access field value result.Field2
if (result.Field1 == "abc"){ dosomething}

Convert DataTable to LINQ: Unable to query multiple fields

Importing a spreadsheet I have filled a DataTable object with that data and returns expected results.
Attempting to put this into a format I can easily query to search for problem records I have done the following
public void Something(DataTable dt)
{
var data = from row in dt.AsEnumerable()
select row["Order"].ToString();
}
Works as expected giving me a list of orders. However I cannot add other fields to this EnumerableRowCollection. Attempting to add other fields as follows gives me an error
public void Something(DataTable dt)
{
// row["Version"] throws an error on me
var data = from row in dt.AsEnumerable()
select row["Order"].ToString(), row["Version"].ToString();
}
Error: "A local variable named 'row' cannot be declared in this scope because it would give a different meaning to 'row' which is already used in a 'child' scope to donate something else"
I'm thinking I need to alias the column name but I'm having no luck. What am I missing here?
It sounds like you're writing a bad select statement. Try the following:
public void Something(DataTable dt)
{
var data = from row in dt.AsEnumerable()
select new {
Order = row["Order"].ToString(),
Something = row["Something"].ToString(),
Customer = row["Customer"].ToString(),
Address = row["Address"].ToString()
};
}
That will create a new collection of Anonymously Typed objects that you can iterate over and use as needed. Keep in mind, though, that you want be able to return data from the function. If you need that functionality, you need to create a concrete type to use (in place of anonymous types).
I think you should use select new like this query for example:
var q = from o in db.Orders
where o.Products.ProductName.StartsWith("Asset") &&
o.PaymentApproved == true
select new { name = o.Contacts.FirstName + " " +
o.Contacts.LastName,
product = o.Products.ProductName,
version = o.Products.Version +
(o.Products.SubVersion * 0.1)
};
You probably want the following.
var data = from row
in dt.AsEnumerable()
select new { Order = row["Order"].ToString(), Version = row["Version"].ToString() };

Categories

Resources