I'm trying to get the total number of columns so that i can set my range from column C to N column. I'm trying to go through each column and pull out the data i need into an array until i reach the last column with data in it.
I tried the below which works for one row, but none of the others i have.
IRange strategyname = foratworkbook.Worksheets["Strategy"].Cells["C4"].CurrentRegion;
C D E
9.040% 10.910% 6.050%
4.920% 5.510% 3.430%
53.030% 64.400% 36.030%
Any Ideas?
Thanks
If you know the maximum size of the array you can pull the entire table A:N x row nums into C# as a DataTable, find the first null column and first null row and then remove the columns and rows that are null from that DataTable. That is a reasonably quick and straightforward procedure.
These functions should return the first null row and column in a datatable
public static int findNullRow(DataTable dt)
{
int row = 0;
for (int a = 0; a < dt.Rows.Count; a++)
{
if (dt.Rows[a][0] == null)
{
row = a;
break;
}
}
return row;
}
public static int findNullColumn(DataTable dt)
{
int col = 0;
for (int i = 0; i < dt.Columns.Count; i++)
{
if (dt.Rows[0][i] == null)
{
col = i;
break;
}
}
return col;
}
The alternative is work iteratively across the first row of the spreadsheet pulling out the individual cell values and testing to find the first null column. Do the same for the first column of data until you find the first null row.
My feeling is that the first method would be quicker unless the potential number of rows is very large.
Following links will Help You for reading the data up to last edited range.
SpreadSheetGear - read unique values from Excel column
and
Get the number of rows of data with SpreadSheetGear?
Related
I can't figure out how to solve this. I want to calculate in datagridview
Column 3 like this
using C#
Check this
int sum = 0;
for(int i=0;i<dataGridView1.Rows.Count;i++)
{
sum += Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value);
}
MessageBox.Show(sum.ToString());
To calculate values from you datagridview, you can do several approaches
For example, you can retrieve by rows then reference the column of the cell by index or column name.
For example, adding values in "Column 3" would be:
var rows = dataGridView1.rows;
double sum = 0;
foreach (DataGridViewRow row in rows)
{
sum += (double)row.Cells["Column 3"].Value;
}
EDIT:
If you're using DataTable (which I presume from your comments) to get individual cell data, you can either reference the row first then adding an index based on the column, or you can create a temp row, then get the value using the column. The records or values within a DataTable are basically just collection of rows.
Example:
int col3 = workTable.Columns.IndexOf("Column 3") -1;
double amount = Convert.ToDouble(workTable.Rows[1][col3]); // 1st value in column 3
OR (extended for clarity)
DataRow row1 = workTable.Rows[1];
double amount = Convert.ToDouble(row1[col3]);
If you need to transpose values into a DataGridView, you can just set the DataSource property of a DataGridView instance i.e.
dataGridView1.DataSource = newFilledTable;
I am a newbie in C# so I don't know if I will address my problem correctly so please bear with me.
I have a dataGridView named dgvShowAllData which has a data source coming from my sqlServer. there are a column named Price.
I want to add a new row at the end of the rows in my dataGridView to show the total of the Price column values.
I've tried multiple solutions and got several errors.
I have found a solution that the sum will execute from the sqlServer.
like below,
Select Sum(Price) from tblProduct
but I got stuck there too. I don't exactly know how to execute two data source in a dataGridview.
Please show me a better way so than I can get the total at the very end of my dataGridView.
use a data table as a data source for your DataGridView. Then add a data row to your data table, Data Table has a compute function.
An example of how I would work this around;
DataTable dt;
dt = yourDataSource; //add your data source to the Data Table
DataRow dr = dt.NewRow();
dr("Price") = dt.Compute("Sum(Price)", "");
dt.Rows.Add(dr);
dgvShowAllData.DataSource = dt;
In your code, create a custom footer row for your dataGridView and populate total value in element within footer row.
Ngengis' solution worked for my implementation. My app does not know the name, type, or number of columns in advance, so I needed to tweak it a bit. I made use of an extension method (by Dmytrii Nagirniak) to check that a DataColumn.DataType is numeric:
public static bool IsNumeric(this DataColumn col)
{
if (col == null)
return false;
var numericTypes = new[] { typeof(Byte), typeof(Decimal), typeof(Double), typeof(Int16), typeof(Int32), typeof(Int64), typeof(SByte), typeof(Single), typeof(UInt16), typeof(UInt32), typeof(UInt64)};
return numericTypes.Contains(col.DataType);
}
And I used a loop to create the total row. I needed to catch a SyntaxErrorException in case the column name didn't work with the Compute() method (aggregated columns with parenthesis in them fail; using a column alias fixes that problem)
//Total Row
if (MakeTotalRow == true)
{
DataRow dr = dt.NewRow();
for (int j = 0; j < dt.Columns.Count; j++)
{
var colName = dt.Columns[j].ColumnName;
if (dt.Columns[j].IsNumeric()) //ensure column data can be summed
{
try
{
dr[j] = dt.Compute("Sum(" + colName + ")", "");
}
catch (SyntaxErrorException e)
{
//possible syntax error in the column name
}
}
}
dt.Rows.Add(dr);
}
At the first you must use LINQ entityframework and then:
You should test these code it`s will you handle, for example, your field in database named by 'Price', so try :
step by step ,
1.Make A List<> from your Database :
List<Database.tblProduct> Lst=new List<Database.tblProduct>;
So you Could Use Query From C#,
Textblock.text=lst.Where(w=>w.PriceId==1).sum(w=>w.Price).tostring("#,##");
it Could Help you.
I have a method to save each row in a datagridview into the database, but I want to remove each row if it gets saved. I have this method:
public static void SaveMajEq(MajorEquipment_CreateView CView)
{
rowCount = 0;
// For each cell in the DataGrid, stores the information in a string.
for (rows = 0; rows < CView.dgvCreate.Rows.Count; rows++)
{
if (CView.dgvCreate.Rows[rows].Cells[col].Value != null)
{
// Creates a model, then populates each field from the cells in the table.
MeModel = new MajorEquipment_Model();
MeModel.EquipmentNumber = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[0].Value);
MeModel.EquipmentType = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[1].Value);
MeModel.Location = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[2].Value);
MeModel.Notes = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[3].Value);
Database_Facade.Operation_Switch(OPWRITE);
}
CView.dgvCreate.Rows.RemoveAt(rows);
}
MessageBox.Show(rowCount + " Entries stored in database.");
}
rowCount gets incremented in a try/catch method in a separate class, so if anything occurs, it wont be incremented. What I want to do is only implement this line:
CView.dgvCreate.Rows.RemoveAt(rows);
only if rowCount is incremented each time. I'm not sure how to implement this.
Revert the loop order
for (rows = CView.dgvCreate.Rows.Count - 1; rows >= 0 ; rows--)
Looping backward allow to remove the row processed by the loop without affecting the index of the next row to process.
I have a function which will return multiple ItemIDs as
for (int i = 0; i < dt.Rows.Count; i++)
{
ItemID = int.Parse(dt.Rows[i]["item_Id"].ToString());
dtAtlr = prodctsDCCls.getItemIds(ItemID);
//dtItems = dtAtlr.Copy();
}
I want to keep on searching for all ItemIds from the same table and have to save all the data in one datatable.If I copy one datatable to another datatable, that is replacing the previous datatable. but I need all the data. Please anybody help me
Use DataTable.Merge to merge two data tables. So your code would be:
for (int i = 0; i < dt.Rows.Count; i++)
{
ItemID = int.Parse(dt.Rows[i]["item_Id"].ToString());
dtAtlr.Merge(prodctsDCCls.getItemIds(ItemID)); // For Merging
}
By using DataTable.Copy, your datatable dtAtlr will have the last returned DataTable against the ItemID
You can check DataTable.Merge
Merge the specified DataTable with the current DataTable.
I originally had a code segment that iterated through rows of an Excel spreadsheet using the UsedRange as such:
range = ws.UsedRange;
for (int row = 3; row <= range.Rows.Count; row++)
{
Object nObj = ((Excel.Range)ws.Cells[row, "N"]).Text;
}
But I needed to only get the rows that remained after I applied a filter so (after viewing How can I get the Range of filtered rows using Excel Interop?) I changed the code as such:
range = ws.UsedRange.SpecialCells(Excel.XlCellType.xlCellTypeVisible, Type.Missing);
foreach (Excel.Range area in range.Areas)
{
foreach (Excel.Range row in area.Rows)
//for (int row = 3; row <= range.Rows.Count; row++)
{
Object nObj = ((Excel.Range)ws.Cells[row, "N"]).Text;
}
}
Except now I'm getting type mismatch errors. What fundamental thing am I missing here?
I believe you are getting a type mismatch at the call to ws.Cells[row, "N"]. In the original code, row is an int. In the modified code, row is an Excel.Range.
Given that, in the modified code, row is a single row (multiple column) range, all you should need to do is index into the cell in that row which corresponds to column N. Assuming your range starts in column A, this will be the cell in 14th column.
E.g.
Object nObj = ((Excel.Range)row.Cells[1, 14]).Text;