i need to find duplicate values in excel worksheet using conditional formating programmatically.
Tried this way, but in 6 line of code i've got COM exception
cannot cast to Excel.FormatCondition
Here's my code
Excel.Workbook xlWB = Application.ActiveWorkbook;
Excel.Worksheet xlWS = xlWB.ActiveSheet;
xlWS.Range["B2:B9"].Select();
Excel.Range xlS = Application.Selection;
xlS.FormatConditions.AddUniqueValues();
Excel.FormatCondition xlFC =
(Excel.FormatCondition)xlS.FormatConditions[xlS.FormatConditions.Count];
xlFC.SetFirstPriority();
Excel.FormatCondition xlFC1 = (Excel.FormatCondition)xlS.FormatConditions[1];
xlFC1.Interior.Pattern = Excel.XlPattern.xlPatternAutomatic;
xlFC1.Interior.TintAndShade = 0;
xlFC1.Interior.Color = ColorTranslator.FromOle(13551615);
Take a look at it MSDN Link
or you could possibly use something like this
Excel.Range usedRange = Worksheet.UsedRange;
usedRange.Interior.Color =
System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
FormatCondition format = (FormatCondition)(Worksheet.get_Range("A1:D13",
Type.Missing).FormatConditions.Add(XlFormatConditionType.xlExpression,
XlFormatConditionOperator.xlEqual,
"=$A1=$D1", Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing));
format.Font.Bold = true;
format.Interior.Color =
System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow);//Duplicate values
Hope this helps ..it worked for me
Related
I am reading an Excel sheet programmatically using Microsoft.Office.Interop.Excel in C#.
I am able to read it row by row and converting each row to a string arrray. Then, I am adding these rows to a DataTable.
Every thing works fine except the one of the column in the Excel contains Date values, and when I fetch it from the Excel Range object and cast it to string array, the date values gets converted to some sort of decimal numbers.
For e.g.-
If the date value is '6/4/2016 8:14:39 PM', I get the value as '42522.5224305556'
If the date value is '5/27/2016 1:10:12 PM', I get the value as '42517.54875'
Below is my code-
private System.Data.DataTable GetTicketsFromExcel(string excelFilePath)
{
System.Data.DataTable dtblTickets = new System.Data.DataTable();
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Worksheet ws = new Worksheet();
Workbook wb = null;
try
{
wb = excelApp.Workbooks.Open(excelFilePath, Type.Missing, Type.Missing,
Type.Missing, Type.Missing,
Type.Missing, Type.Missing,
Type.Missing, Type.Missing,
Type.Missing, Type.Missing,
Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Sheets.get_Item(1);
Range usedRange = ws.UsedRange;
Range rowRange;
string[] lsRow = null;
for (int i = 1; i <= usedRange.Columns.Count; i++)
{
dtblTickets.Columns.Add(usedRange.Cells[5, i].Value.ToString());
}
string sortColumn = "Reported On";
string sortDirection = "DESC";
dtblTickets.Columns[sortColumn].DataType = typeof(DateTime);
for (int row = 6; row <= usedRange.Rows.Count; row++)
{
//dtblTickets.Columns.Add()
rowRange = usedRange.Rows[row];
object[,] cellValues = (object[,])rowRange.Value2;
lsRow = cellValues.Cast<object>().Select(o => Convert.ToString(o)).ToArray<string>();
dtblTickets.Rows.Add(lsRow.ToArray());
}
dtblTickets.DefaultView.Sort = sortColumn + " " + sortDirection;
dtblTickets = dtblTickets.DefaultView.ToTable();
}
catch (Exception ex)
{
}
finally
{
wb.Close();
excelApp.Quit();
Marshal.ReleaseComObject(ws);
Marshal.ReleaseComObject(wb);
Marshal.ReleaseComObject(excelApp);
ws = null;
wb = null;
excelApp = null;
}
return dtblTickets;
}
Please note-
I don't want to use OLEDB to read and export this
I want to able to read the Excel row by row (without extracting each cell value and converting them)
I don't want to convert/format the original Excel document data
Can someone please help me with this?
Not quite sure, if you want to solve the problem this way, but one way is to change the property of the Cells (or the whole row or column) in Excel.
Right click on a Cell
Format Cells
Under "Number" select Category "Text" for the Cells.
I've tested it and it worked.
I have created a set of code to export images from my Image folder into Excel using Microsoft Interop, now I want to change my codes from Microsoft Interop to EPPlus.
Can someone help me with this?
This is my codes:
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
string[] filesindirectory = Directory.GetFiles(Server.MapPath("~/Image"));
int count = 0;
foreach (string img in filesindirectory)
{
count++;
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets.Add();
System.Web.UI.WebControls.Image TEST_IMAGE = new System.Web.UI.WebControls.Image();
worksheet.Name = "Title- " + count;
TEST_IMAGE.ImageUrl = "Image/" + Path.GetFileName(img);
TEST_IMAGE.ImageUrl = this.GetAbsoluteUrl(TEST_IMAGE.ImageUrl);
worksheet.Shapes.AddPicture(TEST_IMAGE.ImageUrl, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, 50, 50, 300, 300);
}
workbook.Worksheets["Sheet1"].Delete();
workbook.Worksheets["Sheet2"].Delete();
workbook.Worksheets["Sheet3"].Delete();
workbook.SaveAs(#"C:\Users\user\Desktop\Test\" + datetime.ToString("dd-MM-yyyy_hh-mm-ss") + ".xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
app.Quit();
Thanks.
To read an image into excel via epplus you can use this as an example (it will also show you how to setup a new workbook from scratch):
Weird behavior when setting a row's height on EPPlus
To delete a worksheet you can do that like this:
using (var pack = new ExcelPackage(existingFile))
{
var ws = pack.Workbook.Worksheets.Add("sheet1");
pack.Workbook.Worksheets.Delete(ws);
...
}
But if you are just trying to clean out the default sheets created by excel when you create a new file you DONT need to do that with EPPlus - by default there are no sheet when creating a new package (i.e. workbook). It is up to the programmer to add sheets and it will throw an error if there is not at least one.
Ok, so here is the scoop. I have an excel sheet that holds quote numbers for clients all stored in the C column in my worksheet. I have it so when selected the program will take the quote number from the datagridview and search for it in excel. Here is the code :
public static string pQuoteHolder;
file = Path.Combine(Application.StartupPath, "__Quote_Tracker.xlsm");
Excel.Application xlapp = new Excel.Application();
Excel.Workbook workbook = xlapp.Workbooks.Open(file);
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets[1];
Excel.Range currentFind = null;
Excel.Range firstFind = null;
Excel.Range range;
Excel.Range clients = xlapp.get_Range("C1", "C500");
pQuoteHolder = Convert.ToString(dataGridView2.CurrentRow.Cells[1].Value);
worksheet = (Excel.Worksheet)workbook.Sheets[1];
currentFind = clients.Find(pQuoteHolder, Type.Missing, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false, Type.Missing, Type.Missing);
if (currentFind == null)
{
MessageBox.Show("Nobody was found.");
}
So here is the problem, I see from debugging that qQuoteHolder is getting the correct value from datagridview, I can see for myself that all quote numbers in my excel sheet are indeed all in the C column and within range, so why is currentfind returning null? I am still learning excel and c#, Did I manage to code the range.Find method incorrectly?
Thanks in advance!
I’m trying to export a datagridview to an excel. I've found a really good solution ,copy-paste solution , but this exception appears.
This is my code, the same code that the solution I've found.
void botonCP_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application xlexcel;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlexcel = new Microsoft.Office.Interop.Excel.Application();
xlexcel.Visible = true;
xlWorkBook = xlexcel.Workbooks.Add(misValue);
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Microsoft.Office.Interop.Excel.Range CR = (Microsoft.Office.Interop.Excel.Range)xlWorkSheet.Cells[1, 1];
CR.Select();
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);
}
In my opinion, interop is infuriatingly irksome to use if you don't need to. Freeing up resources is a PIA and one often seems to encounter these little issues (admittedly, this could be my lack of knowledge on the subject!).
For me, I'd just use a library such as EPPlus to acheive this.
Something like this ought to serve well and would (IMO) be easier to write, manage and debug:
//Get DataGridView into a DataTable:
var bindingSource = (BindingSource)dataGridView.DataSource;
var dataView = (DataView)bindingSource.List;
var dataTable = dataView.Table;
//Create a Spreadsheet
using (ExcelPackage excelPackage = new ExcelPackage())
{
ExcelWorksheet ws = excelPackage.Workbook.Worksheets.Add("DataExport");
ws.Cells[1,1].LoadFromDataTable(dataTable, PrintHeaders:true);
//Write to an outputstream:
excelPackage.SaveAs(outputStream);
//or filesystem:
excelPackage.SaveAs(new FileInfo(#"C:\Temp\Export.xlsx"));
}
Much easier!
I create an Excel file from c# with data validation-it seem like combo with chosen possibility
string mList1 = "=ProductCode";
oRng = oSheet.get_Range("H8", "H9");
oRng.Name = "ProductCode";
int t = dt.Rows.Count + 2;
string st = "F" + t;
oRng = oSheet.get_Range("F2", st);
oRng.Validation.Add(XlDVType.xlValidateList,
XlDVAlertStyle.xlValidAlertStop,
Missing.Value, mList1, Missing.Value);
Now I want to read the Excel file and also the chosen item from the combo. I have successfully read all the data but the data validation.
Read the data-
Microsoft.Office.Interop.Excel.Application ExcelObj = null;
ExcelObj = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook theWorkbook = ExcelObj.Workbooks.Open("C:\\Documents and Settings\\rachelg\\My Documents\\xxx.xls"
,Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Sheets sheets = theWorkbook.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(1);
for(int x = 1; x <= 5; x++)
{
string sd = ((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[x, 1]).Text.ToString();
System.Console.WriteLine(sd);//this one column
}
in different column I have the data validation but I don't know to access into it.
That seems a bit much for what is largely a simple operation.
Whilst not answering your question directly, this post I made a while back might help: accessing data record from Excel in VB.NET.