c# Getting a row in an excel file throws TargetInvocationException - c#

I am making a program to manage different projects for a company, the idea is that you put some info and it writes it into an excel file.
The excel files are names ("FINANZAS - ") + Current Year
The idea is that it detects the current year with DateTime and if the excel file for that year doesnt exists it creates it. This is my code:
MyApp = new Excel.Application();
MyApp.Visible = false;
if (!File.Exists("FINANZAS - " + DateTime.Now.Year.ToString() + ".xlsx")) { File.Copy(rutaPlantilla, "FINANZAS ARAINCO - " + DateTime.Now.Year.ToString() + ".xlsx"); }
MyBook = MyApp.Workbooks.Open(#"C:\Users\Sebastian\Documents\Visual Studio 2015\Projects\Finanzas ARAINCO\Finanzas ARAINCO\bin\Debug\FINANZAS ARAINCO - " + DateTime.Now.Year.ToString() + ".xlsx");
MySheet = (Excel.Worksheet)MyBook.Sheets[1];
lastRow = MySheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row + 1;
The problem comes when I try changing the date to test it with other years, I tried switching it to 2018 for testing but it throws me a TargetInvocationException on the last row (the one that, ironically, I use to detect the last row on excel)
I dont know if this is caused by something on the excel part of the code or if it has something to do with changing the date manually to 2018

Related

C# add formula in a cell programatically

I'm working with Visual Studio 9 and I'm using Microsoft.Office.Interop.Excel to handle Excel files from a program
To add a formula in a cell I use
xlWorkSheet.Cells[cwrite, j + 2].Formula = " =SUM(B" + cwrite.ToString() + "; 3)";
Note the space between " and =
In This case, the formula displayed in the right cell, but is not executed, due to space
However, if I suppress the space
xlWorkSheet.Cells[cwrite, j + 2].Formula = "=SUM(B" + cwrite.ToString() + "; 3)";
I got the error Error: Excepción de HRESULT: 0x800A03EC Line: System.Dynamic
Any Clue??
Thanks
David

Why is an # symbol after = symbol in excel formula with EPPLUS?

This is how the formula appears in excel:
I want to use Forecast formula in Excel with EPPLUS from c#. The formula in the code is correct but in Excel appears =#FORECAST(params).
ExcelRange targetDate = sheet.Cells[listItems + 2, 2];
ExcelRange values = sheet.Cells[2, 3, listItems+1, 3];
ExcelRange timeLine = sheet.Cells[2, 2, listItems+1, 2];
sheet.Cells[8, 4].Formula = "=FORECAST.ETS(" + targetDate + "," + values + "," + timeLine + ",1,1)";
sheet.Cells[8, 4].Calculate();
I want to trim the # from the formula in the excel file, like this:
=FORECAST.ETS(B8,C2:C7,B2:B7,1,1)
In code you don't need to put the '=' character
Just use:
sheet.Cells[8, 4].Formula = "FORECAST.ETS(" + targetDate + "," + values + "," + timeLine + ",1,1)";
Similar Problem
I'm having a similar problem with a different formula:
worksheet.Cells[y, x].Formula = "SUMME(C5:C35)";
gave me =#SUMME(C5:C35) within Excel.
Instead of =SUMME(C5:C35).
Solution
It seems that EPPLUS has problems with the German formula. The problem disappears when I use:
worksheet.Cells[y, x].Formula = "SUM(C5:C35)";
My generated Excel now looks like this: =SUMME(C5:C35) (which is what I need)
I know it's not the answer to the exact problem mentioned above. But I thought it might help someone. And maybe serves as a hint to the original question.

WriteXML, ReadXML Issue with Table Name

I have a program where I run a query and store data in a DataTable. I then allow the user to save that DataTable.WriteXML. The problem I have is that I want to read that saved file (XML file) into another DataTable with a different name - and it does not allow it! It gives me an error "Error while loading Results Table to File: Data Table: 'ImportTable' does not match to any DataTable in Source"
Now I believe this message is telling me that the XML contains a different table name than the DataTable I am trying to ReadXML into it. I have tried setting the TableName property to blank - but that does not make any difference.
So - my question is how do others get around this issue? I am using the standard DataTable.WriteXML(filename) - and DataTable.ReadXML method calls. AND due to some design issues - I do need to have the import DataTable named differently than the one used to export the data.
Is there a different way to write out and read in the data in the DataTable that will get around this issue?
Sample code - showing the issue
In the form load - create two tables - one named Export the other Import. Create a structure for Export - and populate it with 10 records.
private void Form_Main_Load(object sender, EventArgs e)
{
ExportTable = new DataTable("Export");
ImportTable = new DataTable("Import");
ExportTable.Columns.Add("ID", Type.GetType("System.Int32"));
ExportTable.Columns.Add("Name", Type.GetType("System.String"));
ExportTable.Columns.Add("Amount", Type.GetType("System.Int32"));
// Populate the first one
DataRow workRow;
for (int i = 0; i <= 9; i++)
{
workRow = ExportTable.NewRow();
workRow[0] = i;
workRow[1] = "CustName" + i.ToString();
workRow[2] = i;
ExportTable.Rows.Add(workRow);
}
}
Then create two buttons - one for exporting the data - the other for importing the data.
private void button_Export_Click(object sender, EventArgs e)
{
ExportTable.WriteXml("c:\\Temp\\TableOut.xml");
}
private void button_Import_Click(object sender, EventArgs e)
{
ImportTable.ReadXmlSchema("c:\\Temp\\TableOut.xml");
ImportTable.ReadXml("c:\\Temp\\TableOut.xml");
}
Run the program - export the data - then click on the Import button. When you do - you will get the error - "DataTable 'Import' does not match to any DataTable in source."
Now - I realize it is because the XML has the Export table name embedded in the XML. In my case I need to import that data into a DataTable with a different name - and I am wondering how (and if) others have dealt withi this in the past? Did you manually change the name in the XML? Did you temporarily change the datatable name? OR is there another better way around this issue of trying to use the READXML method of a DataTable?
Ok - I have been playing around with this - and have a solution. Not sure it is the best (and I would appreciate any comments as to how I might do this better).
Basically what I had to do was write the XML out to a string reader - change the table name for the schema and the record elements. Both the <> and tags.
Then when I read it in - I had to do the reverse - basically read the file into a string - then change all the table names back to what I needed them to be. Then I had to write the file out to disk (temporary file) - and then use the ReadXML method to read that temp file and then delete the file.
I am not sure why the ReadXML with a string reader did not work (it seems to be a valid parameter) - but I had found a few posts that stated there were issues with the READXML method and string readers - so I simply wrote it out to file and used READXML with the file name - and it worked fine.
I hope this helps others - even if it is not the 'best' solution - maybe someone else can improve on it.
Write XML
// Write XML
StringWriter sw = new StringWriter();
ResultDT.WriteXml(sw, XmlWriteMode.WriteSchema);
string OutputXML = sw.ToString();
// now replace the Table Name
OutputXML = OutputXML.Replace("<" + ResultDT.TableName + ">", "<" + "ExportTable" + ">");
OutputXML = OutputXML.Replace("</" + ResultDT.TableName + ">", "</" + "ExportTable" + ">");
OutputXML = OutputXML.Replace("MainDataTable=\"" + ResultDT.TableName + "\"", "MainDataTable=\"" + "ExportTable" + "\"");
OutputXML = OutputXML.Replace("name=\"" + ResultDT.TableName + "\"", "name=\"" + "ExportTable" + "\"");
System.IO.File.WriteAllText(fileName, OutputXML);
Read XML
// Read XML
InputXML = System.IO.File.ReadAllText(fileName);
// now replace the Table Name
InputXML = InputXML.Replace("<" + "ExportTable" + ">", "<" + ResultTable.TableName + ">");
InputXML = InputXML.Replace("</" + "ExportTable" + ">", "</" + ResultTable.TableName + ">");
InputXML = InputXML.Replace("MainDataTable=\"" + "ExportTable" + "\"", "MainDataTable=\"" + ResultTable.TableName + "\"");
InputXML = InputXML.Replace("name=\"" + "ExportTable" + "\"", "name=\"" + ResultTable.TableName + "\"");
string TempFileName = "TempDumpFile.idt";
System.IO.File.WriteAllText(TempFileName, InputXML);
ResultTable.ReadXmlSchema(TempFileName);
ResultTable.ReadXml(TempFileName);
System.IO.File.Delete(TempFileName);

Writing and Reading excel files in C#

I am writing a program that takes data from a website via selenium web driver. I am trying to create football fixture for our projects.
I am so far, I accomplished to take date and time, team names and scores from the website. Also still trying writing on txt file, but it gets little messy while writing on txt file
How do I accomplish writing on excel file, and reading?
I want to write like that
Date-Time First-Team Second-Team Score Statistics
28/07 19:00 AM AVB 2-1 Shot 13123 Pass 65465 ...
28/07 20:00 BM BVB 2-2 Shot 13123 Pass 65465 ...
28/07 20:00 CM CVB 2-3 Shot 13123 Pass 65465 ...
And this is my part of my code :
StreamWriter file = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Test" + "\\" + pathName + "\\" + subFile + "\\" + pathName + ".txt", false);
for (int k = 2; k > 1; k--)
{
//doing some stuff
}
Writing part:
for (int x = 0; x <dT.Count; x++)
{
file.Write(dateTime[x] + " " + firstTeam[x] + " "
+ secondTeam[x] + " " + firstHalf[x] + " " + secondHalf[x] + " ")
for (int i = 0; i < total_FS.Count(); i++)
{
int index = total_FS[i].Length;
if (total_FS[i][index-1].ToString() != " " && total_FS[i] != "-")
{
file.Write(total_FS[i]);
}
else
{
SpaceC++;
if (total_FS[i][index - 1].ToString() == " ")
file.Write(total_FS[i]);
}
if (SpaceC == 9)
{
file.Write("\n");
SpaceC = 0;
break;
}
}
}
There are few cool libraries that you can use to easy read and write excel files. You can reference them in your project and easily create/modify spreadsheets.
EPPlus
Very developer friendly and easy to use.
EPPlus - codeplex source
Simple tutorial
NOPI
NOPI - codeplex source
DocumentFormat.OpenXml 
It provides strongly typed classes for spreadsheet objects and seems to be fairly easy to work with.
DocumentFormat.OpenXml site
DocumentFormat.OpenXml tutorial
Open XML SDK 2.0 for Microsoft Office
Provides strongly typed classes / easy to work with.
Open XML SDK 2.0 - MSDN
ClosedXML - The easy way to OpenXML
ClosedXML makes it easier for developers to create (.xlsx, .xlsm, etc) files.
ClosedXML - repository hosted at GitHub
ClosedXML - codeplex source
SpreadsheetGear
*Paid - library to import / export Excel workbooks in ASP.NET
SpreadsheetGear site
Instead of creating XLS file, make a CSV text file that can be opened with Excel. Fields are comma separated and each line represents a record.
field11,field12
field21,field22
If a field contains inner commas, it needs to be wrapped in double quotation marks.
"field11(row1,column1)", field12
field21, field22
If a field contains double quotation marks, they need to be escaped. But you can use CsvHelper to do the job. Grab it from Nuget
PM> Install-Package CsvHelper
An example on how to use it.
using(var textWriter = new StreamWriter(#"C:\mypath\myfile.csv")
{
var writer = new CsvWriter(textWriter);
writer.Configuration.Delimiter = ",";
foreach (var item in list)
{
csv.WriteField("field11");
csv.WriteField("field12");
csv.NextRecord();
}
}
Full documentation can be found here.

Remove mask from columns in export CSV File in C#

I am exporting a csv file and getting the date field and phone number field masked as shown in the image below. The problem occurs only when I open the exported file in Microsoft Excel not on other platforms
What I want to do is remove the mask and show the birth date and number properly as: birth date: "12/11/2016" and number as "123456789".
Note: birth date is datetime AND cell_phone or mobile number is string
The code I used to create this is as follows:
foreach (EmployeeDataExportObject item1 in _obj_distinct_company)
{
sb.Append(string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21}"
, item1.client_id
, item1.employee_number
, item1.employee_status_type
, item1.first_name.Replace(",", "")
, item1.middle_name.Replace(",", "")
, item1.last_name.Replace(",", "")
, '"' + item1.ssn.ToString() + '"'
, '"' + birth_date.ToString("MM-dd-yyyy") + '"' //problem is on this part
, Address.Replace(",", "")
, item1.address2.Replace(",", "")
, item1.city
, item1.state
, item1.zip_code
, item1.country
, '"' + item1.cell_phone.ToString().Replace("-", "").Replace("(", "").Replace(")", "").Replace(".", "").Replace(" ", "") + '"' //problem is on this part
, item1.pay_rate1
, item1.pay_rate_amount1.ToString("0.00")
, item1.pay_rate2
, item1.pay_rate_amount2.ToString("0.00")
, item1.employee_status_type
, item1.termination_reason.Replace(",", " ")
, item1.termination_date.ToString("MM-dd-yyyy"))
+ Environment.NewLine);
}
_fileName = item.company_name;
if (!Directory.Exists(paychex_folder))
Directory.CreateDirectory(paychex_folder);
filepath = paychex_folder + _fileName + ".csv";
File.WriteAllText(filepath, sb.ToString());
}
What do you mean by masked, can you attach a screenshot of the excel file?
If a column with a date in is not wide enough, the value is shown as ###### - is this the problem you are having?
It's actually easier to create an XLSX file using a library like EPPLus. XSLX files are zipped XML files which can be generated without having Excel installed. With EPPlus you can fill a sheet with data from a DataTable or collection with a simple call to LoadFromDatatable or LoadFromCollection, eg:
FileInfo targetFile = new FileInfo(targetFile);
using (var excelFile = new ExcelPackage(targetFile))
{
var sheet = excelFile.Workbook.Worksheets.Add("Sheet1");
sheet.LoadFromCollection(_obj_distinct_company, PrintHeaders: true);
excelFile.Save();
}
EPPlus takes care to serialize dates in the decimal format (OA Date) expected by Excel.
LoadFromCollection returns an ExcelRange object which you can use to further format rows and columns, or create a named table, eg:
var range1=sheet.LoadFromCollection(_obj_distinct_company, PrintHeaders: true);
var table = sheet.Tables.Add(range, "Companies");
table.TableStyle = TableStyles.Light2;

Categories