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

Dotnet Discussion :

Lister les fichiers Excel ouverts avec Microsoft.Office.Interop.Excel


Sujet :

Dotnet

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Août 2009
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Août 2009
    Messages : 85
    Points : 228
    Points
    228
    Par défaut Lister les fichiers Excel ouverts avec Microsoft.Office.Interop.Excel
    Bonjour,
    J'ai le problème suivant. Je dois travailler sur des fichiers excel en VB.Net. Dans mes références, j'ai bien ajouté :

    Microsoft.Office.Interop.Excel.

    Par contre, quand j'instancie Excel de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim MonExcel As New Excel.Application
    Il me crée un nouveau Process Excel, et je ne peux pas lister les fichiers Excel déjà ouverts avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    For Each Workbook As Excel.Workbook In MonExcel.Workbooks
         MessageBox.Show(Workbook.Name)
    Next
    Car il cherche les fichiers Excel dans la session nouvellement instanciée (et donc MonExcel.Workbooks.Count = 0), mais pas dans le process Excel déjà actif (j'ai 15 fichiers Excel déjà ouverts...).

    Ceci marche bien sur en VBA sous Excel (puisque VBA travaille déjà dans l'instance active d'Excel), mais je n'arrive pas à le faire marcher en .Net

    Comment faire ?

    Merci !

  2. #2
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Hello,

    Ce n'est pas évident de faire ça, mais voici un code qui devrait pouvoir répondre à ton besoin :

    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
    122
    123
     
    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Text;
    using Microsoft.Office.Interop.Excel;
     
    namespace ConsoleApplication
    {
        class Program
        {
            [DllImport("Oleacc.dll")]
            static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint dwObjectID, byte[] riid, out ExcelWindow ptr);
     
            public delegate bool EnumChildCallback(IntPtr hwnd, ref IntPtr lParam);
     
            [DllImport("User32.dll")]
            public static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildCallback lpEnumFunc, ref IntPtr lParam);
     
            [DllImport("User32.dll")]
            public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
     
            public static bool EnumChildProc(IntPtr hwndChild, ref IntPtr lParam)
            {
                StringBuilder buf = new StringBuilder(128);
                GetClassName(hwndChild, buf, 128);
                if (buf.ToString() == "EXCEL7")
                {
                    lParam = hwndChild;
                    return false;
                }
                return true;
            }
     
            /// 
            /// Interface definition for Excel.Window interface
            /// 
            [Guid("00020893-0000-0000-C000-000000000046")]
            [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
            public interface ExcelWindow
            {
            }
     
     
            /// 
            /// This class is needed as a workaround to http://support.microsoft.com/default.aspx?scid=kb;en-us;320369
            /// Excel automation will fail with the follwoing error on systems with non-English regional settings:
            /// "Old format or invalid type library. (Exception from HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))" 
            /// 
            class UILanguageHelper : IDisposable
            {
                private CultureInfo _currentCulture;
     
                public UILanguageHelper()
                {
                    // save current culture and set culture to en-US 
                    _currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
                    System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
                }
     
                public void Dispose()
                {
                    // reset to original culture 
                    System.Threading.Thread.CurrentThread.CurrentCulture = _currentCulture;
                }
            }
     
     
     
            static void Main(string[] args)
            {
                // Use the window class name ("XLMAIN") to retrieve a handle to Excel's main window.
                // Alternatively you can get the window handle via the process id:
                // int hwnd = (int)Process.GetProcessById(excelPid).MainWindowHandle;
                //
                foreach (Process excelProcess in Process.GetProcessesByName("EXCEL"))
                {
                    IntPtr hwnd = excelProcess.MainWindowHandle;
     
                    if (hwnd != IntPtr.Zero)
                    {
                        IntPtr hwndChild = IntPtr.Zero;
     
                        // Search the accessible child window (it has class name "EXCEL7") 
                        EnumChildCallback cb = new EnumChildCallback(EnumChildProc);
                        EnumChildWindows(hwnd, cb, ref hwndChild);
     
                        if (hwndChild != IntPtr.Zero)
                        {
                            // We call AccessibleObjectFromWindow, passing the constant OBJID_NATIVEOM (defined in winuser.h) 
                            // and IID_IDispatch - we want an IDispatch pointer into the native object model.
                            //
                            const uint OBJID_NATIVEOM = 0xFFFFFFF0;
                            Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}");
                            ExcelWindow ptr;
     
                            int hr = AccessibleObjectFromWindow(hwndChild, OBJID_NATIVEOM, IID_IDispatch.ToByteArray(), out ptr);
     
                            if (hr >= 0)
                            {
                                // We successfully got a native OM IDispatch pointer, we can QI this for
                                // an Excel Application using reflection (and using UILanguageHelper to 
                                // fix http://support.microsoft.com/default.aspx?scid=kb;en-us;320369)
                                //
                                using (new UILanguageHelper())
                                {
                                    Application xlApp = (Application)ptr.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, ptr, null);
                                    foreach (Workbook workbook in xlApp.Workbooks)
                                    {
                                        Console.WriteLine(workbook.Name);
                                    }
                                }
                            }
                        }
                    }
                }
     
                Console.ReadLine();
            }
        }
    }

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Août 2009
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Août 2009
    Messages : 85
    Points : 228
    Points
    228
    Par défaut
    Hummmm... C'est bien ce que je craignais...
    Devoir prendre la main sur le système en quelque sorte...

    Bon, j'essaie de comprendre tout ça, merci beaucoup !

Discussions similaires

  1. Lister les fichiers d'un répertoire dans une feuille Excel
    Par AlainTech dans le forum Contribuez
    Réponses: 3
    Dernier message: 10/03/2016, 14h14
  2. Réponses: 1
    Dernier message: 03/09/2009, 14h26
  3. Réponses: 5
    Dernier message: 21/05/2009, 23h59
  4. Réponses: 2
    Dernier message: 09/05/2008, 22h36
  5. Réponses: 1
    Dernier message: 09/05/2008, 05h53

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