2009-07-10 8 views
10

Un de mes utilisateurs rencontre un problème en essayant d'ouvrir un fichier Excel via mon application C#.C# et Excel interop

Tout fonctionne bien quand je l'exécute à partir de ma machine et cela fonctionne pour les autres utilisateurs. Je ne suis pas un expert en interopérabilité Excel et j'espère que vous pourrez m'aider.

Voici comment il est mis en place:

J'ai ajouté une référence à mon application à Microsoft.Office.Interop.Excel.dll, la version 10.0.4504.0 (que je crois Excel 2002). Sur ma machine, je l'ai installé Excel 2007. Dans mon code, je tente d'ouvrir une feuille de calcul comme ceci:

using Microsoft.Office.Interop 
... 
Microsoft.Office.Interop.Excel.ApplicationClass _excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass(); 
Microsoft.Office.Interop.Excel.Workbook excelWorkbook = _excelApp.Workbooks.Open(workbookPath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", false, false, 0, true, false, false); 
Microsoft.Office.Interop.Excel.Sheets excelSheets = excelWorkbook.Worksheets; 
Microsoft.Office.Interop.Excel.Worksheet excelWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)excelSheets.get_Item(1); 

Je la version connecté aux utilisateurs Excel 9.0 (qui est 2000). L'erreur que l'utilisateur obtient est:

Exception='System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad) 

Il semble que le classeur ne puisse pas être ouvert. Le fichier a été confirmé pour exister et était juste lâche sur le PC de l'utilisateur à C :. Je pensais qu'en utilisant le PIA, je n'aurais pas à m'inquiéter des problèmes de version d'Excel. Je sais que d'autres utilisateurs utilisent Excel 2000, et cela fonctionne sur ma machine de développement.

Des idées? Peut-être que mes appels pour ouvrir le fichier Excel devraient être changés? La chose malheureuse est que je suis incapable de le reproduire.

+0

s'il vous plaît aide avec ce si vous pouvez http://stackoverflow.com/questions/9962157/safely-disposing-of-an-object-using-c-sharp/ –

Répondre

14

« Je pensais à l'aide du PIA je ne avoir à se soucier des problèmes de version Excel . Je sais qu'il ya d'autres utilisateurs en utilisant Excel 2000, et il fonctionne sur mon machine dev. »

Presque vrai, mais pas tout à fait.

En développant par rapport au PIA pour Excel 2002, votre programme sera compatible pour toutes les versions d'Excel 2002 (10.0) et au-dessus. La machine défaillante, cependant, fonctionne avec Excel 2000 (9.0), qui est une version ci-dessous la version que vous avez développée.

Il n'existe aucun PIA officiellement supporté sous Excel 2002, donc si vous avez besoin que votre programme s'exécute sous Excel 2000 (9.0), vous devrez créer votre propre assembly interop personnalisé. Vous pouvez utiliser TlbImp.exe pour créer un assembly interop pour Excel 9.0, comme expliqué dans l'article Achieving Backward Compatibility with .NET Interop: Excel as Case Study.

Si votre assembly porte un nom fort, vous devez créer un assembly interop à nom fort. Cela peut être fait en fournissant le nom de votre fichier .pfx ou .snk via le commutateur/keyfile, comme démontré dans l'article How to create a Primary Interop Assembly (PIA). Cet article utilise également le commutateur/primary pour créer un "assembly interop primaire".Faire de l'assembly interop primaire n'est pas vraiment nécessaire dans votre cas, mais ne fait pas de mal. Ce que l'article omet, cependant, est l'utilisation du commutateur/sysarray, que vous devriez utiliser. Toutefois, la création d'un assembly interop à nom fort présente certaines complexités à prendre en compte. Pour plus de détails, lisez Using TLBIMP.exe to create Strong Named Interop Assemblies. (Cet article explique notamment la nécessité du commutateur/sysarray.)

En résumé, la création d'un ensemble d'interopérabilité personnalisé est très simple si votre assembly n'est pas doté d'un nom fort. C'est plus compliqué si votre assembly porte un nom fort et, par conséquent, vous devez créer un assembly interop nommé fort. Mais j'espère que ces articles devraient vous aider à démarrer.

- Mike

+0

Pas de problème Jaspion. .. btw, si vous utilisez .NET 4.0, vous n'avez plus besoin de créer d'assembly Interop. :-) Donc, ce besoin de cette solution est seulement pour .NET 3.5 et ci-dessous. –

2

J'utilise Microsoft.Office.Interop.Excel.dll: Version Durée: v1.1.4322 Version: 12.0.0.0

pourrait essayer:

private object mMissingValue = System.Reflection.Missing.Value; 

    private void CreateWorkbook(string fileName) 
    { 
    if (File.Exists(fileName)) 
    { 
     // Create the new excel application reference 
     mExcelApplication = new Application(); 
     // Open the file 
     Workbook excel_workbook = mExcelApplication.Workbooks.Open(templatePath, 
       mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, 
       mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, 
       mMissingValue, mMissingValue, mMissingValue, mMissingValue); 
     Worksheet sheet = (Worksheet)mExcelWorkbook.Worksheets[1]; 
    } 
} 
0

Je suis venu Préférer enregistrer des fichiers Excel en tant que feuilles de calcul XML, puis les ouvrir avec des objets System.Xml. XML J'utilise beaucoup pour toutes sortes de choses, alors qu'Interop est pour moi un art noir. Ce n'est peut-être pas suffisant pour vos besoins, mais si c'est le cas, c'est probablement beaucoup plus facile que de s'emmêler avec les bibliothèques Interop.

Questions connexes