web-dev-qa-db-fra.com

Ouvrir un fichier Excel pour lire avec VBA sans affichage

Je souhaite effectuer une recherche dans les fichiers Excel existants avec une macro, mais je ne souhaite pas afficher ces fichiers lorsqu'ils sont ouverts par le code. Existe-t-il un moyen de les ouvrir "en arrière-plan", pour ainsi dire?

55
notnot

Pas sûr de pouvoir les ouvrir de manière invisible dans l'instance Excel actuelle

Vous pouvez cependant ouvrir une nouvelle instance d'Excel, la masquer, puis ouvrir les classeurs.

Dim app as New Excel.Application
app.Visible = False 'Visible is False by default, so this isn't necessary
Dim book As Excel.Workbook
Set book = app.Workbooks.Add(fileName)
'
' Do what you have to do
'
book.Close SaveChanges:=False
app.Quit
Set app = Nothing

Comme d'autres l'ont posté, assurez-vous de nettoyer après avoir terminé tous les classeurs ouverts.

72
Patrick McDonald

Si cela vous convient, j'utiliserais simplement

Application.ScreenUpdating = False

avec l'avantage supplémentaire d'accélérer votre code, au lieu de le ralentir en utilisant une seconde instance d'Excel.

30
Patrick Honorez

Pour ouvrir un classeur masqué dans l'instance existante d'Excel, utilisez ce qui suit:

    Application.ScreenUpdating = False
    Workbooks.Open Filename:=FilePath, UpdateLinks:=True, ReadOnly:=True
    ActiveWindow.Visible = False
    ThisWorkbook.Activate
    Application.ScreenUpdating = True
18
Ashok

Même si vous avez la réponse, pour ceux qui trouvent cette question, il est également possible d'ouvrir une feuille de calcul Excel en tant que magasin de données JET. Emprunter la chaîne de connexion d'un projet sur lequel je l'ai utilisé, cela ressemblera un peu à ceci:

strExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & objFile.Path & ";Extended Properties=""Excel 8.0;HDR=Yes"""
strSQL = "SELECT * FROM [RegistrationList$] ORDER BY DateToRegister DESC"

Notez que "RegistrationList" est le nom de l'onglet dans le classeur. Quelques tutoriels circulent sur le Web avec les détails de ce que vous pouvez et ne pouvez pas faire pour accéder à une feuille de cette façon.

Je pensais juste ajouter. :)

11
AnonJr

Une approche beaucoup plus simple qui ne nécessite pas de manipuler des fenêtres actives:

Dim wb As Workbook
Set wb = Workbooks.Open("workbook.xlsx")
wb.Windows(1).Visible = False

D'après ce que je peux dire, l'index Windows sur le classeur devrait toujours être 1. Si quelqu'un connait des conditions de course qui rendraient cela inexact, merci de me le faire savoir.

7
Anthony Lusardi

Le problème des réponses à la fois d'iDevlop et d'Ashok est que le problème fondamental est un défaut de conception d'Excel (apparemment) dans lequel la méthode Open ne parvient pas à respecter le paramètre Application.ScreenUpdating de False. Par conséquent, le paramétrer sur False n’est pas avantageux pour ce problème.

Si la solution de Patrick McDonald est trop lourde en raison du temps système nécessaire pour démarrer une deuxième instance d'Excel, la meilleure solution que j'ai trouvée consiste à réduire le temps pendant lequel le classeur ouvert est visible en réactivant le plus rapidement possible la fenêtre d'origine:

Dim TempWkBk As Workbook
Dim CurrentWin As Window

Set CurrentWin = ActiveWindow
Set TempWkBk = Workbooks.Open(SomeFilePath)
CurrentWin.Activate      'Allows only a VERY brief flash of the opened workbook
TempWkBk.Windows(1).Visible = False 'Only necessary if you also need to prevent
                                    'the user from manually accessing the opened
                                    'workbook before it is closed.

'Operate on the new workbook, which is not visible to the user, then close it...
3
pstraton

Ouvrez-les à partir d'une nouvelle instance d'Excel.

Sub Test()

    Dim xl As Excel.Application
    Set xl = CreateObject("Excel.Application")

    Dim w As Workbook
    Set w = xl.Workbooks.Add()

    MsgBox "Not visible yet..."
    xl.Visible = True

    w.Close False
    Set xl = Nothing

End Sub

Vous devez vous rappeler de nettoyer après que vous avez terminé.

1
guillermooo

Ouvrez le classeur en tant que masqué, puis définissez-le comme "enregistré" afin que les utilisateurs ne soient pas invités à se fermer.

Dim w As Workbooks

Private Sub Workbook_Open()
    Application.ScreenUpdating = False
    Set w = Workbooks
    w.Open Filename:="\\server\PriceList.xlsx", UpdateLinks:=False, ReadOnly:=True 'this is the data file were going to be opening
    ActiveWindow.Visible = False
    ThisWorkbook.Activate
    Application.ScreenUpdating = True
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    w.Item(2).Saved = True 'this will suppress the safe Prompt for the data file only
End Sub

Ceci est un peu dérivé de la réponse postée par Ashok.

En procédant ainsi, vous ne serez pas invité à enregistrer les modifications dans le fichier Excel à partir duquel vous avez lu. C'est très bien si le fichier Excel que vous avez lu est conçu comme source de données pour la validation. Par exemple, si le classeur contient des noms de produit et des données de prix, il peut être masqué et vous pouvez afficher un fichier Excel qui représente une facture avec des listes déroulantes pour le produit validé à partir de cette liste de prix.

Vous pouvez ensuite stocker la liste de prix sur un emplacement partagé sur un réseau quelque part et la rendre en lecture seule.

1
Pen123

Dans Excel, masquez les classeurs et enregistrez-les comme masqués. Lorsque votre application les charge, elles ne seront pas affichées.

Edit: lors de la relecture, il est devenu évident que ces cahiers ne font pas partie de votre application. Une telle solution serait inappropriée pour les classeurs utilisateur.

0
JohnW