Imagine, that u have the Column A.
There are 100 Rows and in the Cells are Numbers, like 1, 2, 3 until 100..
How can I programmaticaly (C#) Delete a specific Row, by Example: Deleting the Row which
Value in Column A is 5..
I'm working with the Microsoft.Office.Interop.Excel and thats the related code:
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(#"C:\Users\fre\Desktop\TestDatei.xls");
Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
xlWorksheet.Select(Type.Missing);
Microsoft.Office.Interop.Excel.Range range = xlWorksheet.get_Range("B1:B5", Type.Missing);
range.Delete(Microsoft.Office.Interop.Excel.XlDeleteShiftDirection.xlShiftUp);
because i was interested, too, i did some investigation on the web and created some sample code. maybee this can help you:
private void DeleteCells(object sender, EventArgs e)
{
// create excel-instance:
Excel.Application excel = new Excel.Application();
// open the concrete file:
Excel.Workbook excelWorkbook = excel.Workbooks.Open(#"D:\test.xls");
// select worksheet. NOT zero-based!!:
Excel._Worksheet excelWorkbookWorksheet = excelWorkbook.Sheets[1];
// create a range:
Excel.Range usedRange = excelWorkbookWorksheet.UsedRange;
// iterate range
foreach (Excel.Range r in usedRange)
{
// check condition:
if (r.Value2 == 5.0F)
// if match, delete and shift remaining cells up:
r.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);
}
// save changes (!!):
excelWorkbook.Save();
// cleanup:
if (excel != null)
{
Process[] pProcess;
pProcess = System.Diagnostics.Process.GetProcessesByName("Excel");
pProcess[0].Kill();
}
}
greetings!
jens
If you want to delete the entire row, try this it works
Range usedRanage=sheet.UsedRange;
foreach (Range r in usedRanage)
{
if (Convert.ToString(r.Value2)=="RETRIEVE")
{
r.EntireRow.Delete(XlDeleteShiftDirection.xlShiftUp);
}
}
Related
I can use XlCellType.xlCellTypeLastCell to find last cell in the used range. How to get first cell in one line ?
Code to get last cell position.
Excel.Range mergeCells = (Excel.Range)mergeSheet.Cells[6,1].EntireRow;
var rowRng = mergeCells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);
var colPosition = rowRng.Column;
One way is to get mergeCells.value and loop through to increment a counter until I see null/empty value. But I was hoping to get this in one line.
Any ideas ?
Test Cases:
(1)
Expected Result colPosition = 1
(2)
Expected Result colPosition = 5
Here is a solution using the Excel Interop library (as tagged in the question). The below method will return a 1-based column index of the first cell in a given row. It worked for me on your supplied test cases as well as a few of my own. Note that if you wish to simply use the first row in the used range - rather than a supplied row, you can find the first used row number using ActiveSheet.UsedRange.Rows[1].Row.
public static int FindFirstCellInExcelRow(string filePath, int rowNum)
{
Excel.Application xlApp = null;
Excel.Workbook wkBook = null;
Excel.Worksheet wkSheet = null;
Excel.Range range = null;
try
{
xlApp = new Excel.Application();
wkBook = xlApp.Workbooks.Open(filePath);
wkSheet = wkBook.ActiveSheet;
range = wkSheet.Cells[rowNum, 1].EntireRow;
if (range.Cells[1, 1].Value != null)
{
return range.Cells[1, 1].Column;
}
var result = range.Find(What: "*", After: range.Cells[1, 1], LookAt: Excel.XlLookAt.xlPart, LookIn: Excel.XlFindLookIn.xlValues, SearchOrder: Excel.XlSearchOrder.xlByColumns, SearchDirection: Excel.XlSearchDirection.xlNext, MatchByte: false, MatchCase: false);
int colIdx = result?.Column ?? 0; // return 0 if no cell in row contains value
return colIdx;
}
finally
{
wkBook.Close();
Marshal.ReleaseComObject(xlApp);
Marshal.ReleaseComObject(wkBook);
Marshal.ReleaseComObject(wkSheet);
Marshal.ReleaseComObject(range);
xlApp = null;
wkBook = null;
wkSheet = null;
range = null;
}
}
I highly (x10) recommend using ClosedXML over Microsoft's Excel libraries (unless you are using the old xls files). Using ClosedXML you would do the following (this is taken right from their webpage):
Get it right off the NuGet packages. Install-Package ClosedXML -Version 0.93.1
https://github.com/ClosedXML/ClosedXML/wiki/Finding-and-extracting-the-data
var wb = new XLWorkbook(northwinddataXlsx);
var ws = wb.Worksheet("Data");
// Look for the first row used
var firstRowUsed = ws.FirstRowUsed();
// Narrow down the row so that it only includes the used part
var categoryRow = firstRowUsed.RowUsed();
// Move to the next row (it now has the titles)
categoryRow = categoryRow.RowBelow();
// Get all categories
while (!categoryRow.Cell(coCategoryId).IsEmpty())
{
String categoryName = categoryRow.Cell(coCategoryName).GetString();
categories.Add(categoryName);
categoryRow = categoryRow.RowBelow();
}
try the below code snippet, this will give the first row of a excel used range
Excel.Workbook xlWB = Globals.ThisAddIn.Application.ActiveWorkbook;
Excel.Worksheet xlWS = xlWB.ActiveSheet;
int firstRow = xlWS.UsedRange.Row;
I’m working on a project and I’ve ran into an exception that I don’t know how to fix. I’ve searched everywhere and can’t find a solution that helps.
I’m trying to cut a range on a spreadsheet that has found a specific value in a cell in Column A and paste the entire row of that specific value into a new spreadsheet starting from A2 and until the value is no longer found in the original spreadsheet.
My code currently pastes one row in the new spreadsheet then gives me this exception “The information cannot be pasted because the Cut area and the paste area are not the same size and shape.” The exception is happening at this point in the code;
Excel.Range from = currentFind.EntireRow;
Excel.Range to = oSheet.get_Range("A2:A2500");
I think I need to use the active cell and active sheet properties.
Please help me!
public void btnLoad_Click(object sender, EventArgs e)
{
Excel.Application oXL;
Excel._Workbook oWB;
Excel._Worksheet oSheet;
if (dmCheck.IsChecked == true && fldCheck.IsChecked == true)
{
oXL = new Excel.Application();
oXL.Visible = true;
oWB = (Excel._Workbook)(oXL.Workbooks.Add());
oSheet = (Excel._Worksheet)oWB.ActiveSheet;
string dXLPath = #"N:/DAILY2.xlsx";
Excel.Workbook dWB = oXL.Workbooks.Open(dXLPath);
Excel.Worksheet dSheet = dWB.Worksheets.get_Item(1);
Excel.Range dRng = dSheet.get_Range("B1");
dRng.EntireColumn.Hidden = true;
Excel.Range currentFind = null;
Excel.Range firstFind = null;
Excel.Range taskHazpoi = dSheet.get_Range("A2", "A2500");
currentFind = taskHazpoi.Find("HAZPOI", Type.Missing, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false, Type.Missing, Type.Missing);
while(currentFind != null)
{
if (firstFind == null)
{
firstFind = currentFind;
}
else if (currentFind.get_Address(Excel.XlReferenceStyle.xlA1) == firstFind.get_Address(Excel.XlReferenceStyle.xlA1))
{
break;
}
Excel.Range from = currentFind.EntireRow;
Excel.Range to = oSheet.get_Range("A2:A2500");
from.Cut(to);
currentFind = taskHazpoi.FindNext(currentFind);
}
else if (dmCheck.IsChecked == false && fldCheck.IsChecked == false)
{
MessageBox.Show("Please check the DM and Flood box", "Report Loader");
}
I recommend you use Epplus instead of the interop Excel (i used it).
Advantages:
No requires office package installed in system.
No instance of Excel in memory.
Methods more clear.
Example of use:
http://zeeshanumardotnet.blogspot.com.es/2011/06/creating-reports-in-excel-2007-using.html?m=1
You found it in Nuget.
Regards,
You try to copy an entire row into the cell area A2:A2500, that's what triggers the exception.
For the 'to' range, take oSheet.get_Range("A2").EntireRow or oSheet.get_Range("A:A").
For an excel 2010 plugin, I need a method to change cell values of the active worksheet.
This code works, but opens a new excel window.
How can I change this, to edit the values from the active worksheet?
Microsoft.Office.Interop.Excel.Application objApp;
Microsoft.Office.Interop.Excel.Workbook objBook;
Microsoft.Office.Interop.Excel.Sheets objSheets;
Microsoft.Office.Interop.Excel._Worksheet workSheet;
objApp = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
objApp.Visible = true;
objBook = (Microsoft.Office.Interop.Excel.Workbook)objApp.ActiveWorkbook;
if (objBook == null)
{
objBook = objApp.Workbooks.Add();
}
// get the collection of sheets in the workbook
objSheets = objBook.Worksheets;
// get the first and only worksheet from the collection of worksheets
workSheet = (Microsoft.Office.Interop.Excel.Worksheet)objSheets.get_Item(1);
workSheet.Cells[1, "A"] = "wert1";
Now I found the solution:
Microsoft.Office.Interop.Excel.Workbook objBook;
Microsoft.Office.Interop.Excel.Sheets objSheets;
Microsoft.Office.Interop.Excel._Worksheet workSheet;
objBook = (Workbook)Globals.ThisAddIn.Application.ActiveWorkbook;
if (objBook == null)
{
objBook = objApp.Workbooks.Add();
}
// get the first and only worksheet from the collection of worksheets
workSheet = (Microsoft.Office.Interop.Excel.Worksheet)objBook.ActiveSheet;
workSheet.Cells[1, "A"] = "value1A";
Source:
http://www.dreamincode.net/forums/topic/199576-getting-current-excel-application-or-workbook-in-c%23/
I am writing a C# program which copies a range of cells from a worksheet of one workbook to a worksheet of an other workbook. But the problem I am facing is I am only able to copy and paste the whole worksheet of first workbook. I want to know how to select only a specific range(from row 5 [column 1 to column 10] to row 100 [column 1 to column 10]) and paste it in second workbook worksheet starting from row 2 column 8.
Also i want to know how a fill a column say from C1 to C100 with some value in a direct way instead of using the loop like below
for(i=1;i<2;i++)
{
for(j=1;j<101;i++)
{
worksheet.cells[i,j]="Fixed";
}
}
Here is the code that i have written so far
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Excel.Application srcxlApp;
Excel.Workbook srcworkBook;
Excel.Worksheet srcworkSheet;
Excel.Range srcrange;
Excel.Application destxlApp;
Excel.Workbook destworkBook;
Excel.Worksheet destworkSheet;
Excel.Range destrange;
string srcPath;
string destPath;
//Opening of first worksheet and copying
srcPath="C:\\Documents and Settings\\HARRY\\Desktop\\incident.csv";
srcxlApp = new Excel.Application();
srcworkBook = srcxlApp.Workbooks.Open(srcPath);
srcworkSheet = srcworkBook.Worksheets.get_Item(1);
srcrange = srcworkSheet.UsedRange;
srcrange.Copy(Type.Missing);
//opening of the second worksheet and pasting
destPath = "C:\\Documents and Settings\\HARRY\\Desktop\\FIXED Aging incident Report.xls";
destxlApp = new Excel.Application();
destworkBook = destxlApp.Workbooks.Open(destPath,0,false);
destworkSheet = destworkBook.Worksheets.get_Item(1);
destrange = destworkSheet.Cells[1, 1];
destrange.Select();
destworkSheet.Paste(Type.Missing, Type.Missing);
destworkBook.SaveAs("C:\\Documents and Settings\\HARRY\\Desktop\\FIXED Aging incident Report " + DateTime.Now.ToString("MM_dd_yyyy") + ".xls");
srcxlApp.Application.DisplayAlerts = false;
destxlApp.Application.DisplayAlerts = false;
destworkBook.Close(true, null, null);
destxlApp.Quit();
srcworkBook.Close(false, null, null);
srcxlApp.Quit();
}
}
}
You should be able to do this:
Excel.Range from = srcworkSheet.Range("C1:C100");
Excel.Range to = destworkSheet.Range("C1:C100");
from.Copy(to);
mrtig has a very elegant solution. But it won't work if you have the workbooks in separate instances of excel. So, the key is to open them in just one instance. I've modified your example to show using this approach:
public void CopyRanges()
{
// only one instance of excel
Excel.Application excelApplication = new Excel.Application();
srcPath="C:\\Documents and Settings\\HARRY\\Desktop\\incident.csv";
Excel.Workbook srcworkBook = excelApplication.Workbooks.Open(srcPath);
Excel.Worksheet srcworkSheet = srcworkBook.Worksheets.get_Item(1);
destPath = "C:\\Documents and Settings\\HARRY\\Desktop\\FIXED Aging incident Report.xls";
Excel.Workbook destworkBook = excelApplication.Workbooks.Open(destPath,0,false);
Excel.Worksheet destworkSheet = destworkBook.Worksheets.get_Item(1);
Excel.Range from = srcworkSheet.Range("C1:C100");
Excel.Range to = destworkSheet.Range("C1:C100");
// if you use 2 instances of excel, this will not work
from.Copy(to);
destworkBook.SaveAs("C:\\Documents and Settings\\HARRY\\Desktop\\FIXED Aging incident Report " + DateTime.Now.ToString("MM_dd_yyyy") + ".xls");
srcxlApp.Application.DisplayAlerts = false;
destxlApp.Application.DisplayAlerts = false;
destworkBook.Close(true, null, null);
srcworkBook.Close(false, null, null);
excelApplication.Quit();
}
For the First part of setting the same value for the entire range, instead of looping following will work out
range1 = workSheet.get_Range("A1:B100");
range1.Value = "Fixed";
And for copying you can try what #mrtig has suggested.
How can i display created arraylist in ms excel?
Please guide me..
Add a reference to Microsoft.Office.Interop.Excel assembly.
Then try this (just an idea, not full and perfect code):
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excel = new Excel.Application();
Excel.Workbook wb = excel.Workbooks.Open("filename");
Excel.Worksheet sh = wb.Sheets[1]; // or wb.Sheets["name"]
int row = 2;
foreach (string item in array)
{
sh.Cells[row,col].Value2 = item;
row++;
}
wb.Save();
wb.Close();
excel.Quit();