IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Interopérabilité Word/Excel et COMException


Sujet :

C#

  1. #1
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 895
    Par défaut Interopérabilité Word/Excel et COMException
    Bonjour CSharpers

    Voici mon problème. Je veux lire un document Word pour récupérer certaines informations. Pour ce faire, j'utilise l'interopérabilité. Je teste, Ok, ça marche.
    Maintenant, je veux pouvoir utiliser ces données récupérées pour écrire un fichier Excel, toujours avec l'interopérabilité. Voici le code de la classe principale:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using StudyPlanReader;
    using DmpkFilesGenerator;
     
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string cwd = @"C:\Documents and Settings\gldavid\Desktop";
                string file = @"C:\Documents and Settings\gldavid\My Documents\Documents\MyDoc.doc";;
                StudyPlanParser target = new StudyPlanParser(file);
                try
                {
                    Console.WriteLine("Reading Word");
                    target.Open();
                    target.Parse();
                    string sn = target.StudyNumber;
                    List<String>clots = target.CompoundLots;
                    target.Close();
                    Console.WriteLine("Creating Excel");
                    CalculationsSummaryCreator csc = new CalculationsSummaryCreator(sn, clots, cwd);
                    csc.CreateFile();
                    Console.WriteLine("OK...");
                    Console.ReadKey();
                }
                catch (Exception e)
                {
                    target.Close();
                    Console.WriteLine("{0}", e.Message);
                    Console.WriteLine("{0}", e.Source);
                    Console.WriteLine("{0}", e.StackTrace);
                    Console.WriteLine("...");
                    Console.ReadKey();
                }
            }
        }
    }
    Le problème est qu'en cours d'exécution, j'ai l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    System.Runtime.InteropServices.COMException was unhandled
      Message=The remote procedure call failed and did not execute. (Exception from HRESULT: 0x800706BF)
      Source=StudyPlanReader
      ErrorCode=-2147467259
      StackTrace:
           at StudyPlanReader.AWordReader.Close() in C:\Documents and Settings\dbourgais\my documents\visual studio 2010\Projects\DmpkExcelCalculationsLib\StudyPlanReader\AWordReader.cs:line 74
           at ConsoleApplication1.Program.Main(String[] args) in C:\Documents and Settings\dbourgais\my documents\visual studio 2010\Projects\DmpkExcelCalculationsLib\ConsoleApplication1\Program.cs:line 33
           at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException:
    J'ai oublié quelque chose ?
    Merci d'avance de votre aide.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 056
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 056
    Par défaut
    Peut etre qu'il faudrait mettre le code de target.Close();
    A priori si celui-ci pose problème, tu le rappelles dans le catch, et à ce moment là il ne sera plus catch!

  3. #3
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 895
    Par défaut
    Bonjour

    Voici le code mon catch:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    public void Close()
            {
                try
                {
                    if (this.document != null)
                    {
                        this.document.Close(missing, missing, missing);
                    }
                    if (this.word != null)
                    {
                        this.word.Quit(missing, missing, missing);
                    }
                }
                catch (Exception e)
                {
                    throw new IOException(e.Message);
                }
            }
    J'ai "résolu" mon problème de la manière suivante toutefois:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Console.WriteLine("Reading Word");
                    target.Open();
                    target.Parse();
                    string sn = target.StudyNumber;
                    List<String>clots = target.CompoundLots;
                    target.Close();
                    Thread.Sleep(1000);
                    Console.WriteLine("Creating Excel");
                    CalculationsSummaryCreator csc = new CalculationsSummaryCreator(sn, clots, cwd);
                    csc.CreateFile();
                    Thread.Sleep(1000);
                    Console.WriteLine("OK...");
                    Console.ReadKey();
    Bon, franchement, j'aime pas mettre des Sleep dans mon code...
    Si quelqu'un a une solution plus raffinée, je prends volontiers,

    Merci,

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 056
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 056
    Par défaut
    On ne connais pas les types de document et word, je suppose que document c'est un workbook et word est excel ?

    Je connais pas trop mais souvent ce que je vois c'est ca :
    Marshal.FinalReleaseComObject(document);
    apres le close( et aussi apres le quit).
    Regarde si ca change quelque chose!

  5. #5
    Membre Expert Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Par défaut
    Bonjour,

    Le code de la méthode Close est l'effet, cela produit l'erreur, mais ce qu'il faut connaître pour comprendre c'est le code de la classe StudyPlanParser .

    GLDavid : ça fait du bien d'entendre que les Thread.Sleep sont moche, car c'est le cas. Beaucoup de gens se satisfont de ce genre de solutions. J'aime cette démarche.

  6. #6
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 895
    Par défaut
    Bonjour à tous

    Merci de vos réponses. De mon côté, j'ai décidé d'attraper le COMException...et de ne rien en faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
            public void Close()
            {
                try
                {
                    if (this.document != null)
                    {
                        this.document.Close(missing, missing, missing);
                    }
                    if (this.word != null)
                    {
                        this.word.Quit(missing, missing, missing);
                    }
                }
                catch (COMException) { }
                catch (Exception e)
                {
                    throw new IOException(e.Message);
                }
            }
    J'enlève mes Thread.Sleep.
    A l'exécution, OK, ça marche.
    Néanmoins, je me demande si c'est la bonne procédure à suivre.
    Qu'en pensez-vous ?

    Merci d'avance,

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  7. #7
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 895
    Par défaut
    Bonjour

    @micka132, j'ai ajouté ton snippet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
            public void Close()
            {
                try
                {
                    if (this.document != null)
                    {
                        this.document.Close(missing, missing, missing);
                    }
                    if (this.word != null)
                    {
                        this.word.Quit(missing, missing, missing);
                    }
                    Marshal.FinalReleaseComObject(this.document);
                }
                //catch (COMException) { }
                catch (Exception e)
                {
                    throw new IOException(e.Message);
                }
            }
    Ca a l'air pas mal comme ça.
    Voyez-vous d'autres éléments à ajouter ?

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  8. #8
    Membre Expert Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Par défaut
    Bonsoir,

    Je pense qu'on s'est pas compris, je voulais que tu nous postes le code de ta classe StudyPlanParser. La StackTrace que tu nous as fournie met en évidence une erreur à ce niveau, au moment du close. Tu dois utiliser une classe AWordReader à l'interieur de StudyPlanReader que tu dois avoir instancié dans ta classe StudyPlanParser (un peu compliqué comme tournure de phrase, désolé). L'erreur, comme indiqué dans la stacktrace se produit dans AWordReader.cs à la ligne 74.

    En définitive, si tu pouvais tout de même poster le code de ces 3 classes, ou au moins le code de la ligne qui lève l'erreur, cela pourrais nous permettre d'en savoir plus

    Bon dév.

  9. #9
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 895
    Par défaut
    Oups, je te présente toutes mes désoles Sisgo.
    Voici le code de la classe en question:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Office.Interop.Word;
    using System.Collections;
     
    namespace StudyPlanReader
    {
        public class StudyPlanParser:AWordReader, IWordParser
        {
            private String project;
            private String studyNumber;
            private List<String> compoundLots;
     
            public StudyPlanParser(String filePath):base(filePath)
            {
                this.compoundLots = new List<String>();
            }
     
            #region Properties
     
            public String Project
            {
                get
                {
                    return this.project;
                }
                private set
                {
                    this.project = value;
                }
            }
     
            public String StudyNumber
            {
                get
                {
                    return this.studyNumber;
                }
                private set
                {
                    this.studyNumber = value;
                }
            }
     
            public List<String> CompoundLots
            {
                get
                {
                    return this.compoundLots;
                }
            }
     
            #endregion
     
            #region Private methods
     
            private void SetProject(Table table)
            {
                Project = table.Cell(1, 2).Range.Text;
            }
     
            private void SetStudyNumber(Table table)
            {
                StudyNumber = table.Cell(2, 2).Range.Text;
            }
     
            private void SetCompoundLots(Table table)
            {
                String[] lots = table.Cell(3, 2).Range.Text.Split(',');
                for (int i = 0; i < lots.Length; i++)
                {
                    this.compoundLots.Add(lots[i].Trim());
                }
            }
     
            private Table GetFirstTable(Tables tables)
            {
                IEnumerator it = tables.GetEnumerator();
                int i = 0;
                while (it.MoveNext())
                {
                    if (i == 0)
                    {
                        return (Table)it.Current;
                    }
                    i++;
                }
                return null;
            }
     
            #endregion
     
            public void Parse()
            {
                try
                {
                    _Document document = Document;
                    Range content = document.Content;
                    Tables tables = content.Tables;
                    if (tables.Count < 1)
                    {
                        throw new Exception("No tables in the document!");
                    }
                    else
                    {
                        Table table = GetFirstTable(tables);
                        SetProject(table);
                        SetStudyNumber(table);
                        SetCompoundLots(table);
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }
    }
    Encore navré

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  10. #10
    Membre Expert Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Par défaut
    Salut,

    Pas de soucis

    En revanche, ce code nous permet pas de diagnostiquer l'erreur. Là, c'est le code de la classe AWordReader qui nous intéresse.

    Désolé aussi

  11. #11
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 895
    Par défaut
    Voici voilà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Office.Interop.Word;
    using System.IO;
    using System.Runtime.InteropServices;
     
    namespace StudyPlanReader
    {
        public abstract class AWordReader
        {
            private String filePath;
            private _Application word;
            private _Document document;
            private object missing = System.Reflection.Missing.Value;
            private object readOnly = false;
     
            protected AWordReader(String filePath)
            {
                this.FilePath = filePath;
                word = new Microsoft.Office.Interop.Word.Application();
                word.Visible = false;
            }
     
            public String FilePath
            {
                get
                {
                    return this.filePath;
                }
                private set
                {
                    this.filePath = value;
                }
            }
     
            public _Document Document
            {
                get
                {
                    return this.document;
                }
            }
     
            public void Open()
            {
                try
                {
                    object name = this.FilePath;
                    this.document = this.word.Documents.Open(ref name, ref missing, ref readOnly, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
                }
                catch (Exception e)
                {
                    throw new IOException(e.Message);
                }
            }
     
            public void Close()
            {
                try
                {
                    if (this.document != null)
                    {
                        this.document.Close(missing, missing, missing);
                    }
                    if (this.word != null)
                    {
                        this.word.Quit(missing, missing, missing);
                    }
                    Marshal.FinalReleaseComObject(this.document);
                    Marshal.FinalReleaseComObject(this.word);
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                catch (COMException) { }
                catch (Exception e)
                {
                    throw new IOException(e.Message);
                }
            }
        }
    }
    Merci encore,

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  12. #12
    Membre Expert Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Par défaut
    Bonjour,

    Essaye ça, je pense que c'est le target.close de ton catch et pas celui du code qui est levé...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public void Close()
            {
                try
                {
                    if (this.document != null)
                    {
                        this.document.Close(missing, missing, missing);
                        // On assigne null, car l'appel de Close une deuxième fois fera 
                        // un appel à sur l'objet déjà fermé
                        this.document = null;
                    }
                    if (this.word != null)
                    {
                        this.word.Quit(missing, missing, missing);
                        // On assigne null, car l'appel de Close une deuxième fois fera 
                        // un appel à sur l'objet déjà fermé
                        this.word = null;
                    }
                }
                catch (Exception e)
                {
                    throw new IOException(e.Message);
                }
            }
        }
    }
    J'espère que c'est ça

  13. #13
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 895
    Par défaut
    Bonjour Sisqo,

    C'est parfait ;-)
    Un grand merci à toi.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. VBA Word / Excel
    Par forsay1 dans le forum VBA Word
    Réponses: 3
    Dernier message: 29/12/2005, 16h48
  2. VBA Word / Excel
    Par forsay1 dans le forum VBA Word
    Réponses: 6
    Dernier message: 28/12/2005, 15h39
  3. VBA WORD / Excel
    Par forsay1 dans le forum VBA Word
    Réponses: 7
    Dernier message: 23/12/2005, 14h14
  4. VBA WORD / EXCEL
    Par forsay1 dans le forum VBA Word
    Réponses: 2
    Dernier message: 22/12/2005, 09h58
  5. Export d'etat ACCESS vers WORD/EXCEL : pb de mise en forme
    Par leguminator dans le forum Access
    Réponses: 2
    Dernier message: 25/10/2005, 11h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo