I want to copy some rows of data table, to another one. I tried this code :
DataTable Result = new DataTable();
for(int i = 5; i < PageSize && i < TransactionDataTable.Rows.Count ; i++)
{
DataRow dr = (DataRow)TransactionDataTable.Rows[i];
Result.ImportRow(dr);
}
string MobileNumber = TransactionDataTable.Rows[0]["MobileRegistration_MobileNumber"].ToString();
string MobileNumber2 = Result.Rows[0]["MobileRegistration_MobileNumber"].ToString();
TransactionDataTable is a dataTable with more than 1000 rows.
in above code, MobileNumber has proper vallue, but MobileNumber2 dosent have.
I got this error in last line ( in assigning MobileNumber2 value) :
Additional information: Column 'MobileRegistration_MobileNumber' does not belong to table .
It seems that the rows didnt copy properly, in Result dataTable.
whats the wrong with this code?
and I tried Result.Rows.Add(dr); instead of Result.ImportRow(dr);
but an exception throw with this information:
This row already belongs to another table.
Thanks for any helping...
You are making new datatable Result without any column. So, make sure you are bringing all columns from the table which you are going to copy.
In your case, you can clone the TransactionDataTable and then import the row.
The updated copy implementation will be like this :
DataTable Result = TransactionDataTable.Clone();
for(int i = 5; i < PageSize && i < TransactionDataTable.Rows.Count ; i++)
{
DataRow dr = (DataRow)TransactionDataTable.Rows[i];
Result.ImportRow(dr);
}
string MobileNumber = TransactionDataTable.Rows[0]["MobileRegistration_MobileNumber"].ToString();
string MobileNumber2 = Result.Rows[0]["MobileRegistration_MobileNumber"].ToString();
Related
I am trying to remove rows from datatable in which a certain cell is empty. I have tried using for loop but to no avail.
for (int i = dtbl.Rows.Count - 1; i >= 0; i--)
{
DataRow dr = dtbl.Rows[i];
if (dr["id"] == null)
dtbl.Rows.Remove(dr);
}
If the cell of ID column is empty, then that row should be deleted.
Any help is appreciated. Thanks in advance.
Change your test to this one.
for (int i = dtbl.Rows.Count - 1; i >= 0; i--)
{
DataRow dr = dtbl.Rows[i];
if (dr.IsNull("id"))
dtbl.Rows.Remove(dr);
}
See docs: DataRow.IsNull
or you can use a check against the special field DbValue.Null
if (dr["id"] == DbNull.Value)
Another approach is this one
for (int i = dtbl.Rows.Count - 1; i >= 0; i--)
{
DataRow dr = dtbl.Rows[i];
if (dr.IsNull("id"))
dr.Delete();
}
dtbl.AcceptChanges();
this last one just marks the row for deletion, but the row remains in the table until you call AcceptChanges. (So this approach is suitable for a foreach loop)
Calling DataRow.Delete is the preferred way to work if you plan to update the real database table at later time (for example when you want your user delete many rows from a bound grid and then make a single update to the database only if the user clicks on a Save button).
You could use linq to select those not null
dtbl = dtbl.AsEnumerable()
.Where(r => r.Field<string>("id") != null)
.CopyToDataTable();
Might need the type, specify that nullable type to compare row.Field<int?>("id").HasValue
I'm using SSIS package to clean and load data from .Xlsx file to SQL Server table.
I have also to highlight cells containing wrong data in .Xlsx file, for this I have to get back column and row indexes based on column name and row id(witch I have in my data spreadsheet). For that I compare each column name from my first spreadsheet (Error_Sheet) with rows of a column that I added in a second spreadsheet and do the same for rows, and if I have the same value of cells I get back the column and row indexes of my data spreadsheet and highlight the cell based on that column and row index. The script worked fine, but after trying to run it from a server I got an Memory exception and also on my workstation where it was working fine before.
I've tried to reduce the range that I'm taking data from : AC1:AC10000 to AC1:AC100, it worked only after the first time compilation, but it keeps throwing exception again.
string strSQLErrorColumns = "Select * From [" + Error_Sheet + "AC1:AC100]";
OleDbConnection cn = new OleDbConnection(strCn);
OleDbDataAdapter objAdapterErrorColumns = new OleDbDataAdapter(strSQLErrorColumns, cn);
System.Data.DataSet dsErrorColumns = new DataSet();
objAdapterErrorColumns.Fill(dsErrorColumns, Error_Sheet);
System.Data.DataTable dtErrorColumns = dsErrorColumns.Tables[Error_Sheet];
dsErrorColumns.Dispose();
objAdapterErrorColumns.Dispose();
foreach (DataColumn ColumnData in dtDataColumns.Columns){
ColumnDataCellsValue = dtDataColumns.Columns[iCntD].ColumnName.ToString();
iCntE = 0;
foreach (DataRow ColumnError in dtErrorColumns.Rows){
ColumnErrorCellsValue = dtErrorColumns.Rows[iCntE].ItemArray[0].ToString();
if (ColumnDataCellsValue.Equals(ColumnErrorCellsValue)){
ColumnIndex = ColumnData.Table.Columns[ColumnDataCellsValue].Ordinal;
iCntE = iCntE + 1;
break;
}
}
iCntD = iCntD + 1;
}
ColumnIndexHCell = ColumnIndex + 1;
RowIndexHCell = RowIndex + 2;
Range rng = xlSheets.Cells[RowIndexHCell, ColumnIndexHCell] as Excel.Range;
rng.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow);
There is any other way to load data in DataTable to get column and row index without using a lot of memory or by using Excel.Range.Cell instead of dataset and DataTable to get Cell value, column and row index from xlsx file please ?
I didn't show the whole code because it's long. Please keep me informed if more information needed.
When trying to read data from an Excel with huge number of Rows, it is better to read data by chunk (in OleDbDataAdapter you can use paging option to achieve that).
int result = 1;
int intPagingIndex = 0;
int intPagingInterval = 1000;
while (result > 0){
result = daGetDataFromSheet.Fill(dsErrorColumns,intPagingIndex, intPagingInterval , Error_Sheet);
System.Data.DataTable dtErrorColumns = dsErrorColumns.Tables[Error_Sheet];
//Implement your logic here
intPagingIndex += intPagingInterval ;
}
This will prevent an OutOfMemory Exception. And no more need to specify a range like AC1:AC10000
References
Paging Through a Query Result
Fill(DataSet, Int32, Int32, String)
I have an existing datatable called _longDataTable containing data. Now, I want to duplicate each row and in each duplicate of the row, I want to set only the value in the SheetCode column according to a value from a different datatable called values, see code below. For example, the values datatable contains 1, 2 and 3, then I want each row of _longDataTable to be duplicated three times and in each of the duplicated rows, I want the Sheet Code column to have values 1, 2 and 3 respectively. My code now looks like below:
foreach (DataRow sheets in _longDataTable.Rows)
{
for(int k = 0; k < number_of_sheets; k++)
{
var newRowSheets = _longDataTable.NewRow();
newRowSheets.ItemArray = sheets.ItemArray;
newRowSheets["SheetCode"] = values.Rows[k]["Sheet Code"];
//add edited row to long datatable
_longDataTable.Rows.Add(newRowSheets);
}
}
However, I get the following error:
Collection was modified; enumeration operation might not execute.
Does anyone know where this error comes from and how to solve my problem?
you get enumeration error because you are iterating through a collection which is changing in the loop(new rows added to it),
as you said in the comment, you get out of memory exception because you are iterating on the _longDataTable, then you add rows to it, the iteration never reach to end and you will get out of memory exception.
I assume this can help you:
//assume _longDataTable has two columns : column1 and SheetCode
var _longDataTable = new DataTable();
var duplicatedData = new DataTable();
duplicatedData.Columns.Add("Column1");
duplicatedData.Columns.Add("SheetCode");
foreach (DataRow sheets in _longDataTable.Rows)
{
for (int k = 0; k < number_of_sheets; k++)
{
var newRowSheets = duplicatedData.NewRow();
newRowSheets.ItemArray = sheets.ItemArray;
newRowSheets["SheetCode"] = values.Rows[k]["Sheet Code"];
newRowSheets["Column1"] = "anything";
//add edited row to long datatable
duplicatedData.Rows.Add(newRowSheets);
}
}
_longDataTable.Merge(duplicatedData);
do not modify _longDataTable, add rows to the temp table (with the same schema) and after the iteration merge two data tables.
How can i read the value from every row of a specific column?
I have a table shown here Table Image, i want to get the model name from the "Model" column and i have a database and "SELECT" query behind depending on the "Model" that is shown, it will show the quantity of the "Model" can someone help me?
here is a sample code of my .cs
foreach (GridViewRow row in gv1.Rows)
{
for(int i = 0; i<gv1.Columns.Count;i++)
{
string model = row.Cells[i].Text;
string quan = row.Cells[3].Text;
string ams = row.Cells[4].Text;
}
}
Note:-
data shown in the table are already in the database.
i have 2 seperate View tables for the Models and the Quantity.
If i understand well what you want it's clearly not the best approach, but i will try to help you.
In my opinion you have to get the quantity value before the display of your dataTable, inside this DataTable, but anyway i think this is the type of code that you requested :
//My dataTable to test , with 3 columns
DataTable dt = new DataTable();
dt.Columns.Add("Model");
dt.Columns.Add("Other");
dt.Columns.Add("QuantityFromDB");
//Add some test data in my dataTable
for(int i=0;i<15;i++)
{
DataRow dr = dt.NewRow();
dr[0] = i*2+"";
dr[1] = "XX data XX";
dt.Rows.Add(dr);
}
//Foreach row in your datatable ( your data )
for(int y=0;y<dt.Rows.Count;y++)
{
//Get the value of the current "Model" Column value
string currentModel = dt.Rows[y]["Model"].ToString();
//make your request in the db to get the quantity
int quantityfromdb = 50; //REQUEST
//Update the value of the QuantityFromDB column for this model row
dt.Rows[y]["QuantityFromDB"] = quantityfromdb;
}
You read the value of a specific row, and edit the value of it's other column.
EDIT :
If you want to work directly on the gridview, you can moove your code in the row_databound event of your gridview.
See doc : https://msdn.microsoft.com/fr-fr/library/system.web.ui.webcontrols.gridview.rowdatabound(v=vs.110).aspx
I have a data table in which if the Addresses match move one of the rows to the top of the data table. I am using the following code but it doesnt work. Any idea how to achieve this. The data in the data table is imported from an excel file. I have tried the same if statement in GridView to highlight the duplicates and that works but I also want to move them to the top because the data has more than 1000 rows and its hard to move up and down again and again to check for the highlighted row.
for (int row = 1; row < dtf1.Rows.Count; row++)
{
for (int rowinner = 1; rowinner < dtf1.Rows.Count; rowinner++)
{
if (rowinner != row)
{
if (dtf1.Rows[row][addresscolno] == dtf1.Rows[rowinner][addresscolno].ToString())
{
DataRow newrow = dtf1.Rows[row];
dtf1.Rows.RemoveAt(row);
dtf1.AcceptChanges();
dtf1.Rows.InsertAt(newrow, 1);
dtf1.AcceptChanges();
GridView1.DataSource = dtf1;
GridView1.DataBind();
}
}
}
}
So you want to reorder the DataTable. The row with a given address should be on the top. You can use Linq-To-DataSet to order the rows and CopyToDataTable to create a new DataTable with the new order:
// assuming the address is a string in a variable address, to simplify matters
DataTable tblOrdered = dtf1.AsEnumerable()
.OrderByDescending(r => r.Field<string>("addresscolno") == address)
.ThenBy(r => r.Field<string>("addresscolno"))
.CopyToDataTable();
Then you can use that as DataSource for your GridView.
Edit: Give also DataTable.Rows.InsertAt a try.
dtf1.Rows.InsertAt(dtf1.Rows[rowinner], 0);