Utilisation de plusieurs classeurs VBA

Bonjour,

Je suis actuellement entrain d'essayer d'utiliser plusieurs classeurs VBA pour extraire quelques données de l'un pour remplir l'autre.

Dim base As String 'Nom entier du chemin du second fichier
Dim nb As Integer 'Nombre de ligne du second fichier
Dim fichierbase As String 'Nom du second fichier
Dim file2 As Workbook 'Workbook du second fichier

'Fonction qui compte le nombre de ligne
Function nbLignebase()

file2.Activate
file2.Worksheets("Données exportées").Activate
Range("A2").Select
nb = Range("A2", Selection.End(xlDown)).Cells.Count

End Function

'Bouton où tout se passe
Private Sub Launcher_Click()

    'Ouverture du document
    If base <> "" Then
        Workbooks.Open Filename:=base
        fichierbase = ActiveWorkbook.Name
        Set file2 = Workbooks(fichierbase)

    Else

        MsgBox "Veuillez sélectionner un fichier"
        Exit Sub
    End If

    Call nbLignebase

End Sub

'Fonction qui permet de charger la base
Private Sub Parcourir_Click()

base = Application.GetOpenFilename("Fichiers Excel (*.xls; *.xlsx; *.xlsm),*.xls; *.xlsx; *.xlsm", , "Sélectionner la base")

If (LCase(base) <> "faux" And base <> "0") Then
    Sheets("Outil").Cells(5, 2) = base
End If

End Sub

Donc dans un premier temps, l'utilisateur rentre un fichier (base). J'en extrait son nom que je stock dans fichierbase.

Maintenant j'aimerais me rendre sur ce fameux fichierbase pour pouvoir compter les lignes. (pour réaliser des choses après bien sûr).

Malheureusement j'ai une erreur 1004 : "La méthode Select de la classe Range a échoué"

Pourtant je me suis bien appliqué à activer correctement (visiblement non) mes Workbooks...

Si quelqu'un pouvait m'éclairer là dessus pour bien manipuler les objets Workbooks !

Une autre question, pour revenir sur le fichier sur lequel je rentre le code : il faut que je paramètre au début un :

Dim file1 As Workbooks

file1 = ThisWorkbooks 

Et que je jongle entre le file1.Activate et les file2.Activate ?

En vous remerciant

Bonjour,

Houlala ! Je ne sais par quel bout le prendre...

Bon ! commençons soft ! C'est une bonne idée de penser à vouloir faire de la programmation modulaire. Il ne faut pas la perdre de vue. Ce sera certainement fort utile à l'avenir. Mais il faut commencer par le commencement et avoir défini un projet de façon globale et suffisamment détaillée, sinon exhaustive, pour modulariser le programme de façon efficace...

La méthode qui donnera les meilleurs résultats au démarrage, c'est d'avoir d'abord une idée très précise du déroulement de l'opération d'ensemble (ou des...) que l'on veut mener à terme, ce qui sera le fil conducteur de la procédure principale, et au fil de la construction d'en externaliser telle ou telle opération parcellaire, dans des procédures annexes (Sub ou Function selon les cas), soit parce qu'il s'agit d'éléments répétitifs que l'on gagnera à individualiser pour y faire appel autant de fois que nécessaire dans le déroulement, soit parce que cela donnera plus de clarté au code et éventuellement plus de fiabilité...

Mais au stade où tu en es, le projet apparaît encore nébuleux, on ne voit pas de justification à l'éclatement entre les diverses procédures que tu exposes, les liens entre elles demeurant quelque peu virtuels.

Mais penser de cette façon est toujours un élément positif. Continuons par un autre point qui ne l'est pas , mais que l'on peut rendre très vite positif.

Lorsqu'on travaille manuellement sur le tableur, on active, on sélectionne... c'est le moyen dont on dispose pour interagir avec l'application, si on lui susurait autrement ce que l'on veut ça ne marcherait pas ! Mais passant en VBA, on n'est plus dans Excel !

VBA, on lui dit quoi faire, de la façon adéquate, c'est le code, et il le fait, d'autant mieux et plus vite qu'il utilise ses propres moyens qui ne sont pas les nôtres quand nous travaillons manuellement. Ses rapports avec Excel se situent à un autre niveau que nous, et vouloir lui imposer de travailler de la même façon que nous le faisons avec Excel, c'est carrément au détriment de sa capacité d'action, c'est le freiner, lui mettre un boulet au pied...

Se persuader que dès que l'on pense activer ou sélectionner, c'est toujours a-priori une opération parasite, en trop, qui ne fait que ralentir... Lorsqu'un programme s'exécute, ce sera d'autant plus efficace et rapide que l'on ne voit rien ! que ça se passe en dehors des composants affichés, et même que le travail se fait pour l'essentiel hors Excel après prélèvement des données indispensables, si à la fin de l'exécution l'écran est le même qu'au départ, on saura que l'on aura introduit un élément important d'optimisation dans la programmation réalisée (hors activations automatique que l'on ne pourra éviter...)

Certes Select ou Activate sont des actions qui peuvent s'avérer nécessaires, ne serait-ce que pour présenter au regard de l'utilisateur le résultat du travail effectué, mais cela se passe alors à la fin, non pas comme préalable à une action qui n'en a pas besoin, et c'est alors la fin en soi, la dernière action avant de rendre la main à l'utilisateur.

Voyons les éléments de ton code. Pour l'instant, la seule chose que tu accomplis c'est de définir le nombre de ligne de données sur une feuille... il serait bon déjà de savoir de façon exacte quel est le résultat de l'action que l'on entame. D'une façon générale, il faut savoir où l'on doit arriver avant de partir. Le nombre de lignes de données n'est pas forcément l'élément le plus utile (connaissant la ligne début, si l'on doit parcourir ces lignes, il est plus utile de connaître la ligne de fin que leur nombre) mais laissons cela de côté tant que l'objectif n'est pas défini de façon détaillée et claire.

Ce qui saute aux yeux immédiatement, ce sont tes déclarations de variables niveau module qui présente d'emblée une redondance excessive : pour un même classeur on va disposer d'une variable pour le nom avec chemin, une autre pour le nom seul et une 3e pour l'affecter en tant qu'objet ! Et tout ça au niveau module ! C'est au moins un gaspillage éhonté !

Déjà rien ne justifie ces éléments en variables modules, et tant qu'une variable module n'est pas indispensable, on s'abstient !

Le nom + l'objet, ça fait au moins un de trop...

En matière de variable, il faut ce qu'il faut, ne pas lésiner pour le nécessaire, mais pas plus que le nécessaire.

La 2e chose qui apparaît c'est une fonction, quelque peu superflue d'un côté au regard de ce à quoi tu la destines, mais en plus amputée dès le départ de la caractéristique propre d'une fonction : une fonction renvoie un résultat, la tienne ne renvoie rien !

Après, éclater en deux procédures ce qui logiquement constitue les morceaux d'une même opération, et la façon de le faire n'apparaît pas très judicieux. Je ne vois pas non plus de justification à écrire sur la feuille...

Voilà un bout de code pour réaliser ce que tu peux faire avec les éléments invoqués : ouvrir un fichier et définir le nombre de lignes de données. A titre d'illustration...

Sub Test()
    Dim file2 As Workbook, base, nb%
    base = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", , _
     "Sélectionner la base")
    If base = False Then Exit Sub
    Set file2 = Workbooks.Open(base)
    With file2.Worksheets("Données exportées")
        nb = .Cells(.Rows.Count, 1).End(xlUp).Row - 1
    End With
    MsgBox "La base sélectionnée comporte " & nb & " lignes de données."
End Sub

Mais normalement, lorsqu'on commence à écrire la procédure on sait déjà très exactement où l'on doit arriver...

(Pour le moment on reste au stade de l'exercice gratuit...)

Cordialement.

NB- Du soin à l'écriture du code est indispensable pour travailler correctement dessus : ne pas délayer en sautant des lignes en permanence cela ralentit la lecture, et indenter systématiquement de façon que l'on puisse voir sa structure au premier coup d'oeil.

Bonjour MFerrand,

Tout d'abord : merci d'avoir pris le temps de rédiger votre réponse, sachez que je prendrais en compte ce que vous avez écrit.

Cela fait maintenant quelques semaines que j'apprends tout seul le VBA donc autant vous dire qu'il y a un tas de chose qui peuvent paraître primordiale que je ne respecte donc pas .

J'ai appris pleins de choses grâce à vous !

Votre code marche, je vais bien sûr l'adapter puisque je veux que ces actions passent par des boutons (vis à vis de l'utilisateur je trouve cela plus interactif).

J'ai fait le choix d'écrire sur la feuille pour créer un "interface" avec l'utilisateur. En effet l'idée est qu'en plusieurs étapes il réalise la saisie de toutes les données nécessaires pour la réalisation de la méthode principale. C'est pour cela que j'ai fait le choix d'éclater en différents modules.

J'ai déjà réalisé un outil utilisant tout un tas d'interface utilisateurs (Userforms), du coup je m'essai à rédiger sur une page les différentes étapes de suivis (le chemin du fichier, des dates mais il ne me semblait pas judicieux de rédiger le code dans mon message puisque mon problème ne se portait pas dessus).

Pour ce qui est du saut de ligne et de l'indentation je vous en remercie , je ne savais pas du tout.

Donc corrigez moi si je me trompe, mon erreur principale est porté sur l'utilisation abusive de .Select et .Activate qui sont des propriétés adaptées pour l'utilisateur.

Ne vous en faites pas, ce n'est pas un exercice gratuit, c'est juste que pour mener à bien mon projet j'ai besoin d’interagir entre différentes pages : chose que je n'arrivais pas à faire en utilisant des .Select .Activate.

La preuve en est j'ai quasiment fini mon outil grâce à vos conseils 8)

Rechercher des sujets similaires à "utilisation classeurs vba"