Excel search is duplicating found values - c#

I am trying to create a winform that will search an Excel sheet to find matching text values. When the value is found, I need to continue searching for any more values that are the same. After, the results are placed in a ListView.
Currently, my program is finding all matching values in each row, but it is finding the same row several times before moving onto the next.
Any help would be appreciated.
This is a snippet of the search code:
var app = new Microsoft.Office.Interop.Excel.Application();
var workbook = app.Workbooks.Open(#"//FilePath//");
var sheet = workbook.Worksheets["sheet1"];
Microsoft.Office.Interop.Excel.Range currentFind = null;
Microsoft.Office.Interop.Excel.Range firstFind = null;
object missing = System.Reflection.Missing.Value;
var range = (Microsoft.Office.Interop.Excel.Range)sheet.Columns["A:F"];
currentFind = range.Find(All, missing, Microsoft.Office.Interop.Excel.XlFindLookIn.xlValues,
Microsoft.Office.Interop.Excel.XlLookAt.xlPart, Microsoft.Office.Interop.Excel.XlSearchOrder.xlByRows,
Microsoft.Office.Interop.Excel.XlSearchDirection.xlNext, false, missing, missing);
var address = currentFind.Address;
while (currentFind != null)
{
if (firstFind == null)
{
firstFind = currentFind;
}
else if (currentFind.Address[Microsoft.Office.Interop.Excel.XlReferenceStyle.xlA1] ==
firstFind.Address[Microsoft.Office.Interop.Excel.XlReferenceStyle.xlA1])
{
break;
}
var row = currentFind.EntireRow;
object[,] rowvalues = row.Value2;
var column = currentFind.EntireColumn;
object[,] colvalues = column.Value2;
string[] arr = new string[6];
ListViewItem itm;
arr[0] = Convert.ToString(rowvalues[1, 1]);
arr[1] = Convert.ToString(rowvalues[1, 2]);
arr[2] = Convert.ToString(rowvalues[1, 3]);
arr[3] = Convert.ToString(rowvalues[1, 4]);
arr[4] = Convert.ToString(rowvalues[1, 5]);
arr[5] = Convert.ToString(rowvalues[1, 6]);
itm = new ListViewItem(arr);
listView1.Items.Add(itm);
currentFind = range.FindNext(currentFind);
}

Related

How to add pivot table filters with Microsoft.Office.Interop.Excel in C#

I create a pivot table based on an Excel (.xlsx) file. The program adds fields to rows, values, and the filter. Using PivotFilters.Add2 causes 0x800a03ec error which terminates the program. How to properly use PivotFilters.Add2?
I tried filtering on different fields with different data types. Also, I tried using Type.Missing in a place of unused arguments. There seems to be plenty of information of this method for VB, but not so much for C#.
Items selected in the filter should be between the two dates on the last line.
var xlApp = new Microsoft.Office.Interop.Excel.Application();
xlApp.Visible = true;
var workBook = xlApp.Workbooks.Open(spreadsheetLocation);
var workSheet1 = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets["Data"];
var workSheet2 = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets.Add();
Microsoft.Office.Interop.Excel.Range last = workSheet1.Cells.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
Microsoft.Office.Interop.Excel.Range range = workSheet1.get_Range("A1", last);
Microsoft.Office.Interop.Excel.PivotCaches pivotCaches = null;
Microsoft.Office.Interop.Excel.PivotCache pivotCache = null;
Microsoft.Office.Interop.Excel.PivotTable pivotTable = null;
Microsoft.Office.Interop.Excel.PivotFields pivotFields = null;
Microsoft.Office.Interop.Excel.PivotField filterField = null;
Microsoft.Office.Interop.Excel.PivotField accNumField = null;
Microsoft.Office.Interop.Excel.PivotField amountPaidField = null;
pivotCaches = workBook.PivotCaches();
pivotCache = pivotCaches.Create(XlPivotTableSourceType.xlDatabase, range);
pivotTable = pivotCache.CreatePivotTable(workSheet2.Cells[1,1]);
pivotFields = (Microsoft.Office.Interop.Excel.PivotFields)pivotTable.PivotFields();
amountPaidField = (Microsoft.Office.Interop.Excel.PivotField)pivotFields.Item("AmountPaid");
amountPaidField.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlDataField;
amountPaidField.NumberFormat = "$#,###,###.00";
accNumField = (Microsoft.Office.Interop.Excel.PivotField)pivotFields.Item("AccNumber");
accNumField.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlRowField;
filterField = (Microsoft.Office.Interop.Excel.PivotField)pivotFields.Item("AccDate");
filterField.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlPageField;
filterField.EnableMultiplePageItems = true;
filterField.PivotFilters.Add2(XlPivotFilterType.xlDateBetween, Type.Missing, DateTime.Now.AddDays(-30), DateTime.Now.AddDays(-20));
#First it deletes two rows and then it creates a pivot table#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
namespace ConsoleApplication4
{
class Program
{
public static string Column(int column)
{
column--;
if (column >= 0 && column < 26)
return ((char)('A' + column)).ToString();
else if (column > 25)
return Column(column / 26) + Column(column % 26 + 1);
else
throw new Exception("Invalid Column #" + (column + 1).ToString());
}
static void Main(string[] args)
{
try
{
string path = #"C:\Users\UX155512\Documents\Book1fd.xlsx";
var excelFile = new Application();
Workbook workBook = excelFile.Workbooks.Open(path);
Worksheet workSheet = workBook.Worksheets[1];
Worksheet pivotSheet = workBook.Worksheets.Add(
System.Reflection.Missing.Value,
workBook.Worksheets[workBook.Worksheets.Count],
1,
System.Reflection.Missing.Value);
Range last = workSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);
int lastRow = last.Row;
int lastCol = last.Column;
string lastColVal = Column(lastCol);
string lastFilledCol = lastColVal + lastRow.ToString();
Console.WriteLine(lastFilledCol);
Console.WriteLine(lastColVal);
Console.WriteLine(lastRow);
Console.WriteLine(lastCol);
for (int i = 1; i <= lastRow; i++)
{
if (workSheet.Cells[1][i].Value == ("HDR"))
{
workSheet.Rows[i].Delete();
Console.WriteLine("The Row Containing HDR has been deleted");
}
if (workSheet.Cells[1][i].Value == ("TRL"))
{
workSheet.Rows[i].Delete();
Console.WriteLine("The Row Containing TLR has been deleted");
}
}
Range lastRange = workSheet.Range["A1", lastFilledCol];
pivotSheet.Name = "Pivot Table";
Range range = pivotSheet.Cells[1, 1];
PivotCache pivotCache = (PivotCache)workBook.PivotCaches().Add(XlPivotTableSourceType.xlDatabase, lastRange);
PivotTable pivotTable = (PivotTable)pivotSheet.PivotTables().Add(PivotCache: pivotCache, TableDestination: range);
PivotField pivotField = (PivotField)pivotTable.PivotFields("Plan Number");
pivotField.Orientation = XlPivotFieldOrientation.xlRowField;
PivotField pivotField2 = (PivotField)pivotTable.PivotFields("Source");
pivotField2.Orientation = XlPivotFieldOrientation.xlColumnField;
PivotField pivotField3 = (PivotField)pivotTable.PivotFields("Total");
pivotField3.Orientation = XlPivotFieldOrientation.xlDataField;
pivotField3.Function = XlConsolidationFunction.xlSum;
workBook.SaveAs(#"C:\Users\UX155512\Documents\Excel Dump\Trial9.xlsx");
workBook.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.Read();
}
}
}
As mentioned above by Asger, the filter can't be added to a page field. Instead, the pivot item's visibility property has to be set.
var pivotItems = filterField.PivotItems();
DateTime date = Convert.ToDateTime(item.Name);
foreach (var item in pivotItems)
{
item.Visible = false;
if (date < DateTime.Now.AddDays(-30) || date > DateTime.Now.AddDays(-20))
{
item.Visible = true;
}
}
The best way to find the answer to pretty much ANY interop question is to record a macro then examine the source.

How to SetSourceData on a Chart. Getting error: "HRESULT E_FAIL has been returned from a call to a COM component"

I'm trying to create two charts on a pivot table. When I create the first one it's ok, but when I try to create the second one I'm getting this following error: "HRESULT E_FAIL has been returned from a call to a COM component"
chartPage.SetSourceData(oPivotTable.TableRange2, misValue);
Follow below the code to you guys understand what I'm doing
Workbook xlWorkBook = xlApp.Workbooks.Add (rootFile + "Template.xlsm");
Worksheet xlWorkSheet = (Worksheet) xlWorkBook.Worksheets.get_Item (1);
if (!Directory.Exists (rootFile)) {
Directory.CreateDirectory (rootFile);
}
string fileName = rootFile + report.Name + ".xlsm";
xlWorkSheet.Name = "Invoices";
List<Sheet> sheets = JsonConvert.DeserializeObject<List<Sheet>> (report.Definition);
var startCell = (Range) xlWorkSheet.Cells[1, 1];
var endCell = (Range) xlWorkSheet.Cells[invoices.Count () + creditNotes.Count (), properties.Count () + 1];
var writeRange = xlWorkSheet.Range[startCell, endCell];
writeRange.Value = dataSource;
int lastROW = xlWorkSheet.Cells[xlWorkSheet.Rows.Count, 1].End (XlDirection.xlUp).Row;
int LastCol = xlWorkSheet.Cells[1, xlWorkSheet.Columns.Count].End (XlDirection.xlToLeft).Column;
Range pRange = xlWorkSheet.Cells[1, 1].Resize (lastROW, LastCol);
pRange.Columns.AutoFit ();
foreach (var sheet in sheets) {
PivotCache oPivotCache = (PivotCache) xlWorkBook.PivotCaches ().Add (XlPivotTableSourceType.xlDatabase, pRange);
xlWorkBook.ShowPivotChartActiveFields = true;
Worksheet xlWorkSheetPivot = (Worksheet) xlWorkBook.Worksheets.Add (misValue);
xlWorkSheetPivot.Name = sheet.tabHeading;
xlWorkSheetPivot.Activate ();
foreach (Pivot pivot in sheet.pivots) {
Range last = GetRange (xlWorkSheetPivot);
PivotTable oPivotTable = (PivotTable) xlWorkSheetPivot.PivotTables ().Add (PivotCache: oPivotCache, TableDestination: last, TableName: pivot.title);
oPivotTable.SortUsingCustomLists = false;
foreach (var filter in pivot.filters) {
PivotField oPivotFieldrow1 = (PivotField) oPivotTable.PivotFields (filter.displayName);
oPivotFieldrow1.EnableMultiplePageItems = true;
oPivotFieldrow1.Orientation = XlPivotFieldOrientation.xlPageField;
oPivotFieldrow1.Name = filter.displayName;
if (!String.IsNullOrEmpty (filter.value)) {
oPivotFieldrow1.CurrentPage = filter.value;
}
}
foreach (var row in pivot.rows) {
PivotField oPivotFieldrow1 = (PivotField) oPivotTable.PivotFields (row.displayName);
oPivotFieldrow1.Orientation = XlPivotFieldOrientation.xlRowField;
oPivotFieldrow1.LayoutCompactRow = true;
oPivotFieldrow1.LayoutForm = XlLayoutFormType.xlOutline;
oPivotFieldrow1.Name = row.displayName;
}
foreach (var column in pivot.columns) {
PivotField oPivotFieldrow1 = (PivotField) oPivotTable.PivotFields (column.displayName);
oPivotFieldrow1.Orientation = XlPivotFieldOrientation.xlColumnField;
oPivotFieldrow1.LayoutCompactRow = true;
oPivotFieldrow1.LayoutForm = XlLayoutFormType.xlOutline;
oPivotFieldrow1.Name = column.displayName;
}
var functionToOrder = "";
foreach (var value in pivot.values) {
PivotField field = (PivotField) oPivotTable.PivotFields (value.displayName);
field.Orientation = XlPivotFieldOrientation.xlDataField;
field.NumberFormat = "0.00";
if (value.function != null)
field.Function = GetEnumExcel (value.function.name);
field.Caption = System.Text.RegularExpressions.Regex.Replace (field.Caption, #"[\d-]", string.Empty);
field.Name = System.Text.RegularExpressions.Regex.Replace (field.Name, #"[\d-]", string.Empty);
functionToOrder = field.Name;
}
if (pivot.pivotType == "Chart") {
ChartObjects xlCharts = (ChartObjects) xlWorkSheetPivot.ChartObjects (Type.Missing);
ChartObject myChart = (ChartObject) xlCharts.Add (oPivotTable.TableRange2.Left + 350, last.Top, 400, 200);
Chart chartPage = myChart.Chart;
chartPage.SetSourceData (oPivotTable.TableRange2, misValue);
chartPage.ChartType = (XlChartType) pivot.chartType.id;
}
if (pivot.values.Count > 1) {
oPivotTable.DataPivotField.Orientation = XlPivotFieldOrientation.xlColumnField;
}
//Order By Fields
if (pivot.fieldToOrder != null && pivot.orderType != 0 && (!string.IsNullOrEmpty (pivot.fieldToOrder.displayName) || pivot.fieldToOrder.function != null)) {
PivotField pivotField = oPivotTable.PivotFields (pivot.fieldToOrder.displayName);
var fieldToOrder = pivot.fieldToOrder.function == null ? pivot.fieldToOrder.displayName : pivot.fieldToOrder.function.name + " of " + pivot.fieldToOrder.displayName;
xlApp.Run ("UseOrderFunction", sheet.tabHeading, pivot.title, pivot.rows.FirstOrDefault ().displayName, pivot.orderType, fieldToOrder);
}
oPivotTable.RowAxisLayout (XlLayoutRowType.xlTabularRow);
if (pivot.topCount.HasValue && pivot.topCount > 0) {
var fieldToUseTop = pivot.fieldToOrder.function == null ? functionToOrder : pivot.fieldToOrder.function.name + " of " + pivot.fieldToOrder.displayName;
xlApp.Run ("UseTopFunction", sheet.tabHeading, pivot.title, pivot.rows.FirstOrDefault ().displayName, pivot.topCount, pivot.orderType, fieldToUseTop);
}
}
}
I expect this below works:
if (pivot.pivotType == "Chart") {
ChartObjects xlCharts = (ChartObjects) xlWorkSheetPivot.ChartObjects (Type.Missing);
ChartObject myChart = (ChartObject) xlCharts.Add (oPivotTable.TableRange2.Left + 350, last.Top, 400, 200);
Chart chartPage = myChart.Chart;
chartPage.SetSourceData (oPivotTable.TableRange2, misValue);
chartPage.ChartType = (XlChartType) pivot.chartType.id;
}

C# Appending list to excel file

so currently my code below generates a string and adds it to a list for each image file in a directory, then after its does adding to the list, it opens an excel file, appends the list, and formats it. Currently my problem is that my excel line is selecting the entireColumn and pasting the list, how can I get it to recognize how many strings are in the list and only append that many to the excel sheet.
//Fill A2:B6 with an array of values .
oRng = oSheet.get_Range("C2");
oRng.EntireColumn.Value2 = checkInformation.ToArray();
Here is my whole project
class Program
{
[STAThread]
static void Main(string[] args)
{
Microsoft.Office.Interop.Excel.Application oXL;
Microsoft.Office.Interop.Excel._Workbook oWB;
Microsoft.Office.Interop.Excel._Worksheet oSheet;
Microsoft.Office.Interop.Excel.Range oRng;
object misvalue = System.Reflection.Missing.Value;
Console.WriteLine("Initializing Check Parser Menu.....");
string dataPath = #"C:\Users\User\Desktop\Tesseract\Tesseract\tessdata";
string[] filePaths = Directory.GetFiles(#"C:\Users\User\Desktop\Tesseract\Tesseract\Check_Images", "*.png");
string checkData = "";
int checkCounter = 0;
List<string> checkInformation = new List<string>();
foreach (string filePath in filePaths)
{
checkCounter++;
Console.WriteLine("Initializing Check Parser... on Check: " + checkCounter);
using (TesseractEngine ocr = new TesseractEngine(dataPath, "eng", EngineMode.TesseractOnly))
{
using (Pix p = Pix.LoadFromFile(filePath))
{
using (Pix img = p.Scale(2, 3))
{
using (var page = ocr.Process(img))
{
string text = page.GetText();
if (text.Contains("Claim ID"))
{
int indexOfNone = text.IndexOf("NONE");
int indexOfClaimId = text.IndexOf("Claim ID");
int difference = indexOfClaimId - indexOfNone;
var dollarData = text.Substring(indexOfNone, difference);
int startingPoint = indexOfNone + (dollarData.Length - 6);
var dollarAmount = text.Substring(startingPoint, 6);
var claimIdData = text.Substring(indexOfClaimId, 14);
var claimInfoOutput = claimIdData + " Check Amount: " + dollarAmount;
Console.WriteLine(claimInfoOutput);
checkInformation.Add(claimInfoOutput);
}
else
{
Console.WriteLine("You will need to locate this check, there was an issue parsing " + "\n" + filePath);
Console.WriteLine("Press any Key to continue");
Console.ReadKey();
}
}
}
}
}
}
Console.WriteLine("Writing Data to Excel File... DONT TaCH");
try
{
//Start Excel and get Application object.
oXL = new Microsoft.Office.Interop.Excel.Application();
oXL.Visible = true;
//Get a new workbook.
oWB = (Microsoft.Office.Interop.Excel._Workbook)(oXL.Workbooks.Add(""));
oSheet = (Microsoft.Office.Interop.Excel._Worksheet)oWB.ActiveSheet;
//Add table headers going cell by cell. //Format A1:B1 as bold, vertical alignment = center.
oSheet.Cells[1, 1] = "Claim ID";
oSheet.Cells[1, 2] = "Check Amount";
oSheet.get_Range("A1", "B1").Font.Bold = true;
oSheet.get_Range("A1", "B1").VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
// Create an array to multiple values at once.
//Fill A2:B6 with an array of values .
oRng = oSheet.get_Range("C2");
oRng.Value2 = checkInformation.ToArray();
//oSheet.get_Range("A2", "B6").Value2 = checkInformation.ToArray();
//Fill A2 with a formula(=MID(C2,9,5)
oRng = oSheet.get_Range("A2", "A50");
oRng.Formula = "=MID(C2,9,5)";
//Fill B2 with a =RIGHT(C2,6)
oRng = oSheet.get_Range("B2", "B50");
oRng.Formula = "=RIGHT(C2,6)";
//AutoFit columns A:C.
oRng = oSheet.get_Range("A1", "C1");
oRng.EntireColumn.AutoFit();
oXL.Visible = false;
oXL.UserControl = false;
oWB.SaveAs("C:\\Users\\User\\Desktop\\Tesseract\\Tesseract\\excel\\checkdata.xlsx", Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault,
Type.Missing, Type.Missing,
false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
oWB.Close();
;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Okay I solved it guys sorry to bug you but heres what I did.
//Fill A2:B6 with an array of values .
string cellName;
int counter = 2;
foreach (var check in checkInformation)
{
cellName = "C" + counter.ToString();
oRng = oSheet.get_Range(cellName, cellName);
oRng.Value2 = check.ToString();
++counter;
}
and basically i just need to say for each item in my list this is the first cell name append the value.tostring

Excel range of non-consecutive rows to clipboard

I have a FindRange that finds rows with the text `€´(lblValutaTeken.Text) in my Excel sheet.
What I need to do is get the rows(multiple!) that contain the text and copy them to clipboard. My range is not consecutive rows, which is the basis of my despair.
So far I got this
object[,] cellValues = null;
try
{
Excel.Range currentFind = null;
Excel.Range firstFind = null;
var missing = Missing.Value;
Excel.Range RangeWithValutaSigns = xlApp.ActiveSheet.Range("g1", "g500");
currentFind = RangeWithValutaSigns.Find(lblValutaTeken.Text, missing,
Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false,
missing, missing);
while (currentFind != null)
{
if (firstFind == null)
{
firstFind = currentFind;
}
else if (currentFind.get_Address(Excel.XlReferenceStyle.xlA1)
== firstFind.get_Address(Excel.XlReferenceStyle.xlA1))
{
break;
}
Console.WriteLine("~~~~ currentFind.Row = " + currentFind.Row);
Excel.Range currentFindRow = currentFind.Range[("B" + currentFind.Row), ("H" + currentFind.Row)];
cellValues = (object[,])currentFindRow.Value2;
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(cellValues))
{
string name = descriptor.Name;
object value = descriptor.GetValue(cellValues);
Console.WriteLine("{0}={1}", name, value);
}
for (int j = 1; j < 8; j++)
{
Console.WriteLine(cellValues[i, j].ToString());
}
i = i + 1;
currentFind = RangeWithValutaSigns.FindNext(currentFind);
}
}
catch (Exception ex)
{
MessageBox.Show("Er is een fout gemaakt tijdens het kopiëren van de productregels uit de offerte naar het clipboard." + System.Environment.NewLine + System.Environment.NewLine + "Controleer of er een excel geopend is met daarin regels met productcodes uit de LookApp." + System.Environment.NewLine + System.Environment.NewLine + "Error message:" + System.Environment.NewLine + ex.Message);
}
Clipboard.SetDataObject(cellValues);
I don't know if this will help you or not, but here is my idea:
If you are searching for rows with some text criteria, why not create a string array with that criteria, and then filter your excel file based on your criteria, afterwards, copying those rows.
Example :
string[] Criteria = new string[1]
Criteria[0] = "Your Criteria"; (if the criteria can vary you can use * )
Criteria[1] = "Some other Criteria";
And then filter your excel sheet based on a criteria:
Create a range:
Xl.Range myRange = yourSheet.UsedRange;
next filter :
myRange.AutoFilter(7, Criteria[0], xl.XlAutoFilterOperator.xlOr, Criteria[1], true);
xl.Range my_Range= myRange.SpecialCells(xl.XlCellType.xlCellTypeVisible, Type.Missing);
And now all you need to do is select and copy your remaining visible rows and paste them.
Hopefully this will be of some help.
So, with putting answers from multiple other Q&A's together I came up with this. Not very elegant, but it does precisely what I wanted it to.
Step 1. Create a datatable
Step 2. Use Excel.Range.Find to find the ranges(=cells) that have my valutasign (is same as lblvalutasign.txt, for instance € or $ or CAD)
Step 3. Each time a range is found I use Range.Offset to put cellvalues into my datable in the corresponding column.
Step 4. Put the whole datatable into a datagridview. This can be a non-visible datagridview if you want. Lay-out the datagridview the way you want to.
Step 5. DataGridView.SelectAll() and copy to clipboard with
DataObject d = dataGridView1.GetClipboardContent();
Clipboard.SetDataObject(d);
Step 6. Use ctr+v to paste anywhere!
Excel.Application xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
Excel.Range myRange;
myRange = xlApp.ActiveSheet.UsedRange;
DataTable dtProductRowsFromExcel = new DataTable(); //to save all productrows form excel offer.
dtProductRowsFromExcel.Columns.Add("Code", typeof(String)); //column 1 Excel B
dtProductRowsFromExcel.Columns.Add("Amount", typeof(String)); //column 2 Excel C
dtProductRowsFromExcel.Columns.Add("Unit", typeof(String)); //column 3 Excel D
dtProductRowsFromExcel.Columns.Add("ValutaUnit", typeof(String)); //column 4 Excel E
dtProductRowsFromExcel.Columns.Add("PriceUnit", typeof(String)); //column 5 Excel F
dtProductRowsFromExcel.Columns.Add("ValutaTotal", typeof(String)); //column 6 Excel G
dtProductRowsFromExcel.Columns.Add("PriceTotal", typeof(String)); //column 7 Excel H
try
{
Excel.Range currentFind = null;
Excel.Range firstFind = null;
var missing = Missing.Value;
Excel.Range RangeWithValutaSigns = xlApp.ActiveSheet.Range("g1", "g500");
currentFind = RangeWithValutaSigns.Find(lblValutaTeken.Text, missing,
Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false,
missing, missing);
while (currentFind != null)
{
if (firstFind == null)
{
firstFind = currentFind;
}
else if (currentFind.get_Address(Excel.XlReferenceStyle.xlA1)
== firstFind.get_Address(Excel.XlReferenceStyle.xlA1))
{
break;
}
Console.WriteLine("~~~~ currentFind.Row = " + currentFind.Row);
string B = currentFind.Offset[0, -5].Value2.ToString();
string C = (currentFind.Offset[0, -4].Value2 != null) ? currentFind.Offset[0, -4].Value2.ToString() : "";
string D = (currentFind.Offset[0, -3].Value2 != null) ? currentFind.Offset[0, -3].Value2.ToString() : "";
string E = (currentFind.Offset[0, -2].Value2 != null) ? currentFind.Offset[0, -2].Value2.ToString() : "";
string F = (currentFind.Offset[0, -1].Value2 != null) ? currentFind.Offset[0, -1].Value2.ToString() : "";
string G = currentFind.Value2.ToString();
string H = (currentFind.Offset[0, 1].Value2 != null) ? currentFind.Offset[0, 1].Value2.ToString() : "";
dtProductRowsFromExcel.Rows.Add(B, C, D, E, F, G, H);
currentFind = RangeWithValutaSigns.FindNext(currentFind);
}
// to check datatable in output window use:
foreach (DataRow dataRow in dtProductRowsFromExcel.Rows)
{
foreach (var item in dataRow.ItemArray)
{
Console.WriteLine(item);
}
}
dataGridView1.ReadOnly = true;
dataGridView1.RowHeadersVisible = false;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.DataSource = dtProductRowsFromExcel;
dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
dataGridView1.SelectAll();
DataObject d = dataGridView1.GetClipboardContent();
Clipboard.SetDataObject(d);
}
catch (Exception ex)
{
MessageBox.Show("Error message:" + System.Environment.NewLine + ex.Message);
}

Exception from HRESULT: 0x800A03EC INDIRECT

I'm trying to run excel indirect function from c#. I used the following code but got the exception
"A first chance exception of type
'System.Runtime.InteropServices.COMException' occurred in
System.Dynamic.dll"
Additional information: Exception from HRESULT: 0x800A03EC
Excel.Range vehicle_makes_dropdown = xlWorkSheet1.get_Range("B2", "B101");
vehicle_makes_dropdown.Formula = "=indirect(A2)";
vehicle_makes_dropdown.Validation.Add(Excel.XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertInformation, XlFormatConditionOperator.xlEqual, vehicle_makes_dropdown.Formula, misValue);
vehicle_makes_dropdown.Validation.IgnoreBlank = true;
vehicle_makes_dropdown.Validation.InCellDropdown = true;
Updated Code is
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wlb = app.Workbooks.Open(#"D:\Templates2.xlsx");
Microsoft.Office.Interop.Excel.Worksheet MySheet = (Microsoft.Office.Interop.Excel.Worksheet)wlb.Sheets[1];
Microsoft.Office.Interop.Excel.Range oRange;
// Get Subject
// string subjetcs = string.Empty;
//List<Topics> lstsubject = PickSubject(out subjetcs);
AdminQuestionCommonModel objAdminQuestioncommonModel = new AdminQuestionCommonModel();
// _Question.BindQuestionDropDowns(objAdminQuestioncommonModel);
objAdminQuestioncommonModel.ExcelTopics = _Question.GetTopics(subjectId);
List<SubjectBO> lstTopics = GlobalService.GetAllTopicsandSubtopics(5, subjectId, 0); // get all topics of Subjects
//if (lstsubject.Count > 0)
if (lstTopics.Count > 0)
{
Microsoft.Office.Interop.Excel.Worksheet IDSheet = (Microsoft.Office.Interop.Excel.Worksheet)wlb.Sheets[2];
int rows = 1;
int subrows = 1;
IDSheet.Unprotect("123#");
//foreach (var item in lstsubject)
foreach (var Topic in lstTopics)
{
var TopicName = Topic.Topic_SubTopic.Trim();
TopicName = TopicName.Replace(".", "_").Replace("&", "_").Replace(" ", "_").Replace("__", "_");
// Add the header the first time through
IDSheet.Cells[rows, 1] = Topic.SubjectTopicId.ToString();
IDSheet.Cells[rows, 2] = TopicName;
// List<SubTopics> lst = PickSubTopic(item.TopicName, item.TopicID);
List<SubjectBO> lstsubtopics = _Question.GetSubTopics(subjectId, Topic.SubjectTopicId);
int startindex = subrows;
foreach (var subtopics in lstsubtopics)
{
IDSheet.Cells[subrows, 4] = subtopics.Topic_SubTopic;
IDSheet.Cells[subrows, 5] = subtopics.SubjectTopicId.ToString();
IDSheet.Cells[subrows, 6] = TopicName;
IDSheet.Cells[subrows, 7] = Topic.SubjectTopicId.ToString();
subrows++;
}
if (lstTopics.Count > 0)
{
wlb.Names.Add(TopicName, IDSheet.get_Range("D" + startindex + ":D" + (subrows - 1)));
}
subrows++;
rows++;
}
wlb.Names.Add("Topics", IDSheet.get_Range("B1:B" + (rows - 1)));
Microsoft.Office.Interop.Excel.Range Range = MySheet.get_Range("B2", "B800");
Range.Validation.Delete();
Range.NumberFormat = "Text";
//Range.Cells.Value = lstsubject[0].TopicName.ToString();
Range.Cells.Value = "Text";
Range.Validation.Add(Microsoft.Office.Interop.Excel.XlDVType.xlValidateList, Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertStop
, Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween
, Formula1: "=Topics"
);
Range.Validation.InCellDropdown = true;
Range.Validation.IgnoreBlank = true;
oRange = MySheet.get_Range("c2","c3");
oRange.Validation.Delete();
oRange.NumberFormat = "Text";
oRange.Validation.Add(Microsoft.Office.Interop.Excel.XlDVType.xlValidateList, Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertStop
, Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween
, Formula1: "=INDIRECT(B2)"
);
oRange.Validation.InCellDropdown = true;
oRange.Validation.IgnoreBlank = true;
IDSheet.Protect("123#");
//Range.Validation.InCellDropdown = true;
//Range.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.FromArgb(255, 217, 217, 0));
app.Visible = true;
}
You need to put double quotes around your cell reference inside the formula:
vehicle_makes_dropdown.Formula = "=indirect(""A2"")";
oRange.Validation.Add(Microsoft.Office.Interop.Excel.XlDVType.xlValidateList,
Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertStop,
Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween,
Formula1: "=INDIRECT(if(B2=\"\",A5000,B2))"
// see also http://user.qzone.qq.com/26149705/blog/1474296940

Categories

Resources