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

VB.NET Discussion :

Problème ouverture feuille Excel (instance existante) [Débutant]


Sujet :

VB.NET

  1. #1
    Membre régulier
    Homme Profil pro
    Trader / Formateur / Développeur Options CBOE
    Inscrit en
    Septembre 2018
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afrique Du Sud

    Informations professionnelles :
    Activité : Trader / Formateur / Développeur Options CBOE
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2018
    Messages : 86
    Points : 70
    Points
    70
    Par défaut Problème ouverture feuille Excel (instance existante)
    Bonjour,
    J'ai regardé un bon nombre d'exemples sur le Net et je ne comprends pas pourquoi mon code ne fonctionne pas en ouverture d'un fichier Excel existant (ouvert ou pas).
    L'exception est alors: System.Runtime.InteropServices.COMException: 'Excel cannot open the file 'Book1.xlsm' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.'. Le fichier concerné peut être ouvert sans problème par Excel.

    Si je remplace Open(...) par Add() le code fonctionne pourtant.
    Je ne sais pas si tous ces "Imports" sont nécessaires.

    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
    Imports Excel = Microsoft.Office.Interop.Excel
    Imports System.Runtime.InteropServices
    Imports System.IO
    Imports System
    Imports System.Diagnostics
    Imports System.ComponentModel
     
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim xlApp As Excel.Application
            Dim xlWorkBook As Excel.Workbook
            Dim xlWorkSheet As Excel.Worksheet
            Dim sDT As String
            Dim today As Date = Now()
            sDT = CStr(today)
            xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
            If sDT <> "" And FileName.text <> "" Then
                xlWorkBook = xlApp.Workbooks.Open(FileName.Text) ' FileName is set by a OpenFileDialog control
                xlWorkSheet = xlWorkBook.Worksheets(1)
                xlApp.Visible = True
                xlWorkSheet.Range("A1").Value = "dummy value"
                xlWorkBook.SaveAs(FileName.Text + " " + sDT)
                xlWorkBook.Close()
            End If
            xlApp.Quit()
        End Sub
    Merci par avance pour votre aide.

  2. #2
    Membre éclairé Avatar de r.morel
    Homme Profil pro
    Dessinateur CAO
    Inscrit en
    Août 2014
    Messages
    336
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Dessinateur CAO
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2014
    Messages : 336
    Points : 667
    Points
    667
    Par défaut
    Salut,
    Montre nous comment tu gères ta variable FileName.
    Merci de ainsi que d'utiliser les boutons et

  3. #3
    Membre régulier
    Homme Profil pro
    Trader / Formateur / Développeur Options CBOE
    Inscrit en
    Septembre 2018
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afrique Du Sud

    Informations professionnelles :
    Activité : Trader / Formateur / Développeur Options CBOE
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2018
    Messages : 86
    Points : 70
    Points
    70
    Par défaut
    Merci. Je ne pense toutefois pas que FileName puisse poser problème ?
    Dans le projet VB.NET j'ai un contrôle OpenFileDialog et un TextBox qui s'appelle FileName.


    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
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Me.OpenFileDialog1.FileName = Nothing
            If Me.OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
                FileName.Text = Me.OpenFileDialog1.FileName
            End If
            Dim fo As Boolean
            fo = isFileOpen(FileName.Text)
            If fo Then
                MessageBox.Show("File is already open !")
            Else
                MessageBox.Show("Good to go !!!")
            End If
        End Sub
    Function IsFileOpen(ByRef sName As String) As Boolean
            Dim fs As FileStream
            Try
                fs = File.Open(sName, FileMode.Open, FileAccess.Read, FileShare.None)
                IsFileOpen = False
            Catch ex As Exception
                IsFileOpen = True
            End Try
     End Function

  4. #4
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    OK, il faut donc croire que ton FileName contient bien le nom de ton documents XLS avec son chemin complet.
    A partir de là, je trouve ton code un peu chargé.
    Voici (en espérant que cela t'aide) comment je peux accéder aux cellules de ma feuille de calcul, comment je peux y lancer une macro XLS, ...

    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
     
     
    ' OK pour tes imports :-)
     
    ' ensuite j'ai ceci :
     
    Public Class FMonForm
        Dim XLSAPP As Excel.Application
    ' ............
     
    ' et ensuite dans une procédure, sur le clic d'un bouton BExcel :
     
        Private Sub BExcel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BExcel.Click
            XLSAPP = New Excel.Application
            XLSAPP.Visible = True
            XLSAPP.Workbooks.Open("D:\Tmp\Test.xls")  'ouvir le fichier XLS
     
            ' Il est possible de programmer en VB ce qu'on ferait en Macro
            XLSAPP.Range("C4").Select()                 'sélectionner une cellule
            XLSAPP.ActiveCell.FormulaR1C1 = "127"   'y placer la valeur 127
     
            ' Il est aussi possible de lancer une macro du fichier XLS
            XLSAPP.Run("MaMacro") 'exécuter la macro MaMacro
     
     
            XLSAPP.ActiveWorkbook.Save() 'une sauvegarde
            XLSAPP.ActiveWorkbook.Close() 'fermer Excel, sinon Excel sera fermé à la fermeture de cette applcatioin VB.Net
        End Sub

  5. #5
    Membre régulier
    Homme Profil pro
    Trader / Formateur / Développeur Options CBOE
    Inscrit en
    Septembre 2018
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afrique Du Sud

    Informations professionnelles :
    Activité : Trader / Formateur / Développeur Options CBOE
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2018
    Messages : 86
    Points : 70
    Points
    70
    Par défaut
    Merci pour ton aide. Mon code est certes chargé car je fais pas mal d'essais tous aussi infructueux.
    Si je comprends bien le tien, tu lances une nouvelle instance d'Excel.
    J'ai donc fait un copié-collé de ton code et j'ai la même erreur (le fichier xlsx existe pourtant).
    il instancie bien un nouvel Excel, mais m'envoie toujours: System.Runtime.InteropServices.COMException: 'Excel cannot open the file 'Book1.xlsm' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.'

    Par ailleurs je préfererais vraiment utiliser capturer une instance existante, récupérer un handle et agir sur la feuille Excel...
    Ça n'a pas l'air simple !

  6. #6
    Membre averti Avatar de Delaney
    Homme Profil pro
    Developpeur VB amateur
    Inscrit en
    Mars 2014
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Developpeur VB amateur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 148
    Points : 372
    Points
    372
    Par défaut
    Salut,

    j'ai essayé ton code et j'ai obtenu dans un premier temps la même erreur que toi.

    j'ai juste fait une modif:
    j'ai mis juste avant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xlWorkBook = xlApp.Workbooks.Open(...)
    et cela a fonctionné.

    il y a quand même des lignes dans ton code qui m'interpellent comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
    PS : j'ai simplifié ton code pour faire les tests mais j'ai conservé ta philosophie. je peux t'envoyer mon code si besoin

  7. #7
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 904
    Points : 10 168
    Points
    10 168
    Billets dans le blog
    36
    Par défaut
    Bonjour

    En partant, createObject et GetObject ne sont pas les méthodes privilégiées pour piloter Excel, ou tout objet OLE, en fait, en .net. En fait, cela ne peut pas fonctionner sans la référence à Microsoft.VisualBasic.

    Quand j'aurai plus de temps (disons dans 2 ou 3 jours) je regarderai plus à fond.


    Ceci étant dit, tu peux explorer parmi ces exemples.


    Et il existe également des bibliothèques comme EPPlushttps://github.com/JanKallman/EPPlus et ClosedXml qui permettent de traiter des fichiers Excel en VB.net sans avoir besoin de passer par Excel. Et même sans avoir Excel sur sa machine
    À ma connaissance, le seul personnage qui a été diagnostiqué comme étant allergique au mot effort. c'est Gaston Lagaffe.

    Ô Saint Excel, Grand Dieu de l'Inutile.

    Excel n'a jamais été, n'est pas et ne sera jamais un SGBD, c'est pour cela que Excel s'appelle Excel et ne s'appelle pas Access junior.

  8. #8
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Cette fois, je vois !

    Il s'agit d'une incompatibilité de version d'Excel.

    Veux-tu faire le test suivant :
    1. Ouvre ta feuille Excel avec Excel et sauve-la sous la version Excel 2007, avec l'extension XLS (tu peux faire cela avec le menu d'Excel Enregistrer sous ... / Type de fichier et choisir Excel 2007).
    2. Après cette opération, mon code devrait fonctionner, le tiens aussi sans doute ...

    Tu auras la preuve qu'il y a une incompatibilité de version d'Excel.

    Ensuite, si tu veux vraiment travailler avec Office 2010 ou plus récent, il faudra chercher les librairies appropriées ...

  9. #9
    Membre régulier
    Homme Profil pro
    Trader / Formateur / Développeur Options CBOE
    Inscrit en
    Septembre 2018
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afrique Du Sud

    Informations professionnelles :
    Activité : Trader / Formateur / Développeur Options CBOE
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2018
    Messages : 86
    Points : 70
    Points
    70
    Par défaut
    Tout d'abord, merci à vous tous d'avoir regardé à mon code. J'ai beaucoup programmé de par le passé en C et C++ (librairies mathématiques essentiellement) et ceci est ma première aventure sur .NET. Je voudrais prototyper en VB.NET avant de me consacrer plutôt à C#.
    Ce que je vois à prime abord c'est qu'il y a plusieurs façons d'arriver à un résultat plus ou moins correct, qui au moins fonctionne, mais je n'ai pas la moindre idée de celle qui serait préconisée et pérenne.
    La modif d'Althorn fonctionne, mais pourquoi ? et surtout pourquoi avais je ce message d'erreur qui ne paraît pas approprié ?
    Phil, je n'ai pas essayé en format XLS 2007, car en fait je voudrais piloter un gros spreadsheet sous format XLSM et je ne suis pas sûr qu'il fonctionnerait correctement avec une ancienne version. Je travaille sous Office365 et j'ai déjà bien assez de soucis avec les particularités 32 et 64 bits.
    Enfin Clément, merci pour les liens. Je pense que celui-ci pourrait répondre à mes besoins: https://code.msdn.microsoft.com/Basi...Excel-4453945d.
    Une fois que j'aurais un peu dépatouillé tout ça, je posterai ma version de béotien à l'usage d'autres béotiens ici

  10. #10
    Membre averti Avatar de Delaney
    Homme Profil pro
    Developpeur VB amateur
    Inscrit en
    Mars 2014
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Developpeur VB amateur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 148
    Points : 372
    Points
    372
    Par défaut
    @Phil Rob : en fait non c'est pas ça, j'ai essayé tous les formats avant de faire la modif (j'avais lu cette éventualité sur d'autre forum)

    Par contre j'ai remarqué que lorsqu'on a l'erreur, une instance d'excel s'ouvre quand même mais elle ne s'affiche pas. J'ai repéré ça en ouvrant le gestionnaire des taches suite à un plantage et j'ai constaté que j'avais une quinzaine d'excels ouverts

    Je pense que la commande ne fait pas qu'afficher l'application mais active aussi tout un tas de truc et donc permet d'ouvrir le fichier.
    Malheureusement, je n'ai rien trouvé la dessus qui pourrait confirmer ou infirmer cela. C'est juste une intuition.

  11. #11
    Membre éclairé Avatar de r.morel
    Homme Profil pro
    Dessinateur CAO
    Inscrit en
    Août 2014
    Messages
    336
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Dessinateur CAO
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2014
    Messages : 336
    Points : 667
    Points
    667
    Par défaut
    Afin de tester si cela provient du fait de récupérer le processus Excel existant, remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xlApp = New ExcelApplication
    Merci de ainsi que d'utiliser les boutons et

  12. #12
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Après avoir enregistré ton classeur au format 2007, mon code doit fonctionner.
    Remarque que mon code inclus les conseils de Elthorn (xlApp.Visible = True) et de r.morel (xlApp = New ExcelApplication).
    En fait le problème de incompatibilité des "xlsm", je l'ai constaté en relançant du vieux code (celui que je t'ai posté) sur une feuille Excel récente et je l'ai résolu en faisant comme je te l'indiquais.
    Si ça ne marche pas ainsi ... ???
    Je veux bien chercher un peu plus, mais il me faudrait un document Excel (autre que celui de ton application, question de volume et de confidentialité) pour lequel mon code ne fonctionne pas sur ton ordi. Tu peux mettre un Zip en pièce jointe de ton prochain message.

    [Edit]
    Attention : Erreur de ma part
    Ce n'est pas au format 2007 qu'il faut sauver ton application Excel, mais bien au format 2003. Mais je crois qu'il ne propose pas 2007 et tu auras sûrement corrigé ...

    Il y a autre chose qui doit être fait :
    Outres les Imports, il faut ajouter une référence Net dans les référence du projet. Vois l'illustration ci-jointe.

    Par ailleurs, je te proposais de m'envoyer un document Excel pour que je teste sur mon ordi, mais je fais autrement : je place en attachement à ce message, mon projet VB complet, avec la feuille Excel désignée dans le code. Cela fonctionne correctement chez moi.

    Voici le fichier ProbExcel.zip et l'illustration ProbExcel.jpg.

    ProbExcel.zipNom : ProbExcel.jpg
Affichages : 464
Taille : 35,2 Ko

  13. #13
    Membre régulier
    Homme Profil pro
    Trader / Formateur / Développeur Options CBOE
    Inscrit en
    Septembre 2018
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afrique Du Sud

    Informations professionnelles :
    Activité : Trader / Formateur / Développeur Options CBOE
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2018
    Messages : 86
    Points : 70
    Points
    70
    Par défaut
    Merci, ton code marche bien, mais seulement après avoir enlevé puis ré-établi la référence citée.
    À la fermeture de la 'form', il y a bien un try-catch afin de fermer Excel mais Excel n'est visiblement pas fermé.
    Si je peux me permettre: Que faudrait il changer dans le code afin de récupérer la feuille Excel si elle est déjà ouverte?
    Merci encore
    Bruno

  14. #14
    Membre averti Avatar de Delaney
    Homme Profil pro
    Developpeur VB amateur
    Inscrit en
    Mars 2014
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Developpeur VB amateur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 148
    Points : 372
    Points
    372
    Par défaut
    Citation Envoyé par __bv__ Voir le message
    Que faudrait il changer dans le code afin de récupérer la feuille Excel si elle est déjà ouverte?
    si c'est ouvert dans excel indépendamment de ton code, va falloir que je creuse un peu pour te répondre car par défaut cela ouvre une deuxième instance de excel avec ton fichier en lecture seul. Il faut donc récupérer les infos d'un excel ouvert que ton programme ne connait pas.
    Si c'est déjà ouvert dans ton code, tu dois avoir l'instance en mémoire quelques part donc tu empêches la nouvelle ouverture et tu travailles sur l'instance en mémoire. Sinon tu auras le fichier ouvert une nouvelle fois en lecture seul. Si tu a plusieurs fichiers différents, tu crées un dictionnaire de workbooks pour les gerer.

  15. #15
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Perso, je pense qu'on doit pouvoir re-entrer dans la feuille (ou bien y enter alors qu'elle est déjà active par ailleurs) sans créer de nouvelle instance, mais je ne sais trop comment : j'y regarde tout à l'heure, je ne peux pas maintenant.
    Je te tiens au courant, à tantôt ...

  16. #16
    Membre averti Avatar de Delaney
    Homme Profil pro
    Developpeur VB amateur
    Inscrit en
    Mars 2014
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Developpeur VB amateur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 148
    Points : 372
    Points
    372
    Par défaut
    Salut,

    C'est bon j'ai un code qui fonctionne et qui permet d'avoir accès à un fichier Excel ouvert par Excel et non par VB
    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
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Me.OpenFileDialog1.FileName = Nothing
    If Me.OpenFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK Then
        Me.OpenFileDialog1.FileName = Me.OpenFileDialog1.FileName
    End If
    Dim myexcel As Excel.Application
    Dim xlWorkSheet As Excel.Worksheet
    Dim xlWorkBook As Excel.Workbook
     
    myexcel = GetObject(, "Excel.Application")
    xlWorkBook = myexcel.ActiveWorkbook
    xlWorkSheet = xlWorkBook.Worksheets(1)
    xlWorkSheet.Activate()
    xlWorkSheet.Range("A1").Value = "dummy value"
    myexcel.Visible = True
    End Sub
    attention, si tu as plusieurs fichiers ouverts, il faudra que tu gères le bon fichier avec un "for each" et un " if then "
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    For Each xlWorkBook In myexcel.Workbooks 
    If  xlWorkBook.Name = "nom_recherché" Then
    etc...
    (Bon maintenant je retourne bosser )

  17. #17
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut Un petit pas de plus ...
    Voici le code complet pour remplacer dans mon zip de cet après-midi (ne pas oublier d'ajouter un bouton nommé BFeuilleOuverte sur le Form) :
    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
     
    Imports System
    Imports System.Reflection
    Imports Excel = Microsoft.Office.Interop.Excel
     
    Public Class FBase
     
        Dim XLSAPP As Excel.Application = Nothing
     
        Private Sub BExcel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BExcel.Click
            XLSAPP = New Excel.Application
            XLSAPP.Visible = True
            XLSAPP.Workbooks.Open("D:\Tmp\ProbExcel\Test.xls")  'ouvir le fichier XLS
     
            ' Il est possible de programmer en VB ce qu'on ferait en Macro
            XLSAPP.Range("C4").Select()                 'sélectionner une cellule
            XLSAPP.ActiveCell.FormulaR1C1 = "127"   'y placer la valeur 127
     
            ' Il est aussi possible de lancer une macro du fichier XLS
            XLSAPP.Run("MaMacro") 'exécuter la macro MaMacro
     
            '' .............
        End Sub
     
        Private Sub BFeuilleOuverte_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BFeuilleOuverte.Click
            If Not XLSAPP Is Nothing Then
                If XLSAPP.ActiveWorkbook.Name = "Test.xls" Then
                    XLSAPP.Visible = True
                    XLSAPP.Range("C4").Select()                 'sélectionner une cellule
                    XLSAPP.ActiveCell.FormulaR1C1 = "359"   'y placer la valeur 127
                End If
            End If
        End Sub
     
        Private Sub FBase_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
            Try
                XLSAPP.Quit()
                XLSAPP = Nothing
            Catch
            End Try
        End Sub
     
    End Class
    Il est ainsi possible de reprendre la main dans l'application VB et de relancer la feuille Excel par le bouton BFeuilleOuverte.
    La procédure événementielle de ce bouton teste si le WorkBook en cours est bien celui utilisé par l'application, sinon elle ne fait rien.
    Pour pouvoir tester l'ActiveWorkbook.Name, il faut que l'XLSAPP soit instanciée, sinon erreur !!!
    C'est pour cette raison que la variable XLSAPP est maintenant déclarée dans la classe en dehors de toute procédure et elle est initialisée à Nothing. Cette valeur est changée par l'instanciation de la variable dans la procédure du bouton BExcel.

    Limite : Je peux donc retourner dans le document Excel ouvert par l'application VB mais cela ne fonctionne pas pour un document Excel ouvert par Excel lui-même, ou par une autre application.

    Je n'ai pas testé les codes de Elthorn parce qu'il utilise des références de type COM tandis que je m'en tiens autant que possible aux références .NET qui fournissent du code managé. Il ne s'agit là, de ma part, que d'un choix ni meilleur ni pire : j'évite ce qui n'est pas managé ainsi que la librairie Microsoft.VisualBasic.

    J'espère que ça va faire avancer ...

    Bonne soirée

  18. #18
    Membre averti Avatar de Delaney
    Homme Profil pro
    Developpeur VB amateur
    Inscrit en
    Mars 2014
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Developpeur VB amateur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2014
    Messages : 148
    Points : 372
    Points
    372
    Par défaut
    Bonsoir Phil Rob
    Dans ton code, tu utilises
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Imports Excel = Microsoft.Office.Interop.Excel
    qui te permet de gérer toutes tes commandes de l'application Excel.

    Comment tu fais pour l'utiliser sans avoir la Microsoft Excel xx.0 Object Library en référence (ou xx est le numéro de version, pour moi c'est 14) car cette librairie est de type COM (je la trouve pas ailleurs) et elle est obligatoire pour faire l'import ? tu références directement le fichier DLL ?

    Qu'est ce que tu appelles du "code managé" ?

    @__bv__

    j'ai oublié de préciser que mon dernier code permet d'activer et modifier un fichier déjà ouvert dans Excel par Excel lui même.

  19. #19
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    @Elthorn


    Je ne doute pas un instant du fonctionnement de ton code et moi, je ne suis pas arrivé au même résultat en évitant les références de type COM … 

    La notion de « code managé » concerne en fait les objets managés et la gestion de la mémoire : « Le ramasse-miettes ou garbage collector réalise la récupération des ressources allouées et devenues inutiles. Son travail est transparent pour le programmeur qui ne doit pratiquement jamais s'en occuper.
    Il existe toutefois des cas où il ne suffit pas de compter sur le ramasse-miettes. Ce dernier libère en effet automatiquement la mémoire allouée à un objet managé lorsque cet objet n'est plus utilisé, mais il est impossible de prévoir quand il va le faire.
    De plus, le ramasse-miettes n'a pas connaissance des ressources non managées telles que les handles de fenêtres et les fichiers et flux ouverts.
    Les objets managés sont ceux dont le code est spécifiquement conçu pour le Framework et sont, de ce fait, contrôlés par le CLR (Common language runtime). A l’inverse notamment, des composants appartenant à d'anciennes versions de VB se retrouvent parmi les objets non managés. Lorsqu'il doit ajouter une référence dans un projet, la fenêtre de dialogue qui s'ouvre au programmeur possède plusieurs onglets dont NET et COM. Les références proposées sous l'onglet NET sont des ressources managées. Celles de l'onglet COM ne le sont pas.
    Le programmeur peut parfois souhaiter que la libération d'une ressource soit immédiate. Il doit par ailleurs absolument libérer les ressources qui sont inconnues du ramasse-miettes.
    Plusieurs moyens existent pour libérer explicitement les ressources en association avec le ramasse-miettes. Ce sont les méthodes Close, Dispose et Finalize.
    L'étude des destructeurs est abordée un peu plus loin dans ces pages, mais il faut déjà noter qu'il est préférable d'utiliser la méthode Close quand l'objet concerné l'implémente. Cette méthode appelle la méthode Dispose sans lui passer de paramètres. Si l'objet ne possède pas cette méthode ou s'il est nécessaire de paramétrer le destructeur, il faut utiliser la méthode Dispose adéquate. La méthode Finalize de la classe Object ne doit jamais être appelée explicitement, elle est exécutée automatiquement lors de la destruction de l'objet. »

    L’espace de nom Microsoft.VisualBasic, a été créé pour permettre aux programmeurs VB 6.0 de retrouver bon nombre de leurs outils favoris, il donne notamment la commande Shell nécessaire à l’exécution de programmes externes (à noter que cette commande peut être remplacée par la commande Start).
    Cette librairie est référencée par défaut dans tout nouveau projet. Afin de se prémunir d’éventuelles incompatibilités futures, le programmeur doit n’utiliser les outils de Microsoft.VisualBasic que lorsqu’ils n’ont pas de remplaçant dans DotNet. Pour la plupart des applications, le programmeur peut même désactiver l’importation automatique de cette librairie. (ExtraitVisualBasic.pdf).

    Comment choisir entre .Net et Com lorsqu’on ajoute une référence. ? Attention, l'interface peut différer selon la version de VisualStudio utilisée : Solution en images dans le document ProbExcel.pdf ci-joint, lequel reprend aussi l'entièreté de ce message.

    Faudra quand même que je teste ton code ...

  20. #20
    Membre régulier
    Homme Profil pro
    Trader / Formateur / Développeur Options CBOE
    Inscrit en
    Septembre 2018
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afrique Du Sud

    Informations professionnelles :
    Activité : Trader / Formateur / Développeur Options CBOE
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2018
    Messages : 86
    Points : 70
    Points
    70
    Par défaut
    Merci pour votre aide mais ça n'a pas l'air de fonctionner (chez moi en tout cas) pour une feuille déjà ouverte.
    Cela crée une nouvelle copie de la feuille en lecture seule. Excel me propose donc de la mettre en "Read/Write" et de notifier la feuille ouverte précédemment.

    J'ai trouvé ce code:
    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
     
    Public Function FindOpenedWorkBooks() As List(Of Workbook)
        Dim OpenedWorkBooks As New List(Of Workbook)()
     
        Dim ExcelInstances As Process() = Process.GetProcessesByName("EXCEL")
        If ExcelInstances.Count() = 0 Then
            Return Nothing
        End If
     
        Dim ExcelInstance As Excel.Application = TryCast(Marshal.GetActiveObject("Excel.Application"), Excel.Application)
        If ExcelInstance Is Nothing Then Return Nothing
        Dim worksheets As Sheets = Nothing
        For Each WB As Workbook In ExcelInstance.Workbooks
            OpenedWorkBooks.Add(WB)
            worksheets = WB.Worksheets
            Console.WriteLine(WB.FullName)
            For Each ws As Worksheet In worksheets
                Console.WriteLine(ws.Name)
                Marshal.ReleaseComObject(ws)
            Next
        Next
     
        Marshal.ReleaseComObject(worksheets)
        worksheets = Nothing
        Marshal.FinalReleaseComObject(ExcelInstance)
        Marshal.CleanupUnusedObjectsInCurrentContext()
        ExcelInstance = Nothing
        Return OpenedWorkBooks
    End Function
     
    Private ExcelWorkBooks As List(Of Workbook) = New List(Of Workbook)()
     
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ExcelWorkBooks = FindOpenedWorkBooks()
     
        If ExcelWorkBooks IsNot Nothing Then
            Dim WBNames As New StringBuilder()
            For Each wb As Workbook In ExcelWorkBooks
                WBNames.AppendLine(wb.Name)
                Dim sheets As Sheets = wb.Worksheets
                Console.WriteLine($"Sheets No.: { sheets.Count}")
                For Each ws As Worksheet In sheets
                    Console.WriteLine($"WorkSheet Name: {ws.Name}  Columns: {ws.Columns.Count}  Rows: {ws.Rows.Count}")
                    Dim CellRange As Excel.Range = CType(ws.Cells(1, 1), Excel.Range)
                    Console.WriteLine(CellRange.Value2.ToString)
                    Marshal.ReleaseComObject(CellRange)
                    Marshal.ReleaseComObject(ws)
                Next
     
                Marshal.ReleaseComObject(sheets)
            Next
            MessageBox.Show(WBNames.ToString())
        End If
    End Sub
    Je n'arrive pas à le faire tourner, mais il me semble aussi sur la bonne voie, même si compliqué !
    Qu'en pensez vous ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Probléme ouverture fichier excel créé avec Jasperreport
    Par abderahime_13 dans le forum Jasper
    Réponses: 0
    Dernier message: 06/05/2010, 10h48
  2. [XL-2003] ouverture feuille excel à partir d'un userform
    Par mdambreville dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 09/05/2009, 17h55
  3. Problème rafraichissement feuille excel
    Par xav30 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 02/12/2007, 16h58
  4. Problème ouverture fichier excel
    Par modaffar dans le forum VB.NET
    Réponses: 10
    Dernier message: 05/07/2007, 09h20
  5. [VBA EXCEL]Ouverture feuille excel dans fenêtre maximale
    Par Lexot2 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 10/04/2007, 17h51

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