Jon*_*son 6 c# excel ms-office office-interop excel-interop
我在Windows资源管理器中双击打开了excel工作簿,但无法在代码中访问它
Excel.Application xlApp = (Application)Marshal.GetActiveObject("Excel.Application");
Excel.Workbooks xlBooks = xlApp.Workbooks;
Run Code Online (Sandbox Code Playgroud)
xlBooks.Count等于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 { }
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
我知道这个帖子有点旧,但我找到了另一种方法.创建新Excel.Application对象时,必须创建WorkBooks对象.当您访问已打开的Excel文件时,该WorkBooks对象已经创建,因此您只需要将新的WorkBook添加到现有的WorkBook中.如果您可以访问WorkBook名称,@ Tipx的解决方案很有用,但在我的情况下,当前的WorkBook名称始终是随机的.这是我想出来解决这个问题的解决方案:
Excel.Application excelApp = null;
Excel.Workbooks wkbks = null;
Excel.Workbook wkbk = null;
bool wasFoundRunning = false;
Excel.Application tApp = null;
//Checks to see if excel is opened
try
{
tApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
wasFoundRunning = true;
}
catch (Exception)//Excel not open
{
wasFoundRunning = false;
}
finally
{
if (true == wasFoundRunning)
{
excelApp = tApp;
wkbk = excelApp.Workbooks.Add(Type.Missing);
}
else
{
excelApp = new Excel.Application();
wkbks = excelApp.Workbooks;
wkbk = wkbks.Add(Type.Missing);
}
//Release the temp if in use
if (null != tApp) { Marshal.FinalReleaseComObject(tApp); }
tApp = null;
}
//Initialize the sheets in the new workbook
Run Code Online (Sandbox Code Playgroud)
可能不是最好的解决方案,但它符合我的需求.希望这有助于某人.:)
如果您的所有工作簿都在同一个 Excel 实例中打开(您可以通过检查是否可以使用 Alt-tab 从一个工作簿切换到另一个工作簿来检查这一点)。您可以简单地使用 来参考其他内容Workbooks("[FileName]")。因此,例如:
Dim wb as Workbook //for C#, type Excel.Workbook wb = null;
Set wb = Workbooks("MyDuperWorkbook.xlsx") //for C#, type wb = Excel.Workbooks["MyDuperWorkbook.xlsx"];
wb.Sheets(1).Cells(1,1).Value = "Wahou!"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11503 次 |
| 最近记录: |