Copying specific range of excel cells from below a specific keyword - c#

I am wanting to write a C# program to copy a specific range of cells below a specific keyword. The code will identify a keyword in Excel and then copy the values of all the cells below the keyword to copy into another range.
I am using Aspose. I attempted to write code to find the keyword and can successfully return the cell the keyword is located in. What I am trying to figure out how to do is copy the range specifically below any keyword into another range. I can successfully copy one range to another range but cannot do it from below a specific keyword.
Cells cellsOne = worksheet.Cells;
FindOptions findOptions = new FindOptions();
findOptions.LookAtType = LookAtType.StartWith;
Cell cell = cellsOne.Find("Accounting", null, findOptions);
//Printing the name of the cell found after searching worksheet
Console.WriteLine("Name of the cell containing String: " + cell.Name);
//if cell is found/value is returned
if (cell.Name.Contains("Accounting"))
{
//return cell value ?
//copy all below values (will need the cell keyword is in to do that)
//paste below values into specific columns
//doing it manually
Aspose.Cells.Range range1 = cellsOne.CreateRange("A2:A10");
Aspose.Cells.Range range2 = cellsOne.CreateRange("B28:B34");
range1.Copy(range2);
}
I have visited Aspose website but am struggling to copy a range BELOW a specific keyword. Thank you.

I don't know how to do it in C#, but I would advise you to find the cell which has the value, then in your "Range" statement below you could start at that cell you found before.
For example,
Cell cell = cellsOne.Find("Accounting", null, findOptions).Row;
You get for example "320", then your next line goes to that 320. Using your code:
Aspose.Cells.Range range1 = cellsOne.CreateRange("A2:A10");
Aspose.Cells.Range range2 = cellsOne.CreateRange("B" & cell & ":B34");
range1.Copy(range2);`
That's what I would do in VBA.
Hope it helps!

Checking your code segment a bit, I thought your destination range is "A2:A10". Your code needs some tweaks. See the updated (complete) sample code with comments to accomplish your task for your reference. I evaluated the source range (below the searched keyword) dynamically using CellsHelper static class.
e.g.
Sample code:
Workbook workbook = new Workbook("e:\\test2\\Book1.xlsx");
Worksheet worksheet = workbook.Worksheets[0];
Cells cellsOne = worksheet.Cells;
FindOptions findOptions = new FindOptions();
findOptions.LookAtType = LookAtType.StartWith;
Cell cell = cellsOne.Find("Accounting", null, findOptions);
//Printing the name of the cell found after searching worksheet
Console.WriteLine("Name of the cell containing String: " + cell.Name);
//if cell is found/value is returned
if (cell != null)
{
//I thought this is your destination range
Aspose.Cells.Range range1 = cellsOne.CreateRange("A2:A10");
//Evaluate the the next cell after (found) cell's row and column indices.
int startRow = cell.Row +1; //we add "1" to get the next in the same column
int startCol = cell.Column;
string startCell = CellsHelper.CellIndexToName(startRow, startCol);
//Set and evaluate your end cell for the range.
string endCell = CellsHelper.CellIndexToName(startRow + 6, startCol);
//Create your dynamic source range based on your startCell and endCell values
Aspose.Cells.Range range2 = cellsOne.CreateRange(startCell, endCell);
//Copy the source range to destination range
range1.Copy(range2);
}
workbook.Save("e:\\test2\\out1.xlsx");
Hope, this helps a bit.
You may also see the document on copying ranges for your further reference.
PS. I am working as Support developer/ Evangelist at Aspose.

Related

utilizing spreadsheet find method in c#

I made a C# winforms project which allows the user to pick a cell in a spreadsheet and write an integer value "total" into the selected cell. This takes place on an existing spreadsheet and thus this action changes the value of the cell. What is the best way to change some more cells with particular similarities?
My code is below:
private void button5_Click(object sender, EventArgs e)
{
MySheet = (Excel.Worksheet)MyBook.Sheets[1]; // Explicit cast is not required here
bpRow = excelApp.ActiveCell.Row;
bpColumn = excelApp.ActiveCell.Column;
MySheet.Cells[bpRow, bpColumn] = total;
Excel.Range colRangeH = MySheet.Columns["R:R"];//get the range object where you want to search from
Excel.Range resultRangeH = colRangeH.Find(
What: MySheet.Cells[bpRow, 18],
LookIn: Excel.XlFindLookIn.xlValues,
LookAt: Excel.XlLookAt.xlPart,
SearchOrder: Excel.XlSearchOrder.xlByRows,
SearchDirection: Excel.XlSearchDirection.xlNext
);
textBox3.Text = " " + resultRangeH;
if (MySheet.Cells[resultRangeH, 16] == MySheet.Cells[bpRow, 16])
{
if (MySheet.Cells[resultRangeH, 22] == "T.PLATE")
MySheet.Cells[resultRangeH, bpColumn] = 3 * MySheet.Cells[bpRow, bpColumn];
else if (MySheet.Cells[resultRangeH, 22] == "STUD")
MySheet.Cells[resultRangeH, bpColumn] = (int)(Math.Ceiling(MySheet.Cells[bpRow, bpColumn] / 1.33));
}
MyBook.Save();
}
The spread sheet is made of about 90 entries and each row has a 21 numbers and a written description. I added a find method in my code to give me the row number of an entry with its 18th number equal to the 18th number in the entry corresponding to the selected cell. I then wrote a few if statements to check another number value and the written description. This is so that i may change the values in the column corresponding to the selected cell accordingly.

How to merge cell using closedxml with a dynamic column count?

This is how to merge cell using ClosedXML based on the documentation.
worksheet.Range("B2:D3").Row(1).Merge();
My problem is my column count is dynamic, I can't set column letter value to merge because i will based the merging of cell on my gridview column count.
Anyone who can help me to merge cell using closedXML?
I do it this way
int row = 1;
int col = 1;
worksheet.Range(worksheet.Cell(row, col++), worksheet.Cell(row, col++)).Merge();
Build up the range as a variable based on your column count and pass the variable to the Range method. You don't need to HAVE to pass a hard coded value.
Have you tried the code below?
worksheet.Cell("A1").Value = "Title";
var range = worksheet.Range("A1:F1");
range.Merge().Style.Font.SetBold().Font.FontSize = 16;
It works for me.

How to get all the rows which contain data in a particular column in Excel from C#

I have a data set in Excel and am using C# to open the worksheet and access some of the data.
I am trying to get all the rows that contain data from a particular column. For example in column B starting from cell 'B3' going down I want to store all the rows that contain data in a collection like an Array.
This is what I have so far:
Application excelApplication;
_Workbook workbook;
_Worksheet sheet;
excelApplication = new Excel.Application
{
Visible = true,
ScreenUpdating = true
};
workbook = excelApplication.Workbooks.Open(#"C:\Documents and Settings\user\Desktop\Book1.xls");
sheet = (Worksheet)workbook.Worksheets[2];
Excel.Range range = sheet.Range["b3:b145"].
foreach (Range cell in range)
{
// Do something with rows which contain data
}
As you can see above I have specified the range from B3 to B45 which I don't want. I want to get all the rows in the B column which contain data starting from B3.
How would I achieve this?
In general when I get stuck in these situations I record a Macro and convert the VBA code to C#. The object model in VSTO is pretty much exactly the same (remember this its a great tip) and with .Net 4.0 onwards optional parameters save a lot of code.
In your particular instance I envisage the larger the spreadsheet the longer it will take to read all the Excel cells in column B using VSTO. My advice is to use this technique to read them all at once:
//Work out the number of rows with data in column B:
//int lastColumn = range.Columns.Count;
int lastRow = range.Rows.Count;
//Get all the column values:
object[,] objectArray = shtName.get_Range("B3:B" + lastRow.ToString()).Value2;
rngName.Value2 = objectArray;

C# - How do I iterate all the rows in Excel._Worksheet?

I am looking to programmatically pull data from an Excel worksheet and insert it into a database table.
How do I determine the number of columns and rows in a worksheet or otherwise iterate the rows?
I have
Excel._Worksheet worksheet = (Excel._Worksheet)workbook.ActiveSheet;
I tried worksheet.Range.Rows.Count
which tosses up
Indexed property 'Microsoft.Office.Interop.Excel._Worksheet.Range' has
non-optional arguments which must be provided
What needs to be done?
using Excel = Microsoft.Office.Interop.Excel;
...
public void IterateRows(Excel.Worksheet worksheet)
{
//Get the used Range
Excel.Range usedRange = worksheet.UsedRange;
//Iterate the rows in the used range
foreach(Excel.Range row in usedRange.Rows)
{
//Do something with the row.
//Ex. Iterate through the row's data and put in a string array
String[] rowData = new String[row.Columns.Count];
for(int i = 0; i < row.Columns.Count; i++)
rowData[i] =Convert.ToString(row.Cells[1, i + 1].Value2);
}
}
This compiles and runs just great for me! I'm using it to extract rows with missing fields to an error log.
I presume you are actually looking for the last used row. In that case you need to write it like this:
Range UsedRange = worksheet.UsedRange;
int lastUsedRow = UsedRange.Row + UsedRange.Rows.Count - 1;

How to read the data from Non Adjacent Cells in Excel using C#

I have an excel sheet, in which i have multiple cells selected, which are not adjacent to each other. When the user click on the button, we need to read all the cells data, process it and write it to some other cell.
If the cells are adjacent to each other, i was able to get the range and able to perform the operation. But if the cells are not adjacent to each other, i am not able to get the range.
The Selection.Range is always giving the address of the last cell we selected.
But we need to get the addresses of all Cells, which i am not able to do it.
Please can anybody suggest me a way to handle this scenario.
Sample code:
Range objRange = (Range) Globals.ThisAddIn.Application.Selection;
int nColCount = objRange.Columns.Count;
int nRowCount = objRange.Rows.Count;
Vinay,
I have tried this code based on your suggestion,
Range objRange = (Range) Globals.ThisAddIn.Application.Selection;
foreach (Range cell in objRange)
{
MessageBox.Show("" + cell.Value2);
}
But it didn't worked. Always it's giving the last selected cell. i have selected A1, A4, A13, A16 cells. But this code is returning the A16 Cell Value Only.
Range inherits from IEnumerable. So you can use for each iterator to enumerate via all cells.
See the equivalent VBA code below:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim result As String
result = ""
Dim c As Range
For Each c In Me.Application.Selection
result = result & ", " & c.Text
Next c
Me.Cells.Item(1, 1).Value = result
End Sub
You can always use Range.Row, Range.Column for getting the cell address.
As said in comments, use foreach synatx:
foreach(Range cell in objRange)
{
// now access cell's properties - c.Value will give value
}
After trying alot, I got the answer.
Here is the working code,
Areas objAreas = (Areas)objRange.Areas;
foreach (Range area in objAreas)
{
string CellAddress = (GetExcelColumnName(area.Column) + "" + area.Row);
MessageBox.Show(CellAddress);
}
GetExcelColumnName is the custom function u have written to convert Column number to Column Code(like a, b,... aa, ab.. etc)

Categories

Resources