I am trying to calculate the column sum by skipping specific rows with excel interop in C#.i am not able to figure out how to do that please help. I want to sum highlighted rows and skip the others in the attached image.
Excel array indices are generally 1-based, not 0-based (i.e. lowest element is number 1).
var xl = new Microsoft.Office.Interop.Excel.Application();
var b = xl.Workbooks.Open("C:\\Junk\\Junk.xlsx");
Microsoft.Office.Interop.Excel.Worksheet s = b.Worksheets[1]; //1-based
var r = s.Range["A1", "E4"];
int sum = 0;
for (var row = 1; row <= 4; row += 2)
{
sum += r.Value2[row, 1]; //also 1-based
}
xl.Quit();
Related
I am reading an Excel document grid (Matrix) cell by cell in order to write them in another Excel document. The reading is done starting from a specific cell at some position and stops at some other specific position for example from cell A3 to A5 for 4 rows to get a matrix of cells. Now i want to rewrite these cells in the exact order they are in except that i want to reinitialize the start to be at the origin of the destination Excel document. I am trying with the following code :
int l=1;
int m=1;
for (int i = n1; i <= n2; i++)
{
l++;
for (int j = n3; j <= n4; j++)
{
m++;
if (xlRange.Cells[i, j] != null && ((Excel.Range)xlRange.Cells[i, j]).Value2 != null)
{
l = i; // these indices should be altered in order to write at the origin
m = j; // these indices should be altered in order to write at the origin
// Write at the destination Excel document worksheet (xlWorksheet2)
xlWorksheet2.Cells[l,m] = ((Excel.Range)xlRange.Cells[i, j]).Value2.ToString();
}
}
}
To note that both n1 could be equal to n2 and n3 could be equal to n4.
My solution does not bring the start of the reading grid to the origin when writing to the destination Excel document. My question is how to define the indices of the array in order to write starting from while keeping the order of the cells as is.
UPDATE : using #Caius Jard suggested solution i get the following results in the destination Excel document :
l/m as 1. Increment in step with i/j
for(int i=n1,l=1; i <= n2; i++,l++)
{
for (int j=n3,m=1; j <= n4; j++,m++)
I'm writing a c# Add in for excel that takes values from a column of an excel sheet and does some operations. This is a part of the code that I wrote:
Excel.Range aqRange = currentSheet.Range["C3:C" + cRowCount];
Excel.Range vcRange = currentSheet.Range["D3:D" + cRowCount];
Excel.Range k0R = currentSheet.Range["F2"];
double[] sgVett = new double[cRowCount];
foreach (Range aq in aqRange)
{
if (i == 0) sgVett[i] = k0R.Value + aq.Value;
else sgVett[i] = sgVett[i - 1] + aq.Value;
i++;
}
i = 0;
foreach (Range vc in vcRange)
{
if (i == 0) sgVett[i] -= vc.Value;
else sgVett[i] -= vc.Value;
i++;
}
I want to know if is there some way to do something like this:
for(int j = 0; j<cRowCount; j++) {
if (i == 0) sgVett[i] = k0R.Value + aqRange[i].Value;
else sgVett[i] = sgVett[i - 1] + aqRange[i].Value;
}
I know that I can't use a Excel.Range as a vector, but is there some way to use an index to scroll aqRange and vcRange or, at least, if it's possible to use just one for or one foreach instead of two (as I done).
You can use the Range's Cells property a bit like a 2 dimensional array.
It is important to note that although the syntax used is similar to a C# 2D array (Cells[RowIndex, ColIndex]), the Cells property accesses a COM object that uses 1 as it's start offset, rather than 0.
So you should be able to write something like :
for(int j = 1; j<=cRowCount; j++)
{
if (i == 0) sgVett[i] = k0R.Value + aqRange.Cells[j,1].Value;
}
Also see here : Fastest way to get an Excel Range of Rows & How do I get an Excel range using row and column numbers in VSTO / C#?
I do not understand why the following code write 2,2,2 to Excel while it should be 0,1,2. The code is straightforward - create an ExcelPackage, add a Worksheet, and iterate a loop to write values to a cells.
using (ExcelPackage p = new ExcelPackage())
{
p.Workbook.Worksheets.Add("Foo");
for (int j = 0; j < 3; j++)
p.Workbook.Worksheets["Foo"].Cells[1, 1, 1, 1 + j].Value = j;
p.SaveAs(new FileInfo(#"C:\FooFolder\Foo.xlsx"));
}
You are writting in a range instead of a unique cell. With Cells[1, 1, 1, 1 + j] you are writting from cell 1,1 to cell 1,1+j : the complete range take the assigned value.
Use Cells[1, j, 1, 1 + j] instead
For a project I have a multidimensional array (double[,]) containing double values. Since I'm using a method from the accord framework that expects to receive a jagged array of doubles (double[][]) I need to convert one into the other. However, using the code below, I notice that I never reach the inputs[k] = row; statement.
double[][] inputs = new double[165][];
// Loop through # of rows
for (int k = 0; k < pcaComponents.GetLength(1); k++)
{
double[] row = new double[20];
// Loop through # of columns
for (int l = 0; l < pcaComponents.GetLength(0); l++)
{
row[k] = pcaComponents[k, l];
}
inputs[k] = row;
}
pcaComponents is of type double[,] and is passed through from another piece of code. By using the getLength property I can see that when I'm passing 1, the result is 165, which is the # of rows and by passing 0 I can see that the result is 20, which is the # of columns. Then I try to create a new row for the jagged array with the values from the multidimensional array. It loops through the 2nd loop 20 times, but it doesn't seem to reach the inputs[k] = row; statement and doesn't continue the 1st loop where pcaComponents.GetLength(1) equals 165.
I think you have to replace your line
row[k] = pcaComponents[k, l];
by that one
row[l] = pcaComponents[k, l];
The variable of your inner loop is l not k
And maybe you should use the GetLength for sizing your arrays:
double[] row = new double[pcaComponents.GetLength(0)];
I have established an array and a large textbox which displays the array. Basically, you enter a name, 4 quarterly sales figures and it calculates the yearly total. I am now starting on the sort button. This would sort given columns numbers from most to least. I have gotten an if statement that looks like it should work for column five (the total column). I keep getting an out of range exception and am not sure why. Any ideas out there? I am sure this is a simple problem I am not seeing.
do {
swapFlag = false;
for (n=0; n < lastIndexUsed; n++)
{
if (quarters[n, sortCol] < quarters[n+1, sortCol])
{
//Column 5
temp = quarters[n,5];
quarters[n,5] = quarters[n +1, 3];
quarters[n +1, 3] = temp;
//swapflag
swapFlag = true;
}
}
} while (swapFlag);
This shows how I get 0-5 for sortCol:
if (rbRegion.Checked)
sortCol = 0;
if (rb1.Checked)
sortCol = 1;
if (rb2.Checked)
sortCol = 2;
if (rb3.Checked)
sortCol = 3;
if (rb4.Checked)
sortCol = 4;
if (rbTotal.Checked)
sortCol = 5;
Button Variables:
int n;
int temp;
int sortCol = 0;
string ntemp;
bool swapFlag;
Global Variables
int lastIndexUsed = -1;
int[,] quarters = new int[10, 5];
string[] Branch = new string[10];
quarters is defined as
int[,] quarters = new int[10, 5];
since arrays are zero based this gives you index 0...4 on the second dimension but you are trying to access index 5:
temp = quarters[n,5];
It seems to me, that you could have n = quaters.size - 1, and therefore n + 1 = quaters.size.
So it gets out of array's bound.
I smell the problem is with these:
quarters[n+1, sortCol]
quarters[n+1, 3]
Make sure n+1 is a valid index. What if lastIndexUsed itself is the maximum valid index? Then n+1 would cause IndexOutOfRangeException.
I'd suggest to use more instances of List<int> quartersSortCol0 and use if (rbRegion.Checked) quartersSortCol0.Sort() and avoid ineffective constructions like your "while-for" above. While you can use overload of Sort method with custom comparison.