如何在 C# 中访问已打开的 Excel 文件?
我有一个通过在 Windows 资源管理器中双击打开的 Excel 工作簿,但无法在代码
Excel.Application xlApp = (Application)Marshal.GetActiveObject("Excel.Application");
Excel.Workbooks xlBooks = xlApp.Workbooks;
xlBooks.Count equals 0 中访问它,为什么它不引用我打开的工作簿?
编辑
以下是各种场景以及正在发生的情况:
场景 1:如果文件尚未打开
- 代码会打开工作簿,我很高兴。
场景 2:如果文件最初是从代码打开的,我关闭并重新打开应用程序
- 代码引用文件就好了
xlBooks.Count
等于 1,我很高兴。
场景 3:如果文件最初不是通过代码打开的,并且通过在资源管理器中双击该文件,代码
- 会打开该文件的另一个实例
xlBooks.Count
等于 0,我很愤怒!
这是现在的完整代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;
public class ExcelService : IExcelService
{
const string _filePath = @"C:\Somewhere";
const string _fileName = @"TestFile.xlsb";
string _fileNameAndPath = Path.Combine(_filePath, _fileName);
Application xlApp;
Workbooks xlBooks;
Workbook xlBook;
Worksheet xlSheet;
public ExcelService()
{
try
{
xlApp = (Application)Marshal.GetActiveObject("Excel.Application");
xlBooks = xlApp.Workbooks;
var numBooks = xlBooks.Count;
Log.Info("Number of workbooks: {0}".FormatWith(numBooks));
if (numBooks > 0)
{
xlBook = xlBooks[1];
Log.Info("Using already opened workbook");
}
else
{
xlBook = xlBooks.Open(_fileNameAndPath);
Log.Info("Opening workbook: {0}".FormatWith(_fileNameAndPath));
}
xlSheet = (Worksheet)xlBook.Worksheets[1];
// test reading a named range
string value = xlSheet.Range["TEST"].Value.ToString();
Log.Info(@"TEST: {0}".FormatWith(value));
xlApp.Visible = true;
}
catch (Exception e)
{
Log.Error(e.Message);
}
}
~ExcelService()
{
GC.Collect();
GC.WaitForPendingFinalizers();
try
{
Marshal.FinalReleaseComObject(xlSheet);
}
catch { }
try
{
Marshal.FinalReleaseComObject(xlBook);
}
catch { }
try
{
Marshal.FinalReleaseComObject(xlBooks);
}
catch { }
try
{
Marshal.FinalReleaseComObject(xlApp);
}
catch { }
}
}
I have an excel workbook opened via double-clicking it in windows explorer but cannot access it in code
Excel.Application xlApp = (Application)Marshal.GetActiveObject("Excel.Application");
Excel.Workbooks xlBooks = xlApp.Workbooks;
xlBooks.Count equals 0, why isn't it referencing my opened workbook?
EDIT
Here are the various scenarios and what is happening:
Scenario 1: If the file is not already open
- Code opens workbook, I am happy.
Scenario 2: If the file is initially opened from code and I close and reopen the app
- Code references file just fine
xlBooks.Count
equals 1, I am happy.
Scenario 3: If the file is initially opened not from code, and via double-clicking it in explorer
- Code opens another instance of the file
xlBooks.Count
equals 0, I am in a rage!
Here is the entire code as it stands right now
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;
public class ExcelService : IExcelService
{
const string _filePath = @"C:\Somewhere";
const string _fileName = @"TestFile.xlsb";
string _fileNameAndPath = Path.Combine(_filePath, _fileName);
Application xlApp;
Workbooks xlBooks;
Workbook xlBook;
Worksheet xlSheet;
public ExcelService()
{
try
{
xlApp = (Application)Marshal.GetActiveObject("Excel.Application");
xlBooks = xlApp.Workbooks;
var numBooks = xlBooks.Count;
Log.Info("Number of workbooks: {0}".FormatWith(numBooks));
if (numBooks > 0)
{
xlBook = xlBooks[1];
Log.Info("Using already opened workbook");
}
else
{
xlBook = xlBooks.Open(_fileNameAndPath);
Log.Info("Opening workbook: {0}".FormatWith(_fileNameAndPath));
}
xlSheet = (Worksheet)xlBook.Worksheets[1];
// test reading a named range
string value = xlSheet.Range["TEST"].Value.ToString();
Log.Info(@"TEST: {0}".FormatWith(value));
xlApp.Visible = true;
}
catch (Exception e)
{
Log.Error(e.Message);
}
}
~ExcelService()
{
GC.Collect();
GC.WaitForPendingFinalizers();
try
{
Marshal.FinalReleaseComObject(xlSheet);
}
catch { }
try
{
Marshal.FinalReleaseComObject(xlBook);
}
catch { }
try
{
Marshal.FinalReleaseComObject(xlBooks);
}
catch { }
try
{
Marshal.FinalReleaseComObject(xlApp);
}
catch { }
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我知道这个线程有点旧,但我找到了另一种方法来做到这一点。当您创建新的
Excel.Application
对象时,您必须创建 WorkBooks 对象。当您访问已打开的 Excel 文件时,WorkBooks
对象已创建,因此您只需向现有 WorkBook 添加一个新的 WorkBook 即可。如果您有权访问 WorkBook 名称,@Tipx 的解决方案效果很好,但在我的情况下,当前 WorkBook 名称始终是随机的。这是我为解决此问题而提出的解决方案:可能不是最好的解决方案,但它满足我的需求。希望这对某人有帮助。 :)
I know this thread is a little old, but I found another way of doing this. When you create a new
Excel.Application
object you have to create the WorkBooks object. When you access an already opened Excel file, theWorkBooks
object is already created, so you just need to add a new WorkBook to the existing one. @Tipx 's solution works great if you have access to the WorkBook name, but in my case the current WorkBook name is always random. Here's the solution I came up with to get around this:Might not be the best solution but it worked for my needs. Hope this helps someone. :)
如果您的所有工作簿都在同一个 Excel 实例中打开(您可以通过检查是否可以使用 Alt-tab 从一个工作簿切换到另一个工作簿来检查这一点)。您只需使用
Workbooks("[FileName]")
即可引用另一个。因此,例如:If all your workbooks are opened in the same Excel instance (you can check this by checking if you can switch from one to the other using Alt-tab). You can simply refer to the other using
Workbooks("[FileName]")
. So, for example :