Recherche…


Cahiers de travail

Dans de nombreuses applications Excel, le code VBA effectue des actions sur le classeur dans lequel il est contenu. Vous enregistrez ce classeur avec une extension ".xlsm" et les macros VBA se concentrent uniquement sur les feuilles de calcul et les données à l'intérieur. Toutefois, vous devez souvent combiner ou fusionner des données provenant d'autres classeurs ou écrire certaines de vos données dans un classeur distinct. L'ouverture, la fermeture, la sauvegarde, la création et la suppression d'autres classeurs est un besoin commun pour de nombreuses applications VBA.

À tout moment dans l'éditeur VBA, vous pouvez afficher et accéder à tous les classeurs actuellement ouverts par cette instance d'Excel à l'aide de la propriété Workbooks de l'objet Application . La documentation MSDN l' explique par des références.

Quand utiliser ActiveWorkbook et ThisWorkbook

Il est recommandé de toujours spécifier le classeur auquel votre code VBA fait référence. Si cette spécification est omise, VBA suppose que le code est dirigé vers le classeur actuellement actif ( ActiveWorkbook ).

'--- the currently active workbook (and worksheet) is implied
Range("A1").value = 3.1415
Cells(1, 1).value = 3.1415

Toutefois, lorsque plusieurs classeurs sont ouverts simultanément, en particulier lorsque le code VBA s'exécute depuis un complément Excel, les références à ActiveWorkbook peuvent être confuses ou mal dirigées. Par exemple, un complément avec une fonction définie par l'utilisateur qui vérifie l'heure et le compare à une valeur stockée dans l'une des feuilles de calcul du complément (qui ne sont généralement pas facilement visibles par l'utilisateur) devra identifier explicitement le classeur être référencé. Dans notre exemple, notre classeur ouvert (et actif) a une formule dans la cellule A1 =EarlyOrLate() et n’a PAS de VBA écrit pour ce classeur actif. Dans notre complément, nous avons la fonction définie par l'utilisateur suivante:

Public Function EarlyOrLate() As String
    If Hour(Now) > ThisWorkbook.Sheets("WatchTime").Range("A1") Then
        EarlyOrLate = "It's Late!"
    Else
        EarlyOrLate = "It's Early!"
    End If
End Function

Le code pour le fichier UDF est écrit et stocké dans le complément Excel installé. Il utilise des données stockées sur une feuille de calcul dans le complément appelé "WatchTime". Si l'UDF avait utilisé ActiveWorkbook au lieu de ThisWorkbook , il ne serait jamais en mesure de garantir la destination du classeur.

Ouvrir un (nouveau) classeur, même s'il est déjà ouvert

Si vous souhaitez accéder à un classeur déjà ouvert, vous pouvez accéder directement à l'affectation de la collection Workbooks :

dim myWB as Workbook
Set myWB = Workbooks("UsuallyFullPathnameOfWorkbook.xlsx")

Si vous souhaitez créer un nouveau classeur, utilisez l'objet de collection Workbooks pour Add une nouvelle entrée.

Dim myNewWB as Workbook
Set myNewWB = Workbooks.Add

Il y a des moments où vous pouvez ne pas ou (ou vous en soucier) si le classeur dont vous avez besoin est déjà ouvert ou non, ou si cela n'existe pas. La fonction exemple montre comment toujours retourner un objet classeur valide.

Option Explicit
Function GetWorkbook(ByVal wbFilename As String) As Workbook
    '--- returns a workbook object for the given filename, including checks
    '    for when the workbook is already open, exists but not open, or
    '    does not yet exist (and must be created)
    '    ***  wbFilename must be a fully specified pathname
    Dim folderFile As String
    Dim returnedWB As Workbook
    
    '--- check if the file exists in the directory location
    folderFile = File(wbFilename)
    If folderFile = "" Then
        '--- the workbook doesn't exist, so create it
        Dim pos1 As Integer
        Dim fileExt As String
        Dim fileFormatNum As Long
        '--- in order to save the workbook correctly, we need to infer which workbook
        '    type the user intended from the file extension
        pos1 = InStrRev(sFullName, ".", , vbTextCompare)
        fileExt = Right(sFullName, Len(sFullName) - pos1)
        Select Case fileExt
            Case "xlsx"
                fileFormatNum = 51
            Case "xlsm"
                fileFormatNum = 52
            Case "xls"
                fileFormatNum = 56
            Case "xlsb"
                fileFormatNum = 50
            Case Else
                Err.Raise vbObjectError + 1000, "GetWorkbook function", _
                         "The file type you've requested (file extension) is not recognized. " & _
                         "Please use a known extension: xlsx, xlsm, xls, or xlsb."
        End Select
        Set returnedWB = Workbooks.Add
        Application.DisplayAlerts = False
        returnedWB.SaveAs filename:=wbFilename, FileFormat:=fileFormatNum
        Application.DisplayAlerts = True
        Set GetWorkbook = returnedWB
    Else
        '--- the workbook exists in the directory, so check to see if
        '    it's already open or not
        On Error Resume Next
        Set returnedWB = Workbooks(sFile)
        If returnedWB Is Nothing Then
            Set returnedWB = Workbooks.Open(sFullName)
        End If
    End If
End Function

Enregistrement d'un classeur sans demander à l'utilisateur

L'enregistrement de nouvelles données dans un classeur existant à l'aide de VBA entraîne souvent une question contextuelle indiquant que le fichier existe déjà.

Pour éviter cette question, vous devez supprimer ces types d'alertes.

Application.DisplayAlerts = False        'disable user prompt to overwrite file
myWB.SaveAs FileName:="NewOrExistingFilename.xlsx"
Application.DisplayAlerts = True         're-enable user prompt to overwrite file

Modification du nombre de feuilles de calcul par défaut dans un nouveau classeur

Le nombre "d'usine par défaut" de feuilles de calcul créées dans un nouveau classeur Excel est généralement défini sur trois. Votre code VBA peut définir explicitement le nombre de feuilles de calcul dans un nouveau classeur.

'--- save the current Excel global setting
With Application
    Dim oldSheetsCount As Integer
    oldSheetsCount = .SheetsInNewWorkbook
    Dim myNewWB As Workbook
    .SheetsInNewWorkbook = 1
    Set myNewWB = .Workbooks.Add
    '--- restore the previous setting
    .SheetsInNewWorkbook = oldsheetcount
End With


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow