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.
Related
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.
I'm trying to get the row count of rows which don't have any value (any of columns)
Sample image of the Excel file I'm using:
Highlighted rows have some values in some columns rest of rows are blank I need to count those rows.
I already used this method
int blankRows = 0;
double notEmpty = 1;
while (notEmpty > 0)
{
string aCellAddress = "A" + (rowIndex++).ToString();
Excel.Range row = excelApp.get_Range(aCellAddress, aCellAddress).EntireRow;
notEmpty = excelApp.WorksheetFunction.CountA(row);
if (notEmpty <= 0)
{
blankRows++;
}
}
but this is very time consuming process when file is large and minimum number of blank rows is there.
One thing that might help would be to find the last column that has data and last row that has data as to limit your search.
This is VBA code snippet, but could be easily transformed to C#:
'iterate through columns to determine which is longest to determine the highest row number.
For i = 1 To 16384 'number of columns in excel
'get the row
rowcount = ws.Cells(Rows.Count, i).End(xlUp).Row
'check to see if it's larger than what it is now, if it is, set the value of lRow.
If rowcount > lrow Then
lrow = rowcount
End If
Next
then use a similar loop to get the last row based on the last row, stepping through each row until the last one to get the last column with data.
You can use those values to limit the range that you're looking through. I'm not sure if it will be any faster, but it might help.
any answere would be very much appreciated.
My question is as follow:
Is this the correct way to determin the last non-empty cell/row of my excel worksheet?
xl.Worksheet sh;
int lastRow;
int fullRow;
sh = xlApp.Workbooks.get_Item("myExcelFile").Worksheets.get_Item("MySheet");
fullRow = sh.Rows.Count;
lastRow = sh.Cells[fullRow, 1].End(xl.XlDirection.xlUp).Row;
And if this is indeed correct how do I take my row and copy it into another worksheet. To be more specifict, the first empty cell of column A.
I know that i must use a command that is something like this:
lastRow.EntireRow.Copy(FirstEmptyCell);
Being a int type i cannot copy it to my other sheet.
Any suggestions?
lastRow = sh.Cells[fullRow, 1].End(xl.XlDirection.xlUp).Row;
here, lastRow is an int so you can't use it as an object on your next line:
lastRow.EntireRow.Copy(FirstEmptyCell); // int doesn't have an EntireRow property
What you can do is combine the two into a single line:
Excel.Range myLastRow;
myLastRow = sh.Cells[sh.Rows.Count, 1].End(xl.xlDirection.Up).EntireRow;
now myLastRow is the entire row that you want to copy.
myLastRow.Copy(destination);
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;
I know how to write single cell into excel but when im trying it on array excel sheet is filling with only last value
this is my range
Excel.Range ServiceName = (Excel.Range)_sheet.get_Range(_sheet.Cells[38, "B"] as Excel.Range, _sheet.Cells[45, "B"] as Excel.Range);
_ServiceName is List which contains 1,2,3,4,5,6
for (int i = 0; i < _ServiceName.Count; i++)
{
ServiceNameArray[0, i] = _ServiceName[i];
}
this i my trying to write into excel but as i said it there is only last item (6) in excel book
for (int i = 0; i < _ServiceName.Count; i++)
{
ServiceName.set_Value(Type.Missing, ServiceNameArray[0,i]);
}
does anyone have an idea?
Davide Piras is right. And you're doing a few other strange things there, I can elaborate by request.
For now I just want to point out that you can directly assign the .Value property of a Range to an array:
ServiceName.Value2 = _ServiceName.toArray();
This is much, much faster for bigger amounts of data.
(Side note: If you want to do the same with Formulas, for some strange reason you have to take an extra step (doubling the time):
range.Formula = array;
range.Formula = range.Formula;
unless there is a better way I don't know about yet.)
I see you looping on the ServiceName array to get all values one after the other but not see you changing the focused cell inside the cellrange at every loop iteration. Of course, I would say, you see only the last value, because you are writing all values one over the other always in the same place.