Utilisation de Range pour copier des cellule d'un fichier à un autre

Bonjour à vous,

Je suis en train de m'arracher les cheveux qui me restent sur mon crâne sur la manière de copier/coller un ensemble de cellules d'un fichier à un autre.

Mon premier fichier est un .xslm qui ne contient qu'un bouton, qui appelle une fonction qui demande d'ouvrir un fichier texte.

Dans ce fichier texte, un tableau de valeurs est enregistré et je souhaiterais en récupérer les colonnes de date et d'horaire.

Pour ce faire, je veux parcourir le fichier jusqu'à la ligne de date, enregistrer le numéro de la ligne de début et descendre jusqu'au bout du tableau et enregistrer la ligne de fin.

Ensuite je souhaiterais faire une copie du "Range" de la ligne (ligne_min,1) vers (ligne_max,2)

Malheureusement, je n'arrive pas à faire fonctionner la "fonction" Range comme je le souhaiterai dans ce second fichier.

Vous verrez, en commentaire, les essais que j'ai pu faire (j'ai commencé sérieusement puis j'ai essayé du farfelu parce que je n'avais plus d'idée).

Ma première question ne sera pas "Comment on fait pour résoudre le problème?", mais plutôt "Pourriez-vous m'expliquer ce que je fais mal dans ce code?"

Il semble évident qu'il y a des choses que je ne comprends pas trop ici.

Ensuite je souhaiterai comprendre pourquoi lorsque je fais un ActiveSheet.Range(Cells(v, w), Cells(x, y)).Select cela fonctionne bien dans le premier fichier, mais cela ne fonctionne pas dans celui que j'ouvre.

Je vous joins les fichier en question : le fichier avec le bouton et la macro et le second avec le tableau dont je souhaite retirer des informations.

En espérant que vous pourrez m'aider à comprendre, je vous souhaite une bonne soirée.

16test-macro.xlsm (33.22 Ko)
8test.zip (63.32 Ko)

Bonjour,

A tester :

Bonjour Galopin01

Bonjour,

Ma réponse ne sera pas une réponse à ta question, mais une observation : Ta question est mal posée !

En effet ce n'est pas un

Range(Cells(v, w), Cells(x, y)).Select

...qui ne fonctionne pas, mais le :

Range(Selection, Selection.End(xlDown)).Select

Et cette ligne ne veut pas dire grand chose !
Je suspecte que tu veux détecter la dernière ligne écrite, mais ça ne s'écrit pas comme ça... Ce serait plutot :

Dim MaVariable
MaVariable = Cells(3, 1).End(xlDown).Row
MsgBox MaVariable

...Et la suite un peu plus compliquée !

Je dirais que ce sont tes Select qui complique tout. D'une manière générale on préconise de ne jamais sélectionner.

Sinon pour la question que tu n'as pas posée je la résoudrai de la manière suivante :

Public Sub Traitement()
Dim fichier$, MyRange$
   fichier = Application.GetOpenFilename("DatAnalyst File (*.txt), *.txt")
   If fichier = "False" Then
      Exit Sub
   End If
   Workbooks.OpenText Filename:=fichier
   MyRange = ActiveSheet.UsedRange.Address
   ActiveSheet.Range(MyRange).Copy ThisWorkbook.ActiveSheet.Range(MyRange)
   Workbooks(2).Close
End Sub

EDIT : Pas rafraîchit... Salut Eric

A+

Bonjour à vous galopin01 et Eric,

Merci pour vos réponses! Je regarderai cela ce week-end (@Eric, je ne peux pas ouvrir ton fichier au bureau pour des questions relative à la sécurité, mais promis, sur mon PC perso je le testerai :-) ).

Bonne soirée à vous!

Bonsoir,

Il serait plus simple d'utiliser une requête Power Query pour récupérer ces données. En changeant la source de la requête PQ et en actualisant, on récupère directement la table. La source peut faire référence aussi à une zone nommée. Mes étapes ne sont pas du tout optimisées mais j'ai mis deux minutes à bâtir ma requête d'une manière intuitive, donc sans VBA.

Bonjour à vous,

Désolé de répondre si tard, mais je n'ai pas eu de temps pour bien comprendre, tester vos macro et faire mes propres expérimentations de mon côté plus tôt.

@Eric

Merci à nouveau pour cet exemple de code. Elle marche bien et j'ai appris de nouvelles choses :-)

Je m'en inspirerai pour plus tard. Juste quelques questions cependant:

Pourquoi avoir fait une nouvelle fonction OuvrirFichierTexte?

J'ai testé sans faire de fonction et cela fonctionne de la même manière. Est-ce pour l'esthétique du code?

Personnellement je trouve cela plus confus que de mettre tout à la suite, mais c'est une question de "goût".

Ou alors est pour qu'il y ait moins d'espace mémoire utilisé?

Les variable utiliseés ne me semblent pas prendre tant d'espace que cela, mais peut-être me trompais-je?

Dans la fonction OuvrirFichierTexte" je n'ai vraiment pas compris la raison de tout le texte après "Workbooks.OpenText Filename:=Chemin"

J'ai tout placé en commentaire et j'obtient le même résultat à la fin... Mais peut-être qu'il y a quelque chose qui m'échappe ici.

Pourriez-vous m'expliquer à quoi tout cela sert?

De ce que je comprends de la "fonction" Unload Me, cela sert à supprimer la fenêtre popup ainsi que vider la mémoire qui était utilisée pour les éléments de cette fenêtre.

Y a-t-il une raison de procéder ainsi plutôt que ce la fermer uniquement?

Finalement, et effectivement, le PowerQuery est une solution.

Mais il y a deux raisons pour laquelle je ne peux pas utiliser cela:

- je cherche à ce que ma fonction finale prélève des morceaux de tableau selon certains critères de valeurs et qu'elle crée différents tableaux séparés en fonction de celles-ci.

- je souhaite que cela soit "simple" d'utilisation car ce ne sera pas moi qui aurai à me servir du fichier à la fin. Un gros bouton "Traitement donnée" ne donnera pas le droit à l'erreur ;-)

@Galopin01

Je suis désolé et vous avez raison, mais je vous ai surtout donné un code mal présenté et vous n'avez pas bien saisi le soucis.

C'est bel est bien la fonction Range(Cells(v, w), Cells(x, y)).Select qui m'embête, mais je l'avais mise en commentaire (avec plein d'autres lignes), mais dans ma tête ça semblait clair (comme souvent quand on a la tête dans le guidon).

Je vous envoie une version "élaguée" des lignes inutiles pour que vous vous fassiez une idée.

Si vous déroulez le code vous constaterez que, dans le premier fichier ouvert, la fonction Range fait bien la sélection (A1:J10)... Mais dans le second, il retourne une erreur. Je vous conseille de mettre un point d'arrêt à cette ligne pour voir le message d'erreur.

A côté de cela, j'ai essayé avec "Copy", plutôt que "Select" et le problème reste le même (d'ailleurs le code que j'envoie est avec "Copy").

Je suis surprise par contre que vous me disiez que le problème vient de Range(Selection, Selection.End(xlDown)).Select et qu'elle ne veut pas dire grand chose.

En effet, il s'agit d'une fonction que j'ai "capturée" avec l'enregistreur de macro. Votre macro en tout cas est efficace effectivement! Merci également

Il me semble ainsi avoir compris grace à cela qu'en fait la fonction Range "accepte" qu'on utilise des String (ex. "A:B"), mais pas qu'on utilise Range(Cell(),Cell()) dans ce cas précis...

La raison pour laquelle j'aurais préféré avoir un pointeur de ligne dynamique plutôt que de faire une sélection générique est parce que je vais travailler sur des fichiers qui n'auront pas nécessairement des tailles identique et que je souhaiterais sélectionner des "bouts" de tableau selon des critère que je voudrais sélectionner.

Mais je suppose que je peux contourner le problème en copiant tout le tableau du fichier texte sur le fichier initial.

Mais cela reste frustrant de ne pas savoir pourquoi la fonction marche bien dans un cas et pas dans l'autre (une histoire de pointeur?).

Merci à tous les deux à nouveau :-)

Avec le fichier, c'est mieux :-)

13test-macro2.xlsm (40.03 Ko)

Pourquoi avoir fait une nouvelle fonction OuvrirFichierTexte?

C'est ma façon de coder. Contrairement à vous, je pense que le code est plus lisible en séparant les étapes.

Dans la fonction OuvrirFichierTexte" je n'ai vraiment pas compris la raison de tout le texte après "Workbooks.OpenText Filename:=Chemin"

Vous avez raison, j'aurais pu m'abstenir de mettre la partie FieldInfo. Cette partie sert à typer les colonnes. Si vous regardez le premier array, FieldInfo:=Array(Array(1, 4), la colonne est typée date contrairement aux autres laissées en standard.

De ce que je comprends de la "fonction" Unload Me, cela sert à supprimer la fenêtre popup ainsi que vider la mémoire qui était utilisée pour les éléments de cette fenêtre.

C'est une de mes règles de gestion également. Il y a très longtemps, il fallait faire attention à la gestion de la mémoire pour ne pas avoir de saturation de pile. Si vous regardez mon code, une variable instanciée est détruite dans la même procédure. Lorsque des variables doivent servir dans d'autres procédures ou fonctions, les valeurs sont passées en paramètres. Sur des codes complexes et longs, vous ne passez pas votre temps à chercher le problème. Il n'y a qu'avec les Userform que j'utilise des variables Public.


Concernant Power Query :

"Mais il y a deux raisons pour laquelle je ne peux pas utiliser cela:

- je cherche à ce que ma fonction finale prélève des morceaux de tableau selon certains critères de valeurs et qu'elle crée différents tableaux séparés en fonction de celles-ci.

- je souhaite que cela soit "simple" d'utilisation car ce ne sera pas moi qui aurai à me servir du fichier à la fin. Un gros bouton "Traitement donnée" ne donnera pas le droit à l'erreur ;-)"

Je souhaite seulement pour vous que votre remplaçant connaisse VBA et arrive à maintenir le code sans faire appel à une ressource extérieure (Cela dit, vous connaissez maintenant au moins une ressource... ). Power Query, c'est tout l'inverse de votre argumentaire tant du point de vue simplicité d'utilisation finale que de la fiabilité.

Actuellement, je travaille pour un client qui veut réduire drastiquement le temps pour établir une situation mensuelle. Il lui faut actuellement une journée, les fichiers à traiter sont monstrueux, les fichiers intermédiaires sont également monstrueux. Avec PQ, vous établissez les différentes étapes de traitement sans créer de table, un peu comme un calcul littéral en math, et vous ne réalisez le résultat qu'à la fin uniquement dans des tcd ou des graphiques dynamiques. Au lieu d'avoir des tonnes de MOctets, le résultat ne fait que quelques KOctets. Le but de ce travail est de traiter le tout en moins de 5 minutes (y compris la pause café ). L'avantage également est que les résultats seront directement exploitables dans Power BI (que je ne connais pas encore), fini les mises en forme longues et fastidieuses sur Power Point pour alimenter un CODIR...

Il va falloir quand même un peu mouiller le maillot pour y arriver...

Effectivement Ya quelque chose qui m'avait échappé dans ton capharnaüm !

La bonne syntaxe pour cette ligne :

    With ActiveSheet
    .Range(.Cells(1, 1), .Cells(10, 10)).Copy 
    End With

A+

Désolé Galopin01

J'aurais dû écrire :

Cela dit, vous connaissez maintenant au moins deux ressources...

Yapadkoi ! J'étais d'ailleurs à 2 doigts de plussoyer après ta première réponse mais je me suis abstenu, parce que je n'aime pas flooder et puis je ne maîtrise pas plus que ça PQ que je n'utilise que dans les cas les plus simple...

Comme beaucoup je n'utilise le forum que comme stimulant intellectuel, mais j'évite absolument le surmenage, me contentant de survoler l'actualité...

A+

Bonjour @galopin01 et Eric,

@galopin01

Merci de m'avoir montré la bonne syntaxe! Je n'ai pas encore eu le temps de tester cependant (coder des macros n'est pas mon activité principale ;-) )

@Eric

Merci pour vos réponses! Je travaille dans une petite entreprise: la personne qui se chargera d'exécuter mon code se trouvera forcément dans le bureau d'à côté... Et puis cela m'intéresse/amuse de faire un peu de code VBA et de tenter de le perfectionner.

De manière générale, merci à tous les deux pour votre aide :-) Bonne fin de semaine et portez-vous bien!

Rechercher des sujets similaires à "utilisation range copier fichier"