convert MSProject.Task to System.Tables? - c#

Is there any way to convert MSProject.Project that I am reading from an .mpp file to a DataSet?
Or it is impossible is the first time I use this tool from MSProject.Project
public new string Load(string fileName)
{
MSProject.ApplicationClass app = null;
string retVal = "";
List<MSProject.Task> tasks = new List<MSProject.Task>();
DataSet Datos = new DataSet();
try
{
// execute the Microsoft Project Application
app = new MSProject.ApplicationClass();
// Do not display Microsoft Project
app.Visible = false;
// open the project file.
if (app.FileOpen(fileName, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, MSProject.PjPoolOpen.pjPoolReadOnly, Type.Missing, Type.Missing, Type.Missing, Type.Missing))
{
// go through all the open projects--there should only be one
foreach (MSProject.Project proj in app.Projects)
{
// go through all the tasks in the project
foreach (MSProject.Task task in proj.Tasks)
{
// add Microsoft Project Task to arraylist
Datos.Tables.Add(task);
//tasks.Add(task);
}
}
}
else
{
retVal = "The MS Project file " + fileName + " could not be opened.";
}
}
catch (Exception ex)
{
retVal = "Could not process the MS Project file " + fileName + "." + System.Environment.NewLine + ex.Message + System.Environment.NewLine + ex.StackTrace;
}
// close the application if is was opened.
if (app != null)
{
app.Quit(MSProject.PjSaveType.pjDoNotSave);
}
return retVal;
}
I already managed to pass it to a list<> but it would work better to have it in a DataSet
It is the section that I have commented here
foreach (MSProject.Task task in proj.Tasks)
{
// add Microsoft Project Task to arraylist
Datos.Tables.Add(task);
//tasks.Add(task);
}
The error is as follows:
Argument 1: cannot be converted from 'Microsoft.Office.Interop.MSProject.Task' to 'System.Data.DataTable'

Related

C# Excel.Interop issues

Brief details:
Running Office 360 with Excel 64bit installed.
Application is built on .NET 4.6 and CPU type is set to x64
The code that's not working - line marked where it fails
public bool CreateInvoice()
{
try
{
//Write file
var setting = new Classes.Settings();
string WritePath = setting.DefaultSavePath + "\\Invoices\\" + InvoiceDetails.CustomerID + "\\" + InvoiceDetails.InvoiceNumber + ".xlsx";
if (!System.IO.Directory.Exists(setting.DefaultSavePath + "\\Invoices\\" + InvoiceDetails.CustomerID))
System.IO.Directory.CreateDirectory(setting.DefaultSavePath + "\\Invoices\\" + InvoiceDetails.CustomerID);
if (System.IO.File.Exists(WritePath))
System.IO.File.Delete(WritePath);
System.IO.File.WriteAllBytes(WritePath, AccountManagement.Properties.Resources.Invoice);
//Prepare Excel
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbooks xlWorkBooks = null;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook = null;
Microsoft.Office.Interop.Excel.Sheets xlSheets = null;
Microsoft.Office.Interop.Excel.Worksheet xlExportSheet = null;
Classes.GetExcelProcessID getExcelProcessID = new GetExcelProcessID();
xlWorkBooks = xlApp.Workbooks; //***********FAILS HERE*************
xlWorkBook = xlWorkBooks.Add(WritePath);
xlSheets = xlApp.Worksheets;
xlExportSheet = (Microsoft.Office.Interop.Excel.Worksheet)(xlSheets[1]);
var cells = xlExportSheet.Cells;
var Process = Classes.GetExcelProcessID.ExcelProcesID(xlApp);
try
{
xlApp.Visible = false;
xlApp.DisplayAlerts = false;
//This is where I make my edits.
xlWorkBook.SaveAs(WritePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
xlWorkBook.ExportAsFixedFormat(Microsoft.Office.Interop.Excel.XlFixedFormatType.xlTypePDF, setting.DefaultSavePath + "\\Invoices\\" + InvoiceDetails.CustomerID + "\\" + InvoiceDetails.InvoiceNumber + ".pdf");
InvoiceSavePath = setting.DefaultSavePath + "\\Invoices\\" + InvoiceDetails.CustomerID + "\\" + InvoiceDetails.InvoiceNumber + ".pdf";
InvoiceDetails.InvoiceSavePath = InvoiceSavePath;
}
catch (Exception ex)
{
return false;
}
finally
{
//Ensue all COM objects are closed and realesed or EXCEl will remain open.
xlWorkBook.Close(0, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
xlWorkBooks.Close();
//xlApp.Application.Quit();
xlApp.Quit();
while (Marshal.FinalReleaseComObject(xlApp) != 0) { }
while (Marshal.FinalReleaseComObject(xlWorkBooks) != 0) { }
while (Marshal.FinalReleaseComObject(xlWorkBook) != 0) { }
while (Marshal.FinalReleaseComObject(xlSheets) != 0) { }
while (Marshal.FinalReleaseComObject(xlExportSheet) != 0) { }
while (Marshal.FinalReleaseComObject(cells) != 0) { }
xlApp = null;
xlWorkBooks = null;
xlWorkBook = null;
xlSheets = null;
xlExportSheet = null;
cells = null;
try
{
Process.Kill();
}
catch
{
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
return true;
}
This is the exception I keep getting.
Unable to cast COM object of type 'Microsoft.Office.Interop.Excel.ApplicationClass' to interface type 'Microsoft.Office.Interop.Excel._Application'
I initially thought the issue was about my application possibly still being built at x86 but I have a interop function with Word that runs perfectly fine - and that's 64bit.
I've tried google but all the fixes are to do with 64bit office and a 32bit application.
Any tips?

C# Excel PivotItem Visibility

I want to use C# to get the values of the checkboxes from the Excel Filter.
so ...
Proj_1 should be true
Proj_2 should be true
Proj_3 should be false
Proj_4 should be false
Below is the code I am currently using but item.Visible is ALWAYS false no matter if the UI has a check by it or not (unless I uncheck Select Multiple Items) but I need that checked
foreach (PivotField fld in pivotFields)
{
Console.WriteLine(fld.Name + " -- " + fld.Orientation + " -- " + fld.EnableItemSelection + " -- " + fld.EnableMultiplePageItems + " -- ");
foreach (PivotItem item in fld.PivotItems(Type.Missing))
{
if (item.Visible == true)
{
Console.WriteLine("Item" + item.Name + " in field " + fld.Name + "is Visible (Selected)");
}
else
{
Console.WriteLine("Item" + item.Name + " in field " + fld.Name + "is Hidden (Not Selected)");
}
}
}
This is something that works, if the Microsoft.Office.Interop.Excel library is added:
namespace ExcelAtSomething
{
using System;
using Excel = Microsoft.Office.Interop.Excel;
class Startup
{
static void Main()
{
string filePath = #"C:\Users\stackoverflow\Desktop\Sample.xlsx";
Excel.Application excel = new Excel.Application();
excel.Visible = true;
excel.EnableAnimations = true;
Excel.Workbook wkb = Open(excel, filePath);
foreach (Excel.Worksheet xlWorksheet in wkb.Worksheets)
{
Excel.PivotTables pivotTablesCollection = xlWorksheet.PivotTables();
if (pivotTablesCollection.Count > 0)
{
for (int i = 1; i <= pivotTablesCollection.Count; i++)
{
Excel.PivotTable currentPivotTable = pivotTablesCollection.Item(i);
Console.WriteLine($"Table is named -> {currentPivotTable.Name}");
foreach (Excel.PivotField pivotField in currentPivotTable.PivotFields())
{
Console.WriteLine($"\nField is named -> {pivotField.Name}");
foreach (Excel.PivotItem visibleItems in pivotField.VisibleItems)
{
Console.WriteLine($"Visible item name -> {visibleItems.Name}");
}
foreach (Excel.PivotItem PivotItem in pivotField.PivotItems())
{
Console.WriteLine($"Item is named -> {PivotItem.Name}");
Console.WriteLine(PivotItem.Visible);
}
}
}
}
}
excel.EnableAnimations = true;
wkb.Close(true);
excel.Quit();
Console.WriteLine("Finished!");
}
private static Excel.Workbook Open(Excel.Application excelInstance,
string fileName, bool readOnly = false,
bool editable = true, bool updateLinks = true)
{
Excel.Workbook book = excelInstance.Workbooks.Open(
fileName, updateLinks, readOnly,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
return book;
}
}
}
The trick is that except for PivotItem, there is a PivotField, which has a list of its visible items. If you display these, then only the visible ones are displayed:
Playing a bit and probably making custom a function, that returns the non-visible items, which are not in that list is a good option for the Excel.

C# Excel Worksheet Object reference not set to an instance of an object

When I run a SSIS package Interactively I am getting the error Object reference not set to an instance of an object on a Script task during run time.
So I debugged the code by using break points and after going step by step the code fails at this line objExcelWbk.Close(true, Type.Missing, Type.Missing);
I have checked all my references they are all there and the imports are fine too.
The function is provided below
public void FormatExcel_DVP(string strFinalFileName, string ExcelOutputFolder, SqlConnection Conn)
{
Microsoft.Office.Interop.Excel.ApplicationClass objExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
Microsoft.Office.Interop.Excel.Workbook objExcelWbk = default(Excel.Workbook);
Microsoft.Office.Interop.Excel.Worksheet objWrksheet = default(Excel.Worksheet);
string sFilePath = string.Empty;
DataSet ds = new DataSet();
string DVP_Name = string.Empty;
string sFilename = string.Empty;
int RowCount = 0;
try
{
SqlCommand cmd = new SqlCommand("select distinct LTRIM(RTRIM(DVP_Name))as DVP_Name from SBBCP_DVP_SVP Order By DVP_Name", Conn);
SqlDataAdapter _da = new SqlDataAdapter(cmd);
_da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
DVP_Name = dr[0].ToString().Trim().Replace("'", "''");
sFilename = DVP_Name.Trim();
sFilePath = strFinalFileName + ExcelOutputFolder.Trim() + sFilename;
if (System.IO.File.Exists(sFilePath))
{
objExcelWbk = objExcelApp.Workbooks.Open(sFilePath.Trim(), 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);
objExcelApp.DisplayAlerts = false;
objExcelApp.Visible = false;
objWrksheet = (Excel.Worksheet)objExcelWbk.Worksheets["Details"];
((Microsoft.Office.Interop.Excel._Worksheet)objWrksheet).Activate();
Microsoft.Office.Interop.Excel.Range range;
range = (Excel.Range)objWrksheet.get_Range("A1:J1", Type.Missing);
range.Interior.ColorIndex = 15;
range.Interior.Pattern = Microsoft.Office.Interop.Excel.XlPattern.xlPatternSolid;
range.NumberFormat = "#";
range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
range.VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
range.WrapText = true;
range.Font.Bold = true;
range.Font.Name = "Arial";
range.Font.Size = 10;
range.AutoFilter(1, Type.Missing, Microsoft.Office.Interop.Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);
RowCount = objWrksheet.UsedRange.Rows.Count;
range = objWrksheet.get_Range("A2:J2", "A" + RowCount + ":J" + RowCount);
range.WrapText = true;
FormatPivotTable(ref objExcelWbk, "Summary");
objExcelWbk.SaveAs(sFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}
}
}
objExcelWbk.Close(true, Type.Missing, Type.Missing);
objExcelApp.Quit();
}
catch (Exception e)
{
throw e;
}
}
In your code you have
for each row
{
if file exists
{
open spreadsheet.
do stuff
}
}
Close spreadsheet
the problem is that could be senarios where your spreadsheet was never opened and its trying to close it but it hadnt been set.
You should close the spreadsheet in the same scope you opened it, so in my pseudo code, after the "do stuff" - for then, if you opened it as it didnt barf or die, you have something you can close.

How to Overwrite existing Excel file by adding new sheet with Excel Interop - C#

My program, every hour, does some math calculations and saves these result into excel. When it first run(lets say 08:00 AM) it creates a excel workbook and one sheet namely "Sheet1". It saves excel and releases the COM objects. so far everything is fine.
My problem begins with second run (09:00 AM). when it tries to save new results, it overwrites existing excel file (This is OK, the way i want it) but it overwrites Sheet1 which was created in 08:00 AM. I want it to save new result in Sheet2.
In third run, i want it to save result in Sheet3
In fourth run, i want it to save result in Sheet4. so on so forth..
How can i change my code to do like above ?
thanks in advance..
My Code:
using excelApp = Microsoft.Office.Interop.Excel;
public static void Main(string[] arg)
{
while (true)
{
writeToExcel();
int wait = 3600 * 1000;
System.Threading.Thread.Sleep(Convert.ToInt32(wait));
}
}
public static void writeToExcel()
{
excelApp.Application excl = new Microsoft.Office.Interop.Excel.Application();
excl.Visible = true;
//MATH CALCULATIONS......
excelApp.Workbook wb = excl.Workbooks.Add(excelApp.XlWBATemplate.xlWBATWorksheet);
excelApp.Worksheet ws1 = (excelApp.Worksheet)wb.Worksheets[1];
excelApp.Worksheet ws2 = (excelApp.Worksheet)wb.Sheets.Add();
excelApp.Worksheet ws3 = (excelApp.Worksheet)wb.Sheets.Add();
excelApp.Worksheet ws4 = (excelApp.Worksheet)wb.Sheets.Add();
excelApp.Worksheet ws5 = (excelApp.Worksheet)wb.Sheets.Add();
excl.DisplayAlerts = false;
string fileName = string.Format(#"{0}\Data_" + DateTime.Now.Month + "-" DateTime.Now.Day + ".xlsx", Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));
workSheet.SaveAs(fileName);
Console.WriteLine("Excel Saved Successfully!!");
excl.Quit();
// Release COM objects
if (excl != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(excl);
if (workSheet != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet);
excl = null;
workSheet = null;
GC.Collect();
}
You need to get the work book from the saved file. So at the beginning of your routine, you need a mechanism to determine if today's file already exists, if so, use the the following to get your Workbook.
Workbook WB = ExcelApp.Workbooks.Open(fileName, 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);
Hopefully this helps you see the error in your ways.

Update Excel cells with a textbox via MVC4

I started to learn programming again yesterday. As an assignment i made an API where it is possible to create Excel files, where it is possible to fill in a textbox and the text from this textbox will fill a cell in excel. Here is what i made for the assignment to create a excel file(The question comes after the code).
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult DownloadExcel(string field, int id = 0)
{
var bla = field;
List<Record> obj = new List<Record>();
obj = RecordInfo(field);
StringBuilder str = new StringBuilder();
str.Append("<table border=`" + "1px" + "`b>");
str.Append("<tr>");
str.Append("<td><b><font face=Arial Narrow size=3>Fieldname</font></b></td>");
str.Append("</tr>");
foreach (Record val in obj)
{
str.Append("<tr>");
str.Append("<td><font face=Arial Narrow size=" + "14px" + ">" + val.Fieldname.ToString() + "</font></td>");
str.Append("</tr>");
}
str.Append("</table>");
HttpContext.Response.AddHeader("content-disposition", "attachment; filename=Information" + DateTime.Now.Year.ToString() + ".xls");
this.Response.ContentType = "application/vnd.ms-excel";
byte[] temp = System.Text.Encoding.UTF8.GetBytes(str.ToString());
return File(temp, "application/vnd.ms-excel");
}
public List<Record> RecordInfo(string fieldname = "test")
{
List<Record> recordobj = new List<Record>();
recordobj.Add(new Record { Fieldname = fieldname });
return recordobj;
}
}
Now my question is. Is it possible to modify fields in Excel via C# and is it possible to modify a specific cell with a textbox and that the data will be changed on click (like for example, I want to adjust cell D7 from 1 to 2, so I go to my form and fill in 2 in the textbox and press submit and the specific cell will show the new number when i open Excel). I searched but couldn't find the answer. A link to how it can be made is appreciated.
Thanks in advance!
I recommend that you switch to another approach and use a "grown-up" library for the excel file creation. EPPlus is free, offers great features and is very easy to use.
Have a look at the examples: http://epplus.codeplex.com/wikipage?title=WebapplicationExample
A bit late, but I answered my own question some time ago.
For the ones who are interested, here is the code for how I fixed my problem.
public class ExcelModel
{
Application excelApp;
string newValue;
public ExcelModel(string newValue)
{
excelApp = new Application();
this.newValue = newValue;
}
public void openExcelSheet(string fileName)
{
Workbook workbook = excelApp.Workbooks.Open(fileName, 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);
Worksheet sheet = (Worksheet)workbook.Worksheets.get_Item(2);
double oldValue = sheet.get_Range("D6").get_Value();
sheet.Cells[6, 4] = newValue;
workbook.SaveAs("\\Users\\user1\\Downloads\\text3.xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workbook.Close();
excelApp.Visible = true;
Workbook newWorkbook = excelApp.Workbooks.Open("\\Users\\user1\\Downloads\\text3.xlsx");
}
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult UpdateExcel(string field, int id = 0)
{
ExcelModel model = new ExcelModel(field);
string file = "\\Users\\user1\\Downloads\\Testdocument.xlsx";
model.openExcelSheet(file);
return RedirectToAction("Index");
}
public List<Record> RecordInfo(string fieldname = "test")
{
List<Record> Recordobj = new List<Record>();
Recordobj.Add(new Record { Fieldname = fieldname });
return Recordobj;
}
}

Categories

Resources