Open excel file for manual edition and saving - c#

It seems that most questions regarding working with Excel files through C# resolve around doing it in a fully automated way. I have a slightly different issue.
The way the code is supposed to work.
Launches a batch that creates a .txt file in given location, populated by results of a sql query. (Done and works)
Opens the file in Excel (the reason why I use .txt is that .csv messes up my numbers by removing leading zeroes etc) and makes it visible to the user. The code stops working and leaves the rest to the user.
User makes the changes to the file himself and manually saves them and exits Excel.
The problem that I am encountering is that the process does not want to 'leave the file alone'. It opens correctly, I edit the value and then I save it and when I try to close it it asks me if I want to save changes again. I click yes and that immediately brings up another popup asking the same question.
I do not know how to 'release' the file so that its control will be fully up to the user without actually closing Excel.
This is the bit of code that I use:
{
(...)
RunBatch("Manual_adjustment");
string fileName = "Manual_Adjustment.txt";
Excel.Application excel = new Excel.Application();
object misValue = System.Reflection.Missing.Value;
Excel.Workbook excelWorkbook;
excel.Visible = true;
excelWorkbook = excel.Workbooks.Open(ConstantValues.FolderPathInput + + #"\" + fileName);
releaseObject(excelWorkbook);
releaseObject(excel);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
How do I let the user save the changes without making him manually open the file from the OS level?

I think calling to Excell.Application.Quit may works

Related

C# Excel unable to copy worksheet

I am working on a web App where user can upload an Excel file and I need to copy data from the user worksheet to a destination worksheet in order to do some calculation. To do so, I have the following code:
public class ExcelCtrl
{
private Excel.Application excelApp = null;
private Excel.Workbook srcworkbook = null;
private Excel.Workbook destworkbook = null;
public void excel_init(String srcpath, String destpath, string copyrange)
{
//Open Excel
this.excelApp = new Excel.Application();
//Open user's file
this.srcworkbook = excelApp.Workbooks.Open(srcpath);
Excel.Worksheet srcworksheet = (Excel.Worksheet)srcworkbook.Worksheets.get_Item(1);
//Open calculation file
this.destworkbook = excelApp.Workbooks.Open(destpath);
Excel.Worksheet destworksheet = (Excel.Worksheet)destworkbook.Worksheets.get_Item(1);
//Range of copy
Excel.Range from = srcworksheet.get_Range(copyrange);
Excel.Range to = destworksheet.get_Range(copyrange);
//Copy
from.Copy(to);
//Close user's file
srcworkbook.Close();
//Open Xla file
excelApp.Workbooks.Open("someXlaFile.xla");
excelApp.Workbooks.Open("AnotherXlaFile.xla");
}
Basically I have to different method to run different calculations and they have the following structure. What differ one calculation method to another are just the macro called, the number of macro and the copy range.
public static string Calculation1(String InputFileName, String CurDir)
{
//The Excel calculation file and its path
string filename = "CalculationFile.xls";
string path_server = ExcelCtrl.DossierCalcs + filename;
ExcelCtrl excel = new ExcelCtrl();
excel.excel_init(CurDir + "\\" + InputFileName, ExcelCtrl.DossierCalcs + filename, "A1:Z105");
//excel.excel_run("Macro1");
//The rest is not important
path_server = CurDir + "\\Resultats - " + InputFileName;
excel.excel_run("AnotherMacro", path_server);
excel.excel_close();
return path_server;
}
Now all work fine, except one calculation (the one above). I am unable to copy data from the user worksheet.
I have tested to :
(normal usage) upload an Excel file with some new data and when I download the file after calculation, it is still the old data.
reduce the range of copy ( I though maybe it is too big) to "A1:Z50" then "A1:A2". However, I have another calculation file where I copy a range of "A1:M730" and it works fine.
copy it manually with Ctrl + C; Ctrl + V (I thought maybe the worksheet is protected from modification or something)
With the first 2 tests, I still got old data (not the user data) and the last one works, I can paste user data; though not very useful if someone need to do it manually everytime an user ask for this calculation.
I hope this is enough for you to understand my problem and hope you can guide me.
Thanks
EDIT
Hello,
Just to clarify a little bit about what I am doing. I have an web app where user can download an Excel xlsx file and they have to fill in with their data. After that, They have to upload their file to the server and choose the calculation they want to run. On the server side, I copy their data (see code above) to the corresponding Excel calculation file. So for each calculation I have one input file for the user and one calculation file to run. In total I have 14 input files and 14 calculations files and 13 of them work fine.
I have done some more tests, the following tests do not copy my data :
(And I am using Excel 2010)
Changing the name of my destination Excel file to something more common because there were a "#" in the file name.
Changing the name of my destination Excel file to one another destination file where the copy works.
Changing the worksheet color (I really don't believe that will solve my problem but I have nothing to lose)
Deleting worksheets from my destination file one by one
And the following tests work (data are copied to the destination file) :
Copying to a new Excel file
Copying to an other Excel calculation file (let's say file B) where I know the copy works
My thought for the last case is because when I open my problematic Excel file, 2 warnings come up. The first one says that the workbook contains link to other data sources and ask me if I want to update it (even after updating, it keeps asking me everytime I open it) and the second one says that the workbook contains links that can not be updated.I have also this 2 warnings when I open file B but with this file the copy works.
So I have tried to delete all links in the file and it does not work either. Futhermore, those links are used in my 13 others files.
I am kind of lost now since I have deleted all worksheet and links from my Excel file and it still won't copy. The only difference I see between my problematic file and a new file is that the former contain Macro.

Open Excel with password in C#, and close the excel externally

I am looking for a way to open the password protected Excel file in Excel from my c# program.
Please notice I just need to open it for my user. I am not looking for something like Excel Interop to modify the file.
For a file that has no password, I can simply launch the process start with the full path file name as a parameter. But this one has password in it, so it can't be done like this.
If I use Excel interope to open it, I can open it, but the Excel process will leave there when user close the Excel window.
var excelApp = new Excel.Application();
excelApp.Visible = true;
var wb = excelApp.Workbooks.Open(#"d:\temp\test.xlsx", Password:"1234");
Since user will be modifying the file in the Excel window and then close the windows. This part is out of my control. I simply just want to launch the file, then I don't have to care about it. But by using Excel interope, the COM is actually referecing back to my c# program, so that the whole Excel process can't be disposed completely.
I think I know a workaround for it.
Create a helper C# console application called OpenExcelWorkbookWithPassword.exe which looks like that:
static void Main(string[] args)
{
var excelapp = new Excel.Application();
excelapp.Visible = true;
Excel.Workbook workbook = excelapp.Workbooks.Open(args[0], Password: args[1]);
}
and use this from your main application with the following code:
string path = #"d:\temp\test.xlsx";
string pw = "1234";
System.Diagnostics.Process.Start("OpenExcelWorkbookWithPassword.exe", path + " " + pw);
When the user is closing Excel the Excel.exe process will be terminated even if your main application is still running.

How to connect to an Excel workbook that lives in SharePoint 2013 and update it

I am creating a command line application and I would like to connect to a SharePoint site that has a workbook that I want to update.
I don't even know where to start but I guess the questions I have are.
What API can I use for this? It has to be something that is already built-in and not a third party API if possible :)
Once the connection is done and I am able to open the spreadsheet, will I be able to also switch from one sheet to another?
I've tried to use some code like this but it did not work.
private static void GetExcelSheetNames(string filename)
{
var xls = new Microsoft.Office.Interop.Excel.Application();
xls.Visible = true;
xls.DisplayAlerts = false;
var workbook = xls.Workbooks.Open(Filename: filename, IgnoreReadOnlyRecommended: true, ReadOnly: false);
try
{
// Refresh the data from data connections
workbook.RefreshAll();
// Wait for the refresh occurs - *wish there was a better way than this.
System.Threading.Thread.Sleep(5000);
// Save the workbook back again
workbook.SaveAs(Filename: filename); // This is when the Exception is thrown
// Close the workbook
workbook.Close(SaveChanges: false);
}
catch (Exception ex)
{
//Exception message is "Cannot save as that name. Document was opened as read-only."
}
finally
{
xls.Application.Quit();
xls = null;
}
}
The Exception that I get was:
Microsoft Excel cannot access the file 'https//url/bla/bla/bla/workbook.xlsx There are several possible reasons:
The file name or path does not exist.
The file is being used by another program.
The workbook you are trying to save has the same name as a currently open workbook.
Actually, it seems like it is trying to open an instance of Excel Desktop in my machine.
Sorry for such an open question but I don't really know how can I connect to a SharePoint site.
Thanks in advance!
If you're using a document in a document library, check to make sure that it is checking out the document before you try to save it. I am working with a similar process but using a report library instead of a document library and am able to save documents without check out/in.

Insert picture comment with C# Ok while copy content with comments fail

I'm working on excel using C#, but I face some issues while insert picture comments into excel.
Here is my code:
public void InstertPictureComment(Excel.Range myrange, string picturepath)
{
myrange.ClearComment();
myrange.AddComment();
myrange.Comment.Shape.Fill.UserPicture(picturepath);
myrange.Comment.Shape.Width=400;
myrange.Comment.Shapes.Height=300;
}
The above code works well and I can succesfully insert picture comments.
However, issues show up.
Copy the contents (with the picture comments I have just inserted) to other excel worksheet
==>save excel, and close excel app
==> reopen excel, and a messagebox telling "Excel found unreadable content in xxxxx"
What's wrong with my code? Or it's an excel issue?
I have corrected the code so that it compiles
public void InstertPictureComment(Excel.Range myrange, string picturepath)
{
myrange.Cells.ClearComments();
myrange.AddComment();
myrange.Comment.Shape.Fill.UserPicture(picturepath);
myrange.Comment.Shape.Width = 400;
myrange.Comment.Shape.Height = 300;
}
Part of the problem is with Excel. With your code, you are probably creating a new application instance of Excel. Excel is unable to copy objects across the application instances.
If you open another workbook in the same application instance, the objects will get copied. The only way to copy data across application instances is using Paste Special functionality.
You should fetch the existing Excel application instance. If it is not there, then you may create it.
private Excel.Application GetExcelInstance()
{
Excel.Application instance = null;
try
{
instance = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
}
catch (System.Runtime.InteropServices.COMException ex)
{
instance = new Excel.Application();
appCreatedExcelInstance = true;
}
return instance;
}
You may use the appCreatedExcelInstance flag to decide whether or not to quit the instance during cleanup.

How to Save/Overwrite existing Excel file with Excel Interop - C#

Is there a way to save changes to an excel spreadsheet through the excel interop (in this case I am adding a worksheet to it) without having it prompt the user if they want to overwrite the existing file with the changes. I do not want the user to even see the spreadsheet open in my application so having a message box popping up asking them if they want to overwrite the file seems very out of place and possibly confusing to the user.
I am using the workbook.SaveAs(fileloaction) method.
Here is where I am initializing the COM reference objects for the excel interop.
private Excel.Application app = null;
private Excel.Workbook workbook = null;
public Excel.Workbook Workbook
{
get { return workbook; }
set { workbook = value; }
}
private Excel.Worksheet worksheet = null;
private Excel.Range workSheet_range = null;
Below is the code I am using to close/save the excel file. The workbook.close() method line is the one that is reportedly throwing the unhandled exception.
workbook.Close(true, startForm.excelFileLocation, Missing.Value);
Marshal.ReleaseComObject(app);
app = null;
System.GC.Collect();
Basically, all you need is ExcelApp.DisplayAlerts = False - Here's how I do it, though:
ExcelApp.DisplayAlerts = False
ExcelWorkbook.Close(SaveChanges:=True, Filename:=CurDir & FileToSave)
Hope this helps
Only this code will Require for stop override alert or Template already in use
ExcelApp.DisplayAlerts = False
I know this is an old post, but I wanted to share a way to make this work without causing possible frustration in the future.
First what I do not like about using: ExcelApp.DisplayAlerts = False
Setting this flag will set this property on the excel file, not just in your program. This means that if a user makes changes to the file and closes it (by clicking the X), they will not be prompted to save the file and will cause frustration later. It will also disable any other prompts excel would typically post.
I like checking if the file exists before saving it:
if (File.Exists(SaveAsName))
{
File.Delete(SaveAsName);
}

Categories

Resources