Comment accéder à un déjà ouvert un fichier Excel en C#?
J'ai un classeur excel ouvert par double-cliquant dessus dans l'explorateur windows, mais impossible d'y accéder dans le code
Excel.Application xlApp = (Application)Marshal.GetActiveObject("Excel.Application");
Excel.Workbooks xlBooks = xlApp.Workbooks;
xlBooks.Count est égal à 0, pourquoi n'est-il pas le référencement de mon classeur ouvert?
MODIFIER
Voici les différents scénarios et de ce qui se passe:
Scénario 1: Si le fichier n'est pas déjà ouvert
- Code ouvre le classeur, je suis heureux.
Scénario 2: Si le fichier est d'abord ouvert à partir du code et j'ai fermez et rouvrez l'application
- Des références au Code du fichier de l'amende juste
xlBooks.Count
est égal à 1, je suis heureux.
Scénario 3: Si le fichier est d'abord ouvert pas de code, et par double-cliquant dessus dans l'explorateur
- Code ouvre une autre instance du fichier
xlBooks.Count
est égal à 0, je suis en rage!
Voici le code entier comme il est en ce moment
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 { }
}
}
- Vous assurez-vous de ne pas avoir plus d'une instance d'Excel?
- Dupe de stackoverflow.com/questions/6682678/...
- Nous montrer la ligne de code où vous essayez d'ouvrir le "déjà ouvert" feuille de calcul.
- Dupe de sa propre question... wow...
- oui je suis assez sûr, je regarde le gestionnaire des tâches de plusieurs instances et il est seulement celui que j'ai actuellement ouvert.. je fais aussi des
Marshal.FinalReleaseComObject(xlApp);
dans le destructeur - Je suis en train de poser plus de rétrécissement des questions... je suis pas à obtenir des réponses... désolé
- Ainsi, dans le gestionnaire des tâches, vous n'avez qu'une excel.exe ouvrir? - Il Correct?
- correct
- Quelle version d'Excel?
- 2010..
- Je pense que j'ai d'autres trucs en cours... j'ai déménagé tout ce code pour une application console et cela a fonctionné, et ensuite cela n'a pas encore... je vais inspecter plus demain... merci
- Ok, je suis curieux d'entendre vos résultats.
Vous devez vous connecter pour publier un commentaire.
Si tous vos classeurs sont ouverts dans la même instance d'Excel (vous pouvez vérifier cela en vérifiant si vous pouvez passer de l'un à l'autre à l'aide de Alt-tab). Vous pouvez simplement consulter les autres à l'aide de
Workbooks("[FileName]")
. Ainsi, par exemple :Je sais que ce thread est un peu vieux, mais j'ai trouvé un autre moyen de le faire. Lorsque vous créez un nouveau
Excel.Application
objet, vous devez créer l'objet de Classeurs. Lorsque vous accédez à un déjà ouvert un fichier Excel, leWorkBooks
objet est déjà créé, vous avez juste besoin d'ajouter un nouveau Classeur existant. @Tipx 's solution fonctionne très bien si vous avez accès à le nom du Classeur, mais dans mon cas, le nom actuel du Classeur est toujours aléatoire. Voici la solution que j'ai trouvé pour contourner ce problème:Peut-être pas la meilleure solution, mais cela a fonctionné pour mes besoins. Espérons que cela aide quelqu'un. 🙂