I have a datatable running in a foreach loop, getting site usage information on multiple sahrepoint websites. I would like to be able to add a column next to each foreach iteration adding the site url, I can only figure out how to do this adding a new row making the site url appear below the entry. Like So:
How can I get the url to go into the row above it?
My code is below:
SPListItemCollection items = list.GetItems(query);
DataTable aggregatedTable = new DataTable();
foreach (SPListItem item in items)
{
string url = item["SiteUrl"].ToString();
try
{
using (SPSite siteadd = new SPSite(url))
using (SPWeb webadd = siteadd.OpenWeb())
{
//
DataTable table = webadd.GetUsageData(Microsoft.SharePoint.Administration.SPUsageReportType.browser, Microsoft.SharePoint.Administration.SPUsagePeriodType.lastMonth);
table.Columns.Add("url");
if (table == null)
{
// HttpContext.Current.Response.Write("Table Null");
}
else
{
DataRow dr;
dr = table.NewRow();
dr["url"] = url;
table.Rows.Add(dr);
// table.Rows.Add(url);
aggregatedTable.Merge(table);//Append the data to previous site data.
}
}
}
catch { }
}
dataGridView1.DataSource = aggregatedTable;//bind datatable with
Why you adding a new row to you existing DataTable rather you should set value to you existing row.
e.g.
var CurRow = table.AsEnumerable().FirstOrDefault();
table.Columns.Add("url");
if (CurRow != null)
{
CurRow["url"] = url;
}
Related
I've retrieved a table from outlook as html body then I've parse it to a datatable but when I run the code, all I get is System.Data.DataRow
static void Main(string[] args)
{
var mails = OutlookEmails.ReadMailItems();
foreach (var mail in mails)
{
StringBuilder builder = new StringBuilder();
builder.Append(mail.EmailBody.ToString());
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(builder.ToString());
var nodes = doc.DocumentNode.SelectNodes("//table//tr");
DataTable dataTable = new DataTable();
var headers = nodes[0]
.Elements("th")
.Select(th => th.InnerText.Trim());
foreach (var header in headers)
{
dataTable.Columns.Add(header);
}
var rows = nodes.Skip(1).Select(tr => tr
.Elements("td")
.Select(td => td.InnerText.Trim())
.ToArray());
foreach (var row in rows)
{
dataTable.Rows.Add(row);
}
Console.WriteLine(dataTable.Rows);
Console.ReadLine();
}
}
Because you are just printing out the type of the object.
What else did you expect?
If you want to print out every column for every row in your dataTable, you must specify it.
Try this:
foreach (DataRow row in dataTable.Rows)
{
Console.WriteLine();
foreach (DataColumn col in dataTable.Columns)
{
Console.Write(row[col] + " ");
}
}
For further information: MS DataTable Docs
I have this project on c# windows forms and what I have to do is get some data from a web service and present them to FastRaport.
I have tried display them on a DataGridView first and then fetching the data from it and it works pretty nice. I can download the file and then it gives me a dialog asking me in what format do I want to save it.
But now the requirement is to not use gridview at all, just a button that would convert directly those data into a PDF file.
Here's my code for displaying the data into DataGridView:
var asd1 = dataGridView1.Columns.Add("DrzavaAng", "DrzavaAng");
var asd2 = dataGridView1.Columns.Add("Valuta", "Valuta");
var asd3 = dataGridView1.Columns.Add("Oznaka", "Oznaka");
var asd4 = dataGridView1.Columns.Add("Nomin", "Nomin");
var asd5 = dataGridView1.Columns.Add("Sreden", "Sreden");
for (var i = 0; i<xmlNodes.Count; i++)
{
var node = xmlNodes[i];
var states = new Class();
states.Valuta = node["Valuta"].InnerText;
states.Oznaka = node["Oznaka"].InnerText;
states.Nomin = node["Nomin"].InnerText;
states.Sreden = node["Sreden"].InnerText;
states.DrzavaAng = node["DrzavaAng"].InnerText;
//var asd = dataGridView1.Columns.Add("1", "1");
_ = dataGridView1.Rows.Add();
dataGridView1.Rows[i].Cells["DrzavaAng"].Value=states.DrzavaAng;
dataGridView1.Rows[i].Cells["Valuta"].Value=states.Valuta;
dataGridView1.Rows[i].Cells["Oznaka"].Value=states.Oznaka;
dataGridView1.Rows[i].Cells["Nomin"].Value=states.Nomin;
dataGridView1.Rows[i].Cells["Sreden"].Value=states.Sreden;
}
Here's the part where I pass the data from GridView to the FastReport "database".
using (Report report = new Report())
{
report.Load(ReportPath);
DataTable dt = new DataTable();
foreach (DataGridViewColumn cl in dataGridView1.Columns)
{
dt.Columns.Add();
}
object[] clvl = new object[dataGridView1.Columns.Count];
foreach (DataGridViewRow row in dataGridView1.Rows)
{
for (int i = 0; i<row.Cells.Count; i++)
{ clvl[i] = row.Cells[i].Value; }
dt.Rows.Add(clvl);
}
DataSet ds = new DataSet();
ds.Tables.Add(dt);
report.Dictionary.RegisterData(ds.Tables[0], "test", true);
report.SetParameterValue("date", dateTimePicker1.Value.ToString("dd.MM.yyyy"));
report.Show();
}
Here's my FastReport file before committing anything:
FastReportImage
And here's the output I get : FastReport output
My question is, how can I make it to fetch the data without the gridview, directly from webservice and load it into a FastReport -> PDF file?
I'm trying to link data from my db (sqlite) to my textboxes, but I don't know exactly how...
Here's what i'm trying:
private void btnUpdate_Click(object sender, EventArgs e)
{
con.Open();
adapter = new SQLiteDataAdapter("SELECT PRECO_PRODUTO FROM INGREDIENTES WHERE NOME_PRODUTO='"+listProdutos.SelectedIndex+"'", con);
adapter.Fill(populate);
List<DataTable> precoIng = new List<DataTable>();
precoIng.Add(populate.Tables[0]);
con.Close();
tbPrecoProduto.Text = precoIng[0]; //error here
}
I think I need a way to convert the SQLiteDataTable to a string? I'm new on db stuffs. This is my table and this is my form design, if helps...
It seems as if you're trying to set the text of the TextBox to a DataTable. This doesn't quite make sense, as the type DataTable isn't the same as a string. You'd first have to extract the data out of your table like that:
var builder = new StringBuilder ();
foreach (var rowObject in precoIng [0].Rows)
{
var row = (DataRow) rowObject;
var id = row ["ID_PRODUTO"].ToString ();
var name = row ["NOME_PRODUTO"].ToString ();
var price = row ["PRECO_PRODUTO"].ToString ();
var count = row ["QNT_PRODUTO"].ToString ();
builder.AppendLine ($"Id: {id}; Name: {name}; Price: {price}; Count: {count}");
}
tbPrecoProduto.Text = builder.ToString ();
You can of course shorten this if you only want for example the price:
var builder = new StringBuilder ();
foreach (var rowObject in precoIng [0].Rows)
{
var row = (DataRow) rowObject;
var price = row ["PRECO_PRODUTO"].ToString ();
builder.AppendLine (price);
}
tbPrecoProduto.Text = builder.ToString ();
And, btw, precoIng[0] will always be the same as populate.Tables[0].
Alternatively you could write an extension method like that:
public static string GetData (this DataTable table)
{
var builder = new StringBuilder ();
foreach (DataRow row in table.Rows)
foreach (DataColumn column in table.Columns)
builder.Append (column.ColumnName).Append (": ").Append (row [column]).Append ("; ");
return builder.ToString ();
}
And then call precoIng[0].GetData() to get the data as a string.
If you want to be able to filter the data to get printed, you could do something like this:
public static string GetData (this DataTable table, List <string> columns = null)
{
var builder = new StringBuilder ();
foreach (DataRow row in table.Rows)
if (columns == null)
foreach (DataColumn column in table.Columns)
builder.Append (column.ColumnName).Append (": ").Append (row [column]).Append ("; ");
else
foreach (var column in columns)
builder.Append (column).Append (": ").Append (row [column]).Append ("; ");
return builder.ToString ();
}
I do however feel as if you don't want the data of your whole table as a string, but rather want the data to certain ids or something. To help you with this, however, I'd need more precise information.
Ok, so it seems as if what you actually want is something like this:
var preco = precoIng.FirstOrDefault ()?.Rows.Cast <DataRow> ().FirstOrDefault ()? ["PRECO_PRODUTO"]?.ToString () ?? "";
I am importing data from csv file, sometimes there are column headers and some times not the customer chooses custom columns(from multiple drop downs)
my problem is I am able to change the columns type and name but when I want to import data row into cloned table it just adds rows but no data with in those rows. If I rename the column to old values it works, let's say column 0 name is 0 if I change that to something else which I need to it won't fill the row below with data but If I change zero to zero again it will any idea:
here is my coding:
#region Manipulate headers
DataTable tblCloned = new DataTable();
tblCloned = tblDataTable.Clone();
int i = 0;
foreach (string item in lstRecord)
{
if (item != "Date")
{
var m = tblDataTable.Columns[i].DataType;
tblCloned.Columns[i].DataType = typeof(System.String);
tblCloned.Columns[i].ColumnName = item;
}
else if(item == "Date")
{
//get the proper date format
//FillDateFormatToColumn(tblCloned);
tblCloned.Columns[i].DataType = typeof(DateTime);
tblCloned.Columns[i].ColumnName = item;
}
i++;
}
tblCloned.AcceptChanges();
foreach (DataRow row in tblDataTable.Rows)
{
tblCloned.ImportRow(row);
}
tblCloned.AcceptChanges();
#endregion
in the second foreach loop when it calls to import data to cloned table it adds empty rows.
After couple of tries I came up with this solution which is working:
foreach (DataRow row in tblDataTable.Rows)
{
int x = 0;
DataRow dr = tblCloned.NewRow();
foreach (DataColumn dt in tblCloned.Columns)
{
dr[x] = row[x];
x++;
}
tblCloned.Rows.Add(dr);
//tblCloned.ImportRow(row);
}
but I will accept Scottie's answer because it is less code after all.
Instead of
foreach (DataRow row in tblDataTable.Rows)
{
tblCloned.ImportRow(row);
}
try
foreach (DataRow row in tblDataTable.Rows)
{
tblCloned.LoadDataRow(row.ItemArray, true);
}
I'm trying to convert a DataRow to a DataTable, but I'm getting errors. I searched and tried all possible solutions, but none worked!
I have a method which accepts a DataTable as its parameter (this DataTable has one row exactly). That method will return some information.
At first, I tried to convert the DataRow to a DataTable using ImportRow(newtable.ImportRow(row)), but newtable is empty afterward. Then, I tried dt.clone(), but this fills the newtable with just everything, which is not what I was after! Actually the exact thing I was after.
private static void BatchFrontSidePrinting(Student St, frmBaseCard frm)
{
DBINFOPACK UserInfo;
DBCARDINFO CardInfo;
DataTable newtable = new DataTable("newtable");
foreach (DataRow row in dt.Rows)
{
try
{
// here, I'm trying to send one DataRow as a DataTable to the GetInfo() method,
// and for the next iteratio , after getting the info I'm removing the row which was just added,
// so that for the next iteration, newdatatable is empty. All of the proceeding actions fail !:(
newtable.ImportRow(row); // doesn't work!
UserInfo = GetInfo(newtable);
newtable.Rows.Remove(row); // doesn't work!
St = UserInfo.STUDENT;
((frmFrontSideCard)frm).Replica = UserInfo.CARDINFO.Replica;
if (UserInfo.CARDINFO.Replica)
{
Loger.Items.Add("Replication !");
}
// print
((frmFrontSideCard)frm).Print = St;
// update
CardInfo = UserInfo.CARDINFO;
CardInfo.SID = UserInfo.STUDENT.ID;
CardInfo.BIMAGE = UserInfo.BIMAGE;
SetInfo(CardInfo);
}
catch (Exception exep)
{
Loger.Items.Add(String.Format("Inside [BatchFrontSidePrinting()] : Student {0} {1}:", St.ID, exep.Message));
}
}
}
foreach (DataRow row in dt.Rows)
{
try
{
DataTable newtable = new DataTable();
newtable = dt.Clone(); // Use Clone method to copy the table structure (Schema).
newtable.ImportRow(row); // Use the ImportRow method to copy from dt table to its clone.
UserInfo = GetInfo(newtable);
catch (Exception exep)
{
//
}
}
var someRow = newTable.NewRow();
someRow[0] = row[0]; // etc
newTable.Rows.Add(someRow);
It looks like you are using newtable as a temporary container to send each row in dt to the GetInfo method. If so, why not change the GetInfo method to take a DataRow rather than a DataTable that contains a single DataRow? Then you can get rid of newtable and not bother with creating and copying DataRows in the first place.
private static void BatchFrontSidePrinting(Student St, frmBaseCard frm)
{
DBINFOPACK UserInfo ;
DBCARDINFO CardInfo;
foreach (DataRow row in dt.Rows)
{
try
{
// just pass the row
UserInfo = GetInfo(row);
// rest of the code as before
St = UserInfo.STUDENT;
((frmFrontSideCard)frm).Replica = UserInfo.CARDINFO.Replica;
if (UserInfo.CARDINFO.Replica)
{
Loger.Items.Add("Replication !");
}
//print
((frmFrontSideCard)frm).Print = St;
//update
CardInfo = UserInfo.CARDINFO;
CardInfo.SID = UserInfo.STUDENT.ID;
CardInfo.BIMAGE = UserInfo.BIMAGE;
SetInfo(CardInfo);
}
catch (Exception exep)
{
Loger.Items.Add(String.Format("Inside [BatchFrontSidePrinting()] : Student {0} {1}:", St.ID, exep.Message));
}