Лучший отвечающий
переоткрыть с сохранением Excel файл

Вопрос
-
Ребят, есть вопрос (хотя заголовок звучит странно). На данную тему уже есть немало обсуждений, но может быть ситуация здесь проще.
Работаю в C#, используя Microsoft.Office.Interop.Excel. Создаю excel, записываю в него данные, затем сохраняю и закрываю. А потом, чтобы пользователь не искал его, открываю его с помощью System.Diagnostics.Process.Start().
Например, на форме есть кнопка save_button, при нажатию на которую и осуществляются все эти процедуры:
private void save_button_Click(object sender, EventArgs e) { string path; path = Directory.GetCurrentDirectory(); Excel.Application app = new Excel.Application(); app.SheetsInNewWorkbook = 1; Excel.Workbook wb = app.Workbooks.Add(); Excel.Worksheet worksheet = wb.ActiveSheet; //... здесь записываем данные в файл... app.DisplayAlerts = false; wb.SaveAs(path + @"\file.xlsx"); wb.Close(true); app.Quit(); System.Diagnostics.Process.Start(Directory.GetCurrentDirectory() + @"\file.xlsx"); // Открываем файл для просмотра }
Но!!! Если этот файл будет открыт, и я снова нажму save_button, то вылезет исключение:
System.Runtime.InteropServices.COMException: "Нет доступа к 'file.xlsx'."
Как можно сделать так, чтобы программа определяла открыт файл или нет, и если открыт, то закрывала его, сохраняла изменения и снова открывала ??
Андрей
3 февраля 2019 г. 10:43
Ответы
-
Для того, чтобы подключиться к уже запущенному экземпляру Excel, используйте Marshal.GetActiveObject:
Excel.Application app = (Excel.Application) Marshal.GetActiveObject("Excel.Application");
Если результат null, значит Excel не открыт. В противном случае, проходите по Workbooks и смотрите, есть ли там то, что нужно вам (по свойству Name или Path).
- Изменено VadimTagil 3 февраля 2019 г. 17:09
- Предложено в качестве ответа Maksim MarinovMicrosoft contingent staff, Moderator 4 февраля 2019 г. 9:53
- Помечено в качестве ответа АндрейGreen 20 февраля 2019 г. 21:36
3 февраля 2019 г. 17:08
Все ответы
-
Для того, чтобы подключиться к уже запущенному экземпляру Excel, используйте Marshal.GetActiveObject:
Excel.Application app = (Excel.Application) Marshal.GetActiveObject("Excel.Application");
Если результат null, значит Excel не открыт. В противном случае, проходите по Workbooks и смотрите, есть ли там то, что нужно вам (по свойству Name или Path).
- Изменено VadimTagil 3 февраля 2019 г. 17:09
- Предложено в качестве ответа Maksim MarinovMicrosoft contingent staff, Moderator 4 февраля 2019 г. 9:53
- Помечено в качестве ответа АндрейGreen 20 февраля 2019 г. 21:36
3 февраля 2019 г. 17:08 -
Как можно сделать так, чтобы программа определяла открыт файл или нет, и если открыт, то закрывала его, сохраняла изменения и снова открывала ??
Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!
6 февраля 2019 г. 19:21 -
kosuke904, хахаха, как смешно! Ну конечно знаю. Если было бы все так просто, я, наверное, не задавал бы вопросов сюда.
Андрей
7 февраля 2019 г. 8:50 -
VadimTagil, Извините за задержку с ответом. Нашел такую конструкцию. Но нужно чуть кода добавить =)
допустим мы нашли процесс Excel.Application, а как закрыть процесс в котором открыта именно моя книга, к примеру my_file.xlsx ?? там по-любому нужно пробежаться циклом foreach по какой-то коллекции, наверное, и по свойству Name отрубить его.
private void save_button_Click(object sender,
EventArgs e) { try
{ string path; path = Directory.GetCurrentDirectory(); Excel.Application app = new Excel.Application(); app.SheetsInNewWorkbook = 1; Excel.Workbook wb = app.Workbooks.Add(); Excel.Worksheet worksheet = wb.ActiveSheet; //... здесь записываем данные в файл... app.DisplayAlerts = false; wb.SaveAs(path + @"\file.xlsx"); wb.Close(true); app.Quit(); System.Diagnostics.Process.Start(Directory.GetCurrentDirectory() + @"\file.xlsx"); // Открываем файл для просмотра } catch (Exeption) { Excel.Application app = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); // и как остановить процесс, в котором открыта именно моя книга my_file.xlsx?? } }
Андрей
7 февраля 2019 г. 9:03 -
Современные версии Excel открывают все документы в одном процессе, если их явно не попросить об обратном.
"там по-любому нужно пробежаться циклом foreach по какой-то коллекции, наверное, и по свойству Name отрубить его. "
Да, я же написал:
"В противном случае, проходите по Workbooks и смотрите, есть ли там то, что нужно вам (по свойству Name или Path)."
Name - имя файла, Path - каталог. FullName, вроде, содержит полный путь к файлу.
7 февраля 2019 г. 9:59 -
с помощью какого метода я должен остановить процесс ?
Marshal.ReleaseComObject() -- этот ??
private void save_button_Click(object sender, EventArgs e) { try { string path; path = Directory.GetCurrentDirectory(); Excel.Application app = new Excel.Application(); app.SheetsInNewWorkbook = 1; Excel.Workbook wb = app.Workbooks.Add(); Excel.Worksheet worksheet = wb.ActiveSheet; //... здесь записываем данные в файл... app.DisplayAlerts = false; wb.SaveAs(path + @"\file.xlsx"); wb.Close(true); app.Quit(); System.Diagnostics.Process.Start(Directory.GetCurrentDirectory() + @"\file.xlsx"); // Открываем файл для просмотра } catch (Exeption) { Excel.Application app = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); // и как остановить процесс, в котором открыта именно моя книга my_file.xlsx?? if (app != null) { foreach (var wb in app.Workbooks) { if ((wb as Excel.Workbook).FullName.Equals("Типизация.xlsx")) { (wb as Excel.Workbook).Close(); Marshal.ReleaseComObject(app); app.Quit(); } } } } }
что-то типа такого не хочет работать.
- Изменено АндрейGreen 7 февраля 2019 г. 10:29
7 февраля 2019 г. 10:28 -
И не должно. Вызов GetActiveObject должен быть до создания нового экземпляра Excel. Иначе он вернет этот же вами созданный экземпляр...
Excel.Application app=null; try { app = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); } catch (COMException) { app = null; } if (app != null) { foreach (Excel.Workbook x in app.Workbooks) { if (x.FullName == path + @"\file.xlsx") { x.Save(); x.Close(true); break; } } } app = new Excel.Application(); //работа с Excel... System.Diagnostics.Process.Start(Directory.GetCurrentDirectory() + @"\file.xlsx");
7 февраля 2019 г. 10:52