This code is supposed to get all rows in the range that I specify, and delete ONLY the rows with no cell DATA in them. It's actually deleting every row in the range though. Why?
Range range = _sheet.get_Range("A25:A542", Type.Missing);
range = range.EntireRow;
range.Delete(Type.Missing);
Type.Missing doesn't mean what you think it means. Type.Missing is a COM artefact - it just tells the Excel object that you're not providing that particular parameter. It's the kind of thing that's normally taken care of for you in VB.NET and VBA. C# 4.0 has support for optional parameters, which makes things much easier.
You do not check if any DATA exists, so the program deletes all rows from line 25 til line 542.
Related
I've 2 excel sheets(Sheet1 & Sheet2) in my Excel workbook. I want to copy row data from Sheet2 to Sheet1.
Condition is:
if Sheet2 copied row doesn't exist in Sheet1 then paste it otherwise don't paste the row.
Copied Rows except 1st row in Sheet2:
Range dataWithoutFirstRow = xlAccrualSheet.Range[xlAccrualSheet.UsedRange.Cells[2, 1],
xlAccrualSheet.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)];
dataWithoutFirstRow.Copy();
Paste in below used range in Sheet1:
Range DataRange = xlAccrualWorkSheet.Cells[emptycell, 1];
DataRange.PasteSpecial(XlPasteType.xlPasteAllUsingSourceTheme);
Please Tell me How to check already exist rows in Sheet1.
Awaiting for Your Response
Please Tell me How to check already exist rows in Sheet1.
Use Range to read out all data from the workSheet. You are already doing a similar thing accrualSheet. Then, you can use range.Cells(i,j) or range.Rows(r).Value or even range.Rows(r).Cells(i,j) to get the data inside each specific row.
When pasting occurs, loop over all pasted rows, and for each pasted row compare it with rows from workSheet. You may do it directly by reading that on the fly (as mentioned above), or you may read all rows from workSheet and store them in a List and compare incoming rows against that list - it will work much faster that way.
Now, one of the most interesting things is probably what does it mean to "compare rows". Either you will need to compare all cells within a row with another one, or you will need to compare just a specific set of "columns" like "date, time, cause, origin, caseId" etc. But that.. noone knows, you said nothing about that. If there's no info on that, then you probably should compare whole rows and assume that any difference in any cell means that the rows are different.
When I send data to Excel it ignores the merged "property" of some cells and just writes to the first cell it finds. So assuming I have column A and column B merged and I am sending data to column A and C, it actually splits the merged column so I am left with an empty column B.
Here is some code for context (some variables have been kept generic):
Range cells = this.Worksheet.Cells;
Range cell = (Range)cells[rowIndex, columnIndex];
Boolean merged = (Boolean)cell.MergeCells; //Here I am trying to determine if the
//cell is merged.
My problem is that .MergeCells always returns false. What am I doing wrong here? I know that in the Excel worksheet the cells are merged.
The problem is you are casting to a boolean, and MergeCells is not always guaranteed to give you back a boolean, as outlined in this more recent question: how to detect merged cells in c# using MS interop excel. You need to also check for the value of null - see the linked question for how to do that.
Hypothesis
So what's probably happening to your code is the null value casts back to false, even though what the null value actually indicates is that there are merged cells in the range.
The answer is: Your code is correct.
Boolean merged = (Boolean)cell.MergeCells; //Cast from dynamic{bool} to bool
This works for me (Excel 2013 on Windows 7).
I have noticed both true and false values in my own tests.
So maybe your worksheet's cells just DO NOT CONTAIN a merged cell!?
My worksheet has a number of tables. I need to manipulate one in particular. Of course I could simply look at its cell numbers and manipulate it cell by cell, but is there any "get" function to "get" the table programatically?
And if so, how would I then manipulate the cells? Is there a command to "get" the entire header, or an entire column by its header (rather than its column number)/
If anyone knows of a guide that explains this, that would be sufficient. I tried googling it but all the results are about database tables, i.e. populating a spreadsheet from a DB.
Swift, I'm working on something similar and I ran across this article which helped me.
In short, references to tables can be found in a worksheets list objects. Iterating through the list object and requesting the range or datarange should get you what you need.
I also found this article which has very similar info.
All these examples are in VBA or VB but I found it not to difficult to port over.
-M
When you say a table, I assume you mean a range. The following code will get a range from within an VS2010 Excel Add-In -
Excel.Worksheet activeWorksheet = ((Excel.Worksheet)Application.ActiveSheet);
Excel.Range myRange = activeWorksheet.get_Range("A1", "D20");
I have a C# add-in for Excel and I need to put the data on a worksheet. I do it like so:
// Now build a string array of the results
string[,] resultArray = new string[objects.Length, length];
// Fill in the values
Excel.Range resultRange = worksheet.get_Range("A2").get_Resize(objects.Length, length);
resultRange.Value = resultArray;
I have left out some unimportant steps. Basically, I am passed an array of objects, I get the type from the first one and use the properties to build a list of column names. I put that in the row 1. That is why I start the data in row 2.
The issue I ran across is that I had an Excel 97-2003 workbook (with max rows of around 65K row) and I tried to bring in 105K objects. It choked on the resize. I would like to check to see if my resize is even valid so I can tell the user, but I can't seem to find a "MaxRows" or similar property. Is there one?
worksheet.Rows.Count will give you the maximum number of rows in a given worksheet. If you check this property before accessing a large number of rows you can make your program compatible with 2003, 2007, and take advantage of increased numbers of rows in all future versions of Excel.
Here are the hard limits for a worksheet in Excel 2003. There is no programmatic way to exceed these limits, although you could start spreading data across multiple sheets or various other bits of trickery.
Excel 2010 has expanded these limits significantly. So an option might be to get your customer to upgrade as a part of the project.
How does one delete a column (or multiple columns) in Excel?
eg. How to delete column C and shift the rest left?
Here is the solution to make it clearer (thanks to Leniel for the link)
Excel.Range range = (Excel.Range)sheet.get_Range("C1", Missing.Value);
range.EntireColumn.Delete(Missing.Value);
System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
This was the first result I hit and deleting a column in Excel doesn't need as much code as the current answers suggest. In fact (assuming you have a Worksheet object already, listed below as mySheet) all that is needed for the original question is:
mySheet.Columns["C"].Delete();
If you want to delete multiple columns then:
mySheet.Columns["C:D"].Delete();
You can specify a variable in the Delete method (see https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.excel.xldeleteshiftdirection?view=excel-pia) i.e. mySheet.Columns["C"].Delete(xlShiftToLeft)but there's no need as the Delete method is smart enough to realise that the Range you are selecting is a single column, so will do this automatically.
You can also uses a numeric value to designate the column i.e. mySheet.Columns[2].Delete()
Here you find how to do it:
http://bytes.com/topic/c-sharp/answers/258110-how-do-you-delete-excel-column
http://quicktestprofessional.wordpress.com/2008/02/14/delete-columns-from-xl-sheet/