I have the following code:
Excel.Range range = workSheet.UsedRange;
for (rowCount = 2; rowCount <= range.Rows.Count; rowCount++)
{
//Do something here
}
However, I encounter the following problem. If I have the following excel data:
cell1, cell2, cell3
cell4, cell5, cell6
..............cell7
range.Rows.Count will return 3. However, I don't care about column C - it has some data that is used for drop-down lists within say column 1. How can I get the range.Rows.Count only for columns A and B?
For example:
Assuming there are no blanks in column A, just walk down rows until you hit a blank row using range.Offset(x,y): (sorry, I'm more fluent with Excel VBA, you'll have to translate to C#)
Dim myCell as Range
set myCell = workSheet.Range("A2");
Do Until myCell.Formula = ""
'Do something here
set myCell = myCell.Offset(1,0) 'Moves down a row
Loop
Or just loop through numerically using Worksheet.Cells(row,col):
Dim myRow as Integer
myRow = 2
Do Until cells(myrow,2).Formula = ""
'Do something here
myRow = myRow + 1
Loop
Edit: You could also use Range("A1").End(xlDown) to find the last populated cell of the first column. This should work with your current logic. Something like (I'll try it in C#):
Excel.Range range = workSheet.Range("A1", Range("A1").End(xlDown));
for (rowCount = 2; rowCount <= range.Rows.Count; rowCount++)
{
//Do something here
}
Related
As you can see in the picture, ShiftLeaders row is merged, however, from the 4th to 7th row the values are dynamic(If there are more data more rows will be filled). Because of that, I can't be sure what row to assign on setters and merge those two rows. The current way is displaying the table correctly, the problem is with setters and operators rows which can't be merged. Any help is appreciated!
Shift Leaders is ok:
ws.Cells["A3:C3"].Value = "Shift Leaders";
ws.Cells["A3:C3"].Merge = true;
Setters row is not merging:
ws.Cells[largestLeaders + 4, 2].Value = "Setters";
ws.Cells[largestLeaders + 4, 2].Merge = true;
As well as Operators row:
ws.Cells[largestSetters + 4 + largestLeaders + 2, 2].Value = "Operators";
ws.Cells[largestSetters + 4 + largestLeaders + 2, 2].Merge = true;
it looks like you are using single cell instead of cell range. try with range:
int n = largestLeaders + 4;
string range = $"A{n}:C{n}";
ws.Cells[range].Value = "Setters";
ws.Cells[range].Merge = true;
I have a certain Range, for example:
Range rng = activeWorksheet.Range["A1", "B50"];
I've been retrieving the maximum row and column number used in this Range by looping through it and assigning a row number to my variable, but there must be a better way? I've been doing this:
int maxRow = 0;
foreach (Range row in rng.Rows)
maxRow = row.Row;
I think I found the most elegant solution for this, something like this:
int maxRow = rng.Row + rng.Rows.Count - 1;
int maxColumn = rng.Column + rng.Columns.Count - 1;
rng.Row will retrieve the first used row number in the range, rng.Rows.Count - 1 will retrieve the total amount of rows used in this range and we also deduct 1 to get the correct maximum row number.
How about you search for the last used Row?
public int FindLastFilledRowInRange(Range range)
{
var cell = range.Find("*", SearchOrder: Excel.XlSearchOrder.xlByRows, SearchDirection: Excel.XlSearchDirection.xlPrevious);
return cell.Row;
}
If you start later than row 1 you can just do some additional math on the returned row...
If you don't mind evaluating the string Address...
by using ".EntireRow.Address(False, False)" we get a string that's easily parsed...
C#...
int maxRow = range.EntireRow.Address(false, false).Split(",:".ToCharArray()).Select(n => int.Parse(n)).Max();
string maxCol = range.EntireColumn.Address(false, false).Split(",:".ToCharArray()).Select(s => s.PadLeft(3)).Max().Trim();
VB... ;
Dim maxRow As Integer = -1
Dim maxCol As String = ""
range = ws.Range("$BB9:$C11")
maxRow = range.EntireRow.Address(False, False).Split(",:".ToCharArray()).Select(Function(n) Integer.Parse(n)).Max() ' 9:11
maxCol = range.EntireColumn.Address(False, False).Split(",:".ToCharArray()).Select(Function(s) s.PadLeft(3)).Max().Trim() ' C:BB
given range BB9:C11
maxRow is 11 from 9:11 ...if not parsed to int, then the Max() would be 9 due to string sorting
maxCol is "BB" from C:BB ...if not padded left, then the Max() would be "C" due to string sorting
range = ws.Range("A1:A3,AE15:AE9,C4:C7")
maxRow = range.EntireRow.Address(False, False).Split(",:".ToCharArray()).Select(Function(n) Integer.Parse(n)).Max() ' 1:3,9:15,4:7
maxCol = range.EntireColumn.Address(False, False).Split(",:".ToCharArray()).Select(Function(s) s.PadLeft(3)).Max().Trim() ' 1:3,9:15,4:7
and given range non-contiguous range: A1:A3,AE15:AE9,C4:C7
maxRow is 15 from 1:3,9:15,4:7 ...even with non-contiguous range, and referenced out of order= AE15:AE9
maxCol is "AE" from C:AE ...even with non-contiguous range
this DOES work with whole COLUMN selection "A:A"
this does NOT work with whole row selection "3:3"
I had this on a previous project:
wb = excel.Workbooks.Open(fileName);
worksheet = wb.ActiveSheet;
Range usedRange = worksheet.UsedRange;
this.lastRow = usedRange.Rows.Count;
this.lastCell = usedRange.Columns.Count;
Using lastRow will give you the emptylines which in my case we not useful.
I need to implement this equation:
In c# it is pretty straightforward:
static double LogarithmicSummed(IReadOnlyList<double> values)
{
double outVal = 0;
for (int i = 0; i < values.Count; i++)
{
outVal = outVal + Math.Pow(10, values[i] / 10);
}
return 10 * Math.Log10(outVal);
}
I need to verify the data in an excel sheet where I print out the data programmatically. That is the raw data, my c# calculations on the raw data AND the excel formual that should match my c# calculations. I just do not know how to write the formula in excel.
I know the rows and columns where the data are and they are next to each other. So for example, if I needed the arithmetic average, ie:
I could print out for each row:
// If row = 1, startColumn = A, endColumn = D, noOfColumn = 4. This would print: =SUM(A1:D1)/4
mean[row] = #"=SUM(" + startColumn + row + ":" + endColumn + row + ")/" + noOfColumns;
What would I print out to match the first formula I wrote? Or what would I need to write in Excel?
without VBA:
Put your data in A1 through A10 and in B1 enter:
=10^(A1/10)
and copy down. Then in another cell enter:
=10*LOG10(SUM(B1:B10))
You can avoid the "helper" column (column B) by using:
=10*LOG10(SUMPRODUCT(10^((A1:A10)/10)))
If that's how you enter your formulas, then why not use the literal form of the sum? Ie use a for loop over the columns and fill in:
10*log(10^(A1/10)+10^(A2/10)+10^(A3/10)+10^(A4/10))
well I have a mini program changing all excel cells beginning with ='C:\, but I have a problem. I use range.replace for do this, but my program work wrong, because it don't change all the cells contain ='C:\, only change the first find it and I don't know for what reason.
My code is :
foreach (Excel.Worksheet sheet in xlWorkBook.Sheets)
{
string sheetName = sheet.Name;
Console.WriteLine(sheetName);
//seleccion rango activo
range = sheet.UsedRange;
//leer las celdas
int rows = range.Rows.Count;
int cols = range.Columns.Count;
//Excel.Range startCell = sheet.Cells[1, 1];
//Excel.Range endCell = sheet.Cells[rows, cols];
sheet.Range["A1:J1000"].Replace(#"='C:\", #"='T:\");
//range = sheet.UsedRange;
// leer las celdas
//int rows = range.Rows.Count;
//int cols = range.Columns.Count;
//}
// liberar
releaseObject(sheet);
}
You need to do another foreach-Loop for every cell in the selected range.
I have no way of testing this right now, but this should work:
object whatToReplace = "what you want to replace";
object replacement = "what you want to replace it with";
foreach(Range cell in range)
{
cell.Replace(whatToReplace, replacement);
}
I am using Windows Application. In that Application i exported the DataGrid into Excel Successfully... Now the problem is , When i exported from Grid to the Excel Sheet, The cell values are having some green color mark on left top corner in the Excel Sheet... I thought that is type cast problem . How Shall i avoid that Problem.... and How to change the cell value from text to Number ...(i.e)Convert To Number....
Can Anyone tell me the solution of this problem?
My Code for Formatting That Excel Sheet For Some Range of Values,
wksheet.Range[GetRanges[0].ToString(), GetRanges[GetRanges.Count-2].ToString()].Merge();
wksheet.get_Range(GetRanges[0].ToString(), GetRanges[GetRanges.Count-].ToString()).Interior.Color = Color.FromArgb(192, 0, 0);
I haven't a Windows machine to test on at the moment, but perhaps you would want to try changing the cell format, e.g.:
my_range.NumberFormat = "0.0"; // change number of decimal places as needed
Here's a full example from Microsoft: How to automate Microsoft Excel from Microsoft Visual C#.NET.
The following routine will dynamically fill a spreadsheet from data (text and numbers) in a text file.
The kicker is using an object array to set the values.
StreamReader STRead;
String[] STCells;
object[] cellData;
int temp;
Excel.Range tempRange;
for (int i = 0; i < FileList.Length; i++)
{
STRead = FileList[i].OpenText();
int j = 0;
while (!STRead.EndOfStream)
{
STCells = STRead.ReadLine().Split(',');
cellData = new object[STCells.Length];
for (int k = 0; k < STCells.Length; k++)
{
if (Int32.TryParse(STCells[k], out temp))
cellData[k] = temp;
else
cellData[k] = STCells[k];
}
tempRange = sheetList[i].get_Range(ReturnCellID(j, 0),
ReturnCellID(j, STCells.Length - 1));
j++;
tempRange.Value2 = cellData;
}
STRead.Close();
}
I had this problem with a excel sheet containing both regular numbers and percent (a result of an export of strings from a Crystal Report).
To change all of them at once I made a loop somewhat like this:
//example range
Excel.Range rng = mWorkSheet.get_Range("A1", "H25");
foreach (Excel.Range range in rng)
{
if (range.Value != null)
{
int number;
bool isNumber = int.TryParse(range.Value.ToString().Trim(), out number);
if (isNumber)
{
range.NumberFormat = "#,##0";
range.Value = number;
}
else
{
//the percent values were decimals with commas in the string
string temp = range.Value.ToString();
temp = temp.Replace(",", ".");
range.Value = temp;
}
}
}
Result was that both the percentage strings and the numbers got converted into the correct Excel format.
When you assign the value to the cells, try to get all the values in an 2 dimensional array first and then assign the array to the Range. this way its going to be very fast and also i guess the values in the cell will be number. try it out ...hopefully it should work
Change the cell value from text to Number is easy with Excel Jet Cell .NET component.
Cell["A1"].Style.StringFormat = "##.#"; // or "0.0" same as in MS Excel