J'ai un fichier texte très long et j'ai besoin d'en récupérer seulement les 5 dernières lignes.
Utilise cette macro:
Sub test()
Dim file_name As String
Dim file_length As Long
Dim fnum As Integer
Dim bytes() As Byte
Dim txt As String
Dim i As Integer
file_name = "F:DocFloessai.txt"
file_length = FileLen(file_name)
f2 = 1000
f1 = file_length - f2
fnum = FreeFile
Open file_name For Binary As #fnum
ReDim bytes(1 To f2)
Get #fnum, f1 + 1, bytes
Close fnum
' Afficher résultats
For i = 1 To f2
txt = txt & Chr(Format$(bytes(i)))
Next i
Debug.Print txt
End Sub
Sub test()
Dim file_name As String
Dim file_length As Long
Dim fnum As Integer
Dim bytes() As Byte
Dim txt As String
Dim i As Integer
file_name = "F:DocFloessai.txt"
file_length = FileLen(file_name)
f2 = 1000
f1 = file_length - f2
fnum = FreeFile
Open file_name For Binary As #fnum
ReDim bytes(1 To f2)
Get #fnum, f1 + 1, bytes
Close fnum
' Afficher résultats
For i = 1 To f2
txt = txt & Chr(Format$(bytes(i)))
Next i
Debug.Print txt
End Sub
Mishell,
Ajouté ou modifié le 05/04/2008 (N°1988)
Ajouté ou modifié le 05/04/2008 (N°1988)
J'importe dans excel un texte comportant des retour chariot. Comment utiliser ce retour chariot comme indicateur pour répartir les données dans plusieurs colonnes.
Utilise le menu données/convertir. Le retour chariot n'est pas proposé dans les options de base mais tu peux l'obtenir en tapant dans "séparateur autre" Alt 010.
GeeDee,
Ajouté ou modifié le 25/11/2007 (N°1929)
Ajouté ou modifié le 25/11/2007 (N°1929)
Comment imprimer par macro une feuille ou tout un classeur Excel vers un document pdf sans avoir à saisir le nom de ce fichier dans la boite de dialogue usuelle ?
Méthodes utilisant Acrobat Distiller :
Testé sur PC avec Acrobat Distiller 5.0, Excel 2002, XP pro 2002 sp1.
Dans le projet, il faut référencer Acrobat Distiller (Outils, Références).
1er exemple imprimant la feuille active vers un PDF. Ici le nom est fixé.
La macro peut être associée à un bouton.
' **********************************************************************
Private Sub Imprime1PDF()
' original code there : http://www.rdpslides.com/psfaq/FAQ00053.htm
' adaptée par Trirème, MPFE, septembre 2007
' L'impression dans un fichier via l'imprimante Acrobat Distiller
' génère un fichier PostScript. On nomme ce fichier avec l'extension .ps
' (mais ça n'est pas obligatoire).
' Dans un deuxième temps ce fichier .PS est converti en .PDF
' Éventuellement cette conversion peut se dérouler en tâche de fond
' automatiquement pendant que la macro continue son exécution.
' Nécessite le référencement à Acrobat Distiller
' http://www.adobe.com/devnet/acrobat/pdfs/distiller_api_reference.pdf
' Define the postscript and .pdf file names.
Dim PSFileName As String
Dim PDFFileName As String
Dim myPDF As PdfDistiller
PSFileName = "c:myPostScript.ps" ' Nom complet
PDFFileName = "c:myPDF.pdf" ' Nom complet
ParametreName = "c:MesReglages.jopboptions" ' Nom complet
Set myPDF = New PdfDistiller ' Création d'une instance Distiller
'
myPDF.bSpoolJobs = 0 ' option =0 : conversion immédiate puis reprise de la macro
' à utiliser si la macro imprime un seul document.
' option =1 : conversion en tâche de fond dans un spool
' à utiliser si la macro imprime plusieurs documents dans une boucle
' on gagne ainsi 2-3 secondes à chaque fois.
' Cependant, avec l'option .bSpoolJobs = 1 il faut s'assurer que l'impression se termine
' avant de fermer l'instance de distiller par : Set myPDF = Nothing
' au risque que l'impression du dernier document n'ait pas le temps d'aboutir.
' Bien qu'il existe des évènements permettant de connaitre la fin d'exécution du Job,
' le plus simple est de prévoir une petite temporisation comme ci-dessous :
' Debut = Timer
' Do While Timer < Debut + 3 ' 3 secondes
' Loop
' Set myPDF = Nothing '
'
' Print the Excel sheet to the postscript file
Dim MySheet As Worksheet
Set MySheet = ActiveSheet
' Création du fichier .PS
MySheet.Range("myRange").PrintOut copies:=1, preview:=False, _
ActivePrinter:="Acrobat Distiller", printtofile:=True, collate:=True, _
prtofilename:=PSFileName
' Convert the postscript file to .PDF
myPDF.FileToPDF PSFileName, PDFFileName, ""
' Syntaxe plus complète, si l'on a défini son fichier d'options
' myPDF.FileToPDF PSFileName, PDFFileName, ParametreName
Set myPDF = Nothing ' voir remarque ci-dessus sur myPDF.bSpoolJobs = 1
End Sub' **********************************************************************
2ème exemple, une cellule d'une feuille prend plusieurs valeurs successivement. On imprime cette feuille en PDF avant de passer à la valeur suivante. Le nom du fichier PDF change à chaque fois.
' **********************************************************************
Private Sub Imprime2PDF()
' original code there : http://www.rdpslides.com/psfaq/FAQ00053.htm
' adaptée par Trirème, MPFE, septembre 2007
' Nécessite le référencement à Acrobat Distiller
' http://www.adobe.com/devnet/acrobat/pdfs/distiller_api_reference.pdf
' Define the postscript and .pdf file names.
Dim PSFileName As String
Dim PDFFileName As String
Dim myPDF As PdfDistiller
Dim i as Integer
Set myPDF = New PdfDistiller
' Print the Excel sheet to the postscript file
Dim MySheet As Worksheet
Set MySheet = ActiveSheet
For i = 1 To 5
[A1] = "Essais impressions PDF, fichier n° " & i
PSFileName = "C:myPostScript" & i & ".ps"
' PDFFileName = "C:myPDF" & i & ".pdf" ' optionnel
MySheet.PrintOut copies:=1, ActivePrinter:="Acrobat Distiller", printtofile:=True, prtofilename:=PSFileName
' Convert the postscript file to .pdf
myPDF.FileToPDF PSFileName, "", ""
Next
Set myPDF = Nothing
End Sub
' **********************************************************************
2ème méthode, on "imprime" dans un fichier .PS. Acrobat Distiller le convertit en .PDF.
Dans le projet, il n'est plus nécessaire de référencer Acrobat Distiller.
Il faut rédiger l'instruction d'impression comme ceci :
PSFileName="C:MonDossierin" & "MonFichier.PS"
MySheet.Range("myRange").PrintOut copies:=1, preview:=False, _
ActivePrinter:="Acrobat Distiller", printtofile:=True, collate:=True, _
prtofilename:=PSFileName
Dans un second temps on lance Acrobat Distiller, on vérifie qu'il "surveille" le dossier "C:MonDossier" (sans le 'in'), on ajuste éventuellement les options de conversions et les paramètres de protection pour ce dossier sinon les derniers utilisés seront pris en compte.
MySheet.Range("myRange").PrintOut peut être remplacé par :
• MonClasseur.PrintOut où MonClasseur est un objet classeur
• ActiveSheet.PrintOut
• Range
• Chart… voir l'aide…
Testé sur PC avec Acrobat Distiller 5.0, Excel 2002, XP pro 2002 sp1.
Dans le projet, il faut référencer Acrobat Distiller (Outils, Références).
1er exemple imprimant la feuille active vers un PDF. Ici le nom est fixé.
La macro peut être associée à un bouton.
' **********************************************************************
Private Sub Imprime1PDF()
' original code there : http://www.rdpslides.com/psfaq/FAQ00053.htm
' adaptée par Trirème, MPFE, septembre 2007
' L'impression dans un fichier via l'imprimante Acrobat Distiller
' génère un fichier PostScript. On nomme ce fichier avec l'extension .ps
' (mais ça n'est pas obligatoire).
' Dans un deuxième temps ce fichier .PS est converti en .PDF
' Éventuellement cette conversion peut se dérouler en tâche de fond
' automatiquement pendant que la macro continue son exécution.
' Nécessite le référencement à Acrobat Distiller
' http://www.adobe.com/devnet/acrobat/pdfs/distiller_api_reference.pdf
' Define the postscript and .pdf file names.
Dim PSFileName As String
Dim PDFFileName As String
Dim myPDF As PdfDistiller
PSFileName = "c:myPostScript.ps" ' Nom complet
PDFFileName = "c:myPDF.pdf" ' Nom complet
ParametreName = "c:MesReglages.jopboptions" ' Nom complet
Set myPDF = New PdfDistiller ' Création d'une instance Distiller
'
myPDF.bSpoolJobs = 0 ' option =0 : conversion immédiate puis reprise de la macro
' à utiliser si la macro imprime un seul document.
' option =1 : conversion en tâche de fond dans un spool
' à utiliser si la macro imprime plusieurs documents dans une boucle
' on gagne ainsi 2-3 secondes à chaque fois.
' Cependant, avec l'option .bSpoolJobs = 1 il faut s'assurer que l'impression se termine
' avant de fermer l'instance de distiller par : Set myPDF = Nothing
' au risque que l'impression du dernier document n'ait pas le temps d'aboutir.
' Bien qu'il existe des évènements permettant de connaitre la fin d'exécution du Job,
' le plus simple est de prévoir une petite temporisation comme ci-dessous :
' Debut = Timer
' Do While Timer < Debut + 3 ' 3 secondes
' Loop
' Set myPDF = Nothing '
'
' Print the Excel sheet to the postscript file
Dim MySheet As Worksheet
Set MySheet = ActiveSheet
' Création du fichier .PS
MySheet.Range("myRange").PrintOut copies:=1, preview:=False, _
ActivePrinter:="Acrobat Distiller", printtofile:=True, collate:=True, _
prtofilename:=PSFileName
' Convert the postscript file to .PDF
myPDF.FileToPDF PSFileName, PDFFileName, ""
' Syntaxe plus complète, si l'on a défini son fichier d'options
' myPDF.FileToPDF PSFileName, PDFFileName, ParametreName
Set myPDF = Nothing ' voir remarque ci-dessus sur myPDF.bSpoolJobs = 1
End Sub' **********************************************************************
2ème exemple, une cellule d'une feuille prend plusieurs valeurs successivement. On imprime cette feuille en PDF avant de passer à la valeur suivante. Le nom du fichier PDF change à chaque fois.
' **********************************************************************
Private Sub Imprime2PDF()
' original code there : http://www.rdpslides.com/psfaq/FAQ00053.htm
' adaptée par Trirème, MPFE, septembre 2007
' Nécessite le référencement à Acrobat Distiller
' http://www.adobe.com/devnet/acrobat/pdfs/distiller_api_reference.pdf
' Define the postscript and .pdf file names.
Dim PSFileName As String
Dim PDFFileName As String
Dim myPDF As PdfDistiller
Dim i as Integer
Set myPDF = New PdfDistiller
' Print the Excel sheet to the postscript file
Dim MySheet As Worksheet
Set MySheet = ActiveSheet
For i = 1 To 5
[A1] = "Essais impressions PDF, fichier n° " & i
PSFileName = "C:myPostScript" & i & ".ps"
' PDFFileName = "C:myPDF" & i & ".pdf" ' optionnel
MySheet.PrintOut copies:=1, ActivePrinter:="Acrobat Distiller", printtofile:=True, prtofilename:=PSFileName
' Convert the postscript file to .pdf
myPDF.FileToPDF PSFileName, "", ""
Next
Set myPDF = Nothing
End Sub
' **********************************************************************
2ème méthode, on "imprime" dans un fichier .PS. Acrobat Distiller le convertit en .PDF.
Dans le projet, il n'est plus nécessaire de référencer Acrobat Distiller.
Il faut rédiger l'instruction d'impression comme ceci :
PSFileName="C:MonDossierin" & "MonFichier.PS"
MySheet.Range("myRange").PrintOut copies:=1, preview:=False, _
ActivePrinter:="Acrobat Distiller", printtofile:=True, collate:=True, _
prtofilename:=PSFileName
Dans un second temps on lance Acrobat Distiller, on vérifie qu'il "surveille" le dossier "C:MonDossier" (sans le 'in'), on ajuste éventuellement les options de conversions et les paramètres de protection pour ce dossier sinon les derniers utilisés seront pris en compte.
MySheet.Range("myRange").PrintOut peut être remplacé par :
• MonClasseur.PrintOut où MonClasseur est un objet classeur
• ActiveSheet.PrintOut
• Range
• Chart… voir l'aide…
Trirème,
Ajouté ou modifié le 08/09/2007 (N°1902)
Ajouté ou modifié le 08/09/2007 (N°1902)
Après avoir fait un copier coller d'une page web dans excel, comment supprimer toutes les images pour ne garder que des cellules au format texte ou numérique.
Si tu en as beaucoup, tu peux essayer cette petite procédure qui supprime les images de la feuille de calcul active :
Sub Macro()
ActiveSheet.Pictures.Delete
End Sub
Sub Macro()
ActiveSheet.Pictures.Delete
End Sub
Jocelyn Vaillancourt,
Ajouté ou modifié le 07/01/2006 (N°1728)
Ajouté ou modifié le 07/01/2006 (N°1728)
Comment lire et écrire simultanément des données dans un fichier texte à partir d'excel ?
L'ACCES ALEATOIRE
Contrairement à l'accès séquentiel, l'accès aléatoire permet de travailler simultanément en lecture et écriture sur un fichier ouvert. Le travail avec les fichiers aléatoires repose sur les Types définis par l'utilisateur. Je vous reporte à la structure "Type personnage"
type personnage
nom as string * 40 'Garde 40 caractères pour le nom
age as byte 'Maximun de 256 ans par personne
sexe as string * 8 'Masculin = 8 caractères, Féminin = 7 caractères
end type
dim personnes(10) as personnage 'Établir un tableau de 10 personnes à 3 données par personne
Un type défini par l'utilisateur débute par l'instruction type et se termine par l'instruction End Type. Contrairement aux tableaux traditionnels, qui sont limités à un seul type de données, les types définis par l'utilisateur permettent de regrouper sous une structure unique des types différents de données. C'est ainsi qu'il est possible de traiter ensemble des textes et des nombres.
L'instruction dim, permet de déclarer un tableau contenant 10 ensembles correspondant à personnage.
Pour accéder à un élément particulier du tableau, il suffit de l'appeler en mettant l'indice. Par exemple, pour appeler le nom du premier individu on mettra:
lenom = personnes(1).nom
Pour le sexe de la dixième personne:
lesexe = personnes(10).sexe
Notons, en passant, que le type défini par l'utilisateur peut être utilisé ailleurs qu'avec des fichiers à accès aléatoire.
Pour en revenir à nos fichiers proprement dits, nous pouvons dire, en comparaison avec les fichiers à accès séquentiel, qu'ici la longueur des enregistrements est fixe. Cela signifie donc, que si nous mettons un nom de 20 caractères dans un espace, (certains disent un champ) prévu pour 40 (cela pourrait aussi bien être 60 ou 100, que 10, c'est à la discrétion du programmeur, en fonction des besoins), il y aura obligatoirement 20 blancs d'ajoutés au bout du nom. C'est pour cela qu'il est tout indiqué de les supprimer avec rtrim(), après la lecture du fichier et avant toute
opération. (Sinon, toutes vos comparaisons vont planter et vous risquez d'avoir des problèmes de formatage).
En contrepartie, un nom qui aurait plus de 40 caractères, serait purement et simplement tronqué à partir du 41e caractère. C'est donc dire qu'il faut choisir avec soin la taille maximale des enregistrements. Il faut souvent faire un compromis entre la capacité d'emmagasiner tous les noms possibles et impossibles, et le fait que la taille des fichiers augmente en conséquence.
Contrairement à un fichier à accès séquentiel, on peut accéder directement à une information d'un fichier à accès aléatoire sans lire toutes les données précédentes. Cependant, si vous effacez des données dans un fichier de ce type, il est avantageux de réécrire de nouvelles données à la place des données effacées. Sauf erreur de ma part, VBA ne compacte pas ces fichiers automatiquement. Il faut donc éviter de laisser des blancs inutiles. Vous noterez que c'est pour cela que les systèmes de gestion de bases de données ont un utilitaire de compactage des fichiers de bases de données.
L'ouverture de ce type de fichier passe par l'instruction suivante:
open "fichier" for random as numfichier len = len(type défini par l'utilisateur)
S'il n'y a pas de fichier d'ouvert, le fichier peut prendre n'importe quel numéro choisi par le programmeur. Pour ma part, le premier fichier que j'ouvre prend, je ne sais pas pourquoi, le numéro 1. Comme c'est moi qui décide, je décrète que mon fichier s'appelle Gaston.don .
Donc:
Open "Gaston.don" for random as 1 len = len (personnage)
La longueur s'exprime en octets, calculée principalement sur ces bases.
Pour des textes : 1 octet par caractère, incluant les blancs. donc String * 40 veut dire 40 octets.
Pour des nombres:
Byte : 1 octet
Integer (Entier) : 2 octets
Long (Entier long) : 4 octets
Single (Virgule flottante en simple précision) : 4 octets
Double (Virgule flottante en double précision) : 8 octets
Si vous écrivez un nouveau fichier, vous pouvez utiliser un compteur comme numéro d'enregistrement. Si vous ajoutez des données à un fichier existant, il est nécessaire de connaître le numéro d'enregistrement. Pour ajouter des données à la fin, le numéro de l'enregistrement s'obtient au moyen du calcul suivant
Noenregistrement = LOF(#fichier) \ len(type)
La fonction LOF (Length Of File) donne la longueur du fichier. Le \ représente l'opérateur de division entière, qui donne un entier comme réponse. 4 donne 1
Pour écrire une donnée
Put #numfichier, numéro d'enregistrement, variable d'enregistrement
Pour lire une donnée
Get #numfichier, numéro d'enregistrement, variable d'enregistrement.
La recherche d'un enregistrement existant est un peu plus compliquée. À défaut de connaître le connaître le numéro d'enregistrement, il faut y aller par itérations, pour retrouver le numéro correspondant à la donnée cherchée. Pour faciliter ce type de recherche des esprits brillants ont inventé les fichiers d'indexation. Ces fichiers sont utilisés pour stocker l'emplacement d'une donnée déterminée dans un fichier aléatoire.
L'ACCÈS BINAIRE
Le mode d'accès binaire permet d'écrire, ou de lire octet, par octet. Cela permet donc de modifier directement n'importe quel fichier, Exécutable, base de données, fichier Excel, Word. etc.). Il suffit de savoir à partir de quel octet, et le nombre d'octets qu'il faut lire ou écrire. Si le fait de se
tromper en lecture ne risque pas d,endommager le fichier, il en est tout autrement en écriture. Il suffit de se tromper d'un octet pour foutre en l'air.
Ce mode d'accès binaire, permets également de définir un format de fichier selon ses propres critères. Il faut s'assurer que que la façon dont le fichier est lu est compatible avec la façon dont il est écrit.
Dans ce cas, l'instruction seek, est utilisée pour se déplacer à l'octet où doit débuter la lecture ou l'écrire.
L'instruction Get permet de lire un certains nombre d'octets.
L'instruction Put permet d'écrire dans le fichier.
Contrairement à l'accès séquentiel, l'accès aléatoire permet de travailler simultanément en lecture et écriture sur un fichier ouvert. Le travail avec les fichiers aléatoires repose sur les Types définis par l'utilisateur. Je vous reporte à la structure "Type personnage"
type personnage
nom as string * 40 'Garde 40 caractères pour le nom
age as byte 'Maximun de 256 ans par personne
sexe as string * 8 'Masculin = 8 caractères, Féminin = 7 caractères
end type
dim personnes(10) as personnage 'Établir un tableau de 10 personnes à 3 données par personne
Un type défini par l'utilisateur débute par l'instruction type et se termine par l'instruction End Type. Contrairement aux tableaux traditionnels, qui sont limités à un seul type de données, les types définis par l'utilisateur permettent de regrouper sous une structure unique des types différents de données. C'est ainsi qu'il est possible de traiter ensemble des textes et des nombres.
L'instruction dim, permet de déclarer un tableau contenant 10 ensembles correspondant à personnage.
Pour accéder à un élément particulier du tableau, il suffit de l'appeler en mettant l'indice. Par exemple, pour appeler le nom du premier individu on mettra:
lenom = personnes(1).nom
Pour le sexe de la dixième personne:
lesexe = personnes(10).sexe
Notons, en passant, que le type défini par l'utilisateur peut être utilisé ailleurs qu'avec des fichiers à accès aléatoire.
Pour en revenir à nos fichiers proprement dits, nous pouvons dire, en comparaison avec les fichiers à accès séquentiel, qu'ici la longueur des enregistrements est fixe. Cela signifie donc, que si nous mettons un nom de 20 caractères dans un espace, (certains disent un champ) prévu pour 40 (cela pourrait aussi bien être 60 ou 100, que 10, c'est à la discrétion du programmeur, en fonction des besoins), il y aura obligatoirement 20 blancs d'ajoutés au bout du nom. C'est pour cela qu'il est tout indiqué de les supprimer avec rtrim(), après la lecture du fichier et avant toute
opération. (Sinon, toutes vos comparaisons vont planter et vous risquez d'avoir des problèmes de formatage).
En contrepartie, un nom qui aurait plus de 40 caractères, serait purement et simplement tronqué à partir du 41e caractère. C'est donc dire qu'il faut choisir avec soin la taille maximale des enregistrements. Il faut souvent faire un compromis entre la capacité d'emmagasiner tous les noms possibles et impossibles, et le fait que la taille des fichiers augmente en conséquence.
Contrairement à un fichier à accès séquentiel, on peut accéder directement à une information d'un fichier à accès aléatoire sans lire toutes les données précédentes. Cependant, si vous effacez des données dans un fichier de ce type, il est avantageux de réécrire de nouvelles données à la place des données effacées. Sauf erreur de ma part, VBA ne compacte pas ces fichiers automatiquement. Il faut donc éviter de laisser des blancs inutiles. Vous noterez que c'est pour cela que les systèmes de gestion de bases de données ont un utilitaire de compactage des fichiers de bases de données.
L'ouverture de ce type de fichier passe par l'instruction suivante:
open "fichier" for random as numfichier len = len(type défini par l'utilisateur)
S'il n'y a pas de fichier d'ouvert, le fichier peut prendre n'importe quel numéro choisi par le programmeur. Pour ma part, le premier fichier que j'ouvre prend, je ne sais pas pourquoi, le numéro 1. Comme c'est moi qui décide, je décrète que mon fichier s'appelle Gaston.don .
Donc:
Open "Gaston.don" for random as 1 len = len (personnage)
La longueur s'exprime en octets, calculée principalement sur ces bases.
Pour des textes : 1 octet par caractère, incluant les blancs. donc String * 40 veut dire 40 octets.
Pour des nombres:
Byte : 1 octet
Integer (Entier) : 2 octets
Long (Entier long) : 4 octets
Single (Virgule flottante en simple précision) : 4 octets
Double (Virgule flottante en double précision) : 8 octets
Si vous écrivez un nouveau fichier, vous pouvez utiliser un compteur comme numéro d'enregistrement. Si vous ajoutez des données à un fichier existant, il est nécessaire de connaître le numéro d'enregistrement. Pour ajouter des données à la fin, le numéro de l'enregistrement s'obtient au moyen du calcul suivant
Noenregistrement = LOF(#fichier) \ len(type)
La fonction LOF (Length Of File) donne la longueur du fichier. Le \ représente l'opérateur de division entière, qui donne un entier comme réponse. 4 donne 1
Pour écrire une donnée
Put #numfichier, numéro d'enregistrement, variable d'enregistrement
Pour lire une donnée
Get #numfichier, numéro d'enregistrement, variable d'enregistrement.
La recherche d'un enregistrement existant est un peu plus compliquée. À défaut de connaître le connaître le numéro d'enregistrement, il faut y aller par itérations, pour retrouver le numéro correspondant à la donnée cherchée. Pour faciliter ce type de recherche des esprits brillants ont inventé les fichiers d'indexation. Ces fichiers sont utilisés pour stocker l'emplacement d'une donnée déterminée dans un fichier aléatoire.
L'ACCÈS BINAIRE
Le mode d'accès binaire permet d'écrire, ou de lire octet, par octet. Cela permet donc de modifier directement n'importe quel fichier, Exécutable, base de données, fichier Excel, Word. etc.). Il suffit de savoir à partir de quel octet, et le nombre d'octets qu'il faut lire ou écrire. Si le fait de se
tromper en lecture ne risque pas d,endommager le fichier, il en est tout autrement en écriture. Il suffit de se tromper d'un octet pour foutre en l'air.
Ce mode d'accès binaire, permets également de définir un format de fichier selon ses propres critères. Il faut s'assurer que que la façon dont le fichier est lu est compatible avec la façon dont il est écrit.
Dans ce cas, l'instruction seek, est utilisée pour se déplacer à l'octet où doit débuter la lecture ou l'écrire.
L'instruction Get permet de lire un certains nombre d'octets.
L'instruction Put permet d'écrire dans le fichier.
Clément Marcotte,
Ajouté ou modifié le 09/07/2005 (N°1653)
Ajouté ou modifié le 09/07/2005 (N°1653)
Comment peut-on avec excel lire et/ou écrire des fichiers texte ?
VBA, autorise trois façons d'accéder à un fichier, l'accès séquentiel, l'accès aléatoire et l'accès binaire.
L'accès séquentiel, comme le nom le dit enregistre les informations bout à bout, et donne essentiellement des fichiers texte. L'avantage c'est qu'il est relativement facile à travailler, et d'utilisation plutôt souple. Nous allons voir plus tard que VBA permet de lire le fichier ligne par ligne, ou donnée par donnée. On peut facilement déterminer le format d'enregistrement
et choisir le caractère de délimitation (virgule, point-virgule, tabulation ou même quelque chose d'exotique, en autant que ce soit un caractère qui ne puisse pas être confondu avec des données.
Les principaux inconvénients sont d'une part, que c'est un fichier texte, donc exigeant en espace de stockage, et qui n'a rien de confidentiel. Un fichier texte peut être ouvert avec à peu près n'importe quelle application. Il faut aussi noter que l'on ne peut pas écrire dans un fichier séquentiel ouvert en lecture. L'inverse est aussi vrai.
L'autre inconvénient est lié au fait qu'il n'y a pas moyen d'accéder à une donnée quelconque, sans lire les données précédentes. Si la différence est minime dans le cas de petits fichiers, cela peut devenir très gênant, quand on a besoin de la 50000e donnée, et qu'il faille en lire 49999 pour rien.
On accède à ce type de fichier au moyen de l'une ou l'autre des instructions suivantes:
1) Pour ouvrir en écriture, et écraser un fichier précédent du même nom. (C'est au programmeur de prévoir spécifiquement les gardes-fous qui s'imposent.)
open fichier for output as numfichier
2) Pour ouvrir en écriture, et ajouter des données à un fichier existant:
open fichier for append as numfichier
3) Pour ouvrir un fichier en lecture
open fichier for input as numfichier
Un petit truc pour se rappeler si c'est input ou output. Il faut le voir du point de vue du programme. Le programme lit les données (Input) et écrit les données (output)
Pour écrire des données dans le fichier, le programmeur a le choix entre les instructions Print et Write.
Print #numfichier, les données à sauvegarder
Write #numfichier, les données à sauvegarder.
Print, qui est l'adaptation aux fichiers de l'instruction Print du BASIC original, permet de formater la chaîne de sortie selon ses propres critères, mais exige, en revanche, d'écrire les textes entre guillemets, et d'écrire explicitement le caractère de délimitation.
Par exemple, écrire un nom, l'âge, et le sexe d'un individu avec la virgule comme caractère de délimitation:
Print #1, "Gaston Lagaffe" ; "," ; 69 ; ", " ; "Masculin"
Le point virgule sert à "coller" les données ensemble.
Ou, ici, écrire un nom, l'âge, et le sexe d'un individu avec le point-virgule comme caractère de délimitation:
Print #1, "Gaston Lagaffe" ; ";" ; 69 ; "; " ; "Masculin"
Là, il ne faut pas confondre le point-virgule de l'instruction, et le point-virgule qui sert de délimiteur dans le fichier.
Au lieu de Print, on peut également utiliser Write. Dans ce cas, les chaînes de caractères sont automatiquement afflubées de guillemets, et une virgule sert automatiquement de caractère de délimitation. Cela fait que mon Gaston Lagaffe va devenir:
write #1, "Gaston", "Lagaffe", 69, "Masculin"
Lire un fichier séquentiel
Vous comprendrez vite que l'existence de deux façons d'écrire dans le fichier, oblige à une grande prudence au moment de la lecture du fichier. Rappelons donc que l'instruction pour ouvrir un fichier séquentiel est Open fichier for input as numfichier
Pour lire les données, le programmeur dispose de deux instructions différentes:
Input #numfichier
ou
Line input #numfichier
Si je reprend mon Gaston Lagaffe.
Avec Print
"Gaston Lagaffe" ; ";" ; 69 ; "; " ; "Masculin"
Avec Write:
"Gaston", "Lagaffe", 69, "Masculin"
et que j'écris
Input #1, Nom, âge, sexe
J'obtiens respectivement
Nom:
Gaston Lagaffe (Avec Print)
Gaston (Avec write)
âge:
69 (Avec print)
Lagaffe (Avec write)
sexe
Masculin (Avec print)
69 (Avec write)
Au lieu d'utiliser Input # pour lire les données d'un fichier, il est possible d'utiliser Line Input #.
line input #1 ligne
Dans ce cas, une ligne complètes lue et mise dans la variable ligne. La séparation de la ligne en ses diverses composantes repose uniquement sur les efforts du programmeur. (Si vous avez accès à la fonction Split(), c'est là une chance de l'expérimenter. Sinon c'est le problème de détecter la position des délimiteurs et d'extraire le nombre correspondant de caractères.
Voici quelques petits exemples de routines de gestion de fichiers séquentiels.
'Le Type est une façon de regrouper des données en tableaux. C'est facultatif pour des fichiers à accès séquentiel, mais indispensable pour les fichiers à accès aléatoire.
type personnage
nom as string * 40 'Garde 40 caractères pour le nom
age as byte 'Maximun de 256 ans par personne
sexe as string * 8 'Masculin = 8 caractères, Féminin = 7 caractères
end type
dim personnes(10) as personnage 'Établir un tableau de 10 personnes à 3 données par personne
sub EcrireUnFichiersequentiel()
numero = freefile 'Permets de retrouver le premier numéro libre pour désigner un fichier.
for i = 1 to ubound(personnes)
print #numero, rtrim(personnes(i).nom); ";" personnes(i).age; ";" ;rtrim(personnes(i).sexe personnes(i).sexe
next
close numero
Pour lire un fichier séquentiel.
'Si vous mettez toutes ces procédures dans le même module, vous mettez une fois pour toute le type personnage en haut du module, en dehors de touteprocédure. Si vous mettez vos procédures dans des modules différents, vous devez remettre le Type personnage au début de chaque module.
type personnage
nom as string * 40 'Garde 40 caractères pour le nom
age as byte 'Maximun de 256 ans par personne
sexe as string * 8 'Masculin = 8 caractères, Féminin = 7 caractères
end type
dim personnes(10) as personnage 'Établir un tableau de 10 personnes à 3 données par personne
sub LireUnFichiersequentielavecInput()
numero = freefile 'Permets de retrouver le premier numéro libre pour désigner un fichier.
i = 1
do while not eof(1) 'va boucler tant que l'on aura pas atteint la fin de fichier
input #numero, personnes(i).nom, personnes(i).age,personnes(i).sexe
i = i +1
loop
close numero
sub LireUnFichiersequentielavecLineInput()
numero = freefile 'Permets de retrouver le premier numéro libre pour désigner un fichier.
do while not eof(1) 'va boucler tant que l'on aura pas atteint la fin de fichier
Lineinput #numero, ligne
'Mettre les opérations pour répartir les élements dans des variables
loop
close numero
L'accès séquentiel, comme le nom le dit enregistre les informations bout à bout, et donne essentiellement des fichiers texte. L'avantage c'est qu'il est relativement facile à travailler, et d'utilisation plutôt souple. Nous allons voir plus tard que VBA permet de lire le fichier ligne par ligne, ou donnée par donnée. On peut facilement déterminer le format d'enregistrement
et choisir le caractère de délimitation (virgule, point-virgule, tabulation ou même quelque chose d'exotique, en autant que ce soit un caractère qui ne puisse pas être confondu avec des données.
Les principaux inconvénients sont d'une part, que c'est un fichier texte, donc exigeant en espace de stockage, et qui n'a rien de confidentiel. Un fichier texte peut être ouvert avec à peu près n'importe quelle application. Il faut aussi noter que l'on ne peut pas écrire dans un fichier séquentiel ouvert en lecture. L'inverse est aussi vrai.
L'autre inconvénient est lié au fait qu'il n'y a pas moyen d'accéder à une donnée quelconque, sans lire les données précédentes. Si la différence est minime dans le cas de petits fichiers, cela peut devenir très gênant, quand on a besoin de la 50000e donnée, et qu'il faille en lire 49999 pour rien.
On accède à ce type de fichier au moyen de l'une ou l'autre des instructions suivantes:
1) Pour ouvrir en écriture, et écraser un fichier précédent du même nom. (C'est au programmeur de prévoir spécifiquement les gardes-fous qui s'imposent.)
open fichier for output as numfichier
2) Pour ouvrir en écriture, et ajouter des données à un fichier existant:
open fichier for append as numfichier
3) Pour ouvrir un fichier en lecture
open fichier for input as numfichier
Un petit truc pour se rappeler si c'est input ou output. Il faut le voir du point de vue du programme. Le programme lit les données (Input) et écrit les données (output)
Pour écrire des données dans le fichier, le programmeur a le choix entre les instructions Print et Write.
Print #numfichier, les données à sauvegarder
Write #numfichier, les données à sauvegarder.
Print, qui est l'adaptation aux fichiers de l'instruction Print du BASIC original, permet de formater la chaîne de sortie selon ses propres critères, mais exige, en revanche, d'écrire les textes entre guillemets, et d'écrire explicitement le caractère de délimitation.
Par exemple, écrire un nom, l'âge, et le sexe d'un individu avec la virgule comme caractère de délimitation:
Print #1, "Gaston Lagaffe" ; "," ; 69 ; ", " ; "Masculin"
Le point virgule sert à "coller" les données ensemble.
Ou, ici, écrire un nom, l'âge, et le sexe d'un individu avec le point-virgule comme caractère de délimitation:
Print #1, "Gaston Lagaffe" ; ";" ; 69 ; "; " ; "Masculin"
Là, il ne faut pas confondre le point-virgule de l'instruction, et le point-virgule qui sert de délimiteur dans le fichier.
Au lieu de Print, on peut également utiliser Write. Dans ce cas, les chaînes de caractères sont automatiquement afflubées de guillemets, et une virgule sert automatiquement de caractère de délimitation. Cela fait que mon Gaston Lagaffe va devenir:
write #1, "Gaston", "Lagaffe", 69, "Masculin"
Lire un fichier séquentiel
Vous comprendrez vite que l'existence de deux façons d'écrire dans le fichier, oblige à une grande prudence au moment de la lecture du fichier. Rappelons donc que l'instruction pour ouvrir un fichier séquentiel est Open fichier for input as numfichier
Pour lire les données, le programmeur dispose de deux instructions différentes:
Input #numfichier
ou
Line input #numfichier
Si je reprend mon Gaston Lagaffe.
Avec Print
"Gaston Lagaffe" ; ";" ; 69 ; "; " ; "Masculin"
Avec Write:
"Gaston", "Lagaffe", 69, "Masculin"
et que j'écris
Input #1, Nom, âge, sexe
J'obtiens respectivement
Nom:
Gaston Lagaffe (Avec Print)
Gaston (Avec write)
âge:
69 (Avec print)
Lagaffe (Avec write)
sexe
Masculin (Avec print)
69 (Avec write)
Au lieu d'utiliser Input # pour lire les données d'un fichier, il est possible d'utiliser Line Input #.
line input #1 ligne
Dans ce cas, une ligne complètes lue et mise dans la variable ligne. La séparation de la ligne en ses diverses composantes repose uniquement sur les efforts du programmeur. (Si vous avez accès à la fonction Split(), c'est là une chance de l'expérimenter. Sinon c'est le problème de détecter la position des délimiteurs et d'extraire le nombre correspondant de caractères.
Voici quelques petits exemples de routines de gestion de fichiers séquentiels.
'Le Type est une façon de regrouper des données en tableaux. C'est facultatif pour des fichiers à accès séquentiel, mais indispensable pour les fichiers à accès aléatoire.
type personnage
nom as string * 40 'Garde 40 caractères pour le nom
age as byte 'Maximun de 256 ans par personne
sexe as string * 8 'Masculin = 8 caractères, Féminin = 7 caractères
end type
dim personnes(10) as personnage 'Établir un tableau de 10 personnes à 3 données par personne
sub EcrireUnFichiersequentiel()
numero = freefile 'Permets de retrouver le premier numéro libre pour désigner un fichier.
for i = 1 to ubound(personnes)
print #numero, rtrim(personnes(i).nom); ";" personnes(i).age; ";" ;rtrim(personnes(i).sexe personnes(i).sexe
next
close numero
Pour lire un fichier séquentiel.
'Si vous mettez toutes ces procédures dans le même module, vous mettez une fois pour toute le type personnage en haut du module, en dehors de touteprocédure. Si vous mettez vos procédures dans des modules différents, vous devez remettre le Type personnage au début de chaque module.
type personnage
nom as string * 40 'Garde 40 caractères pour le nom
age as byte 'Maximun de 256 ans par personne
sexe as string * 8 'Masculin = 8 caractères, Féminin = 7 caractères
end type
dim personnes(10) as personnage 'Établir un tableau de 10 personnes à 3 données par personne
sub LireUnFichiersequentielavecInput()
numero = freefile 'Permets de retrouver le premier numéro libre pour désigner un fichier.
i = 1
do while not eof(1) 'va boucler tant que l'on aura pas atteint la fin de fichier
input #numero, personnes(i).nom, personnes(i).age,personnes(i).sexe
i = i +1
loop
close numero
sub LireUnFichiersequentielavecLineInput()
numero = freefile 'Permets de retrouver le premier numéro libre pour désigner un fichier.
do while not eof(1) 'va boucler tant que l'on aura pas atteint la fin de fichier
Lineinput #numero, ligne
'Mettre les opérations pour répartir les élements dans des variables
loop
close numero
Clément Marcotte,
Ajouté ou modifié le 09/07/2005 (N°1652)
Ajouté ou modifié le 09/07/2005 (N°1652)
Je voudrais exporter vers note pad (format text brut donc pour les incorporer dans un éditeur
HTML) des données contenues dans plusieurs cellules excel en colonne. Le copier coller me crée
des guillemets supplémentaires....
Première soluce
Copier dans word pad puis resélectionner et coller dans notepad...
Deuxième soluce, par VBA
Sub Exporttexte()
numfic = FreeFile()
Dim LeTexte As String
Dim lignelue As Integer
'=======================================================
'Contrairement à l'instruction Print #,
'l'instruction Write # insère des virgules entre les éléments
'et des guillemets doubles de part et d'autre des chaînes de caractères
'au moment de leur écriture dans le fichier.
'L'instruction Write # insère un caractère de passage à la ligne,
'c'est-à-dire un retour chariot-saut de ligne (Chr(13) + Chr(10)),
'après l'écriture dans le fichier du dernier caractère '
'contenu dans l'argument outputlist.
'=======================================================
'*****
' CONCLUSION : il ne faut pas utiliser l'instruction WRITE #
' voir également la rubrique d'aide concernant PRINT # (probleme pour relecture !)
'=======================================================
Open "temporaire.htm" For Output As #numfic
With ActiveSheet
lignelue = 1
While Not IsEmpty(.Cells(lignelue, 1))
LeTexte = ActiveSheet.Cells(lignelue, 1).Value
Print #numfic, LeTexte
lignelue = lignelue + 1
Wend
Close #numfic ' Ferme le fichier.
End With
End Sub
Copier dans word pad puis resélectionner et coller dans notepad...
Deuxième soluce, par VBA
Sub Exporttexte()
numfic = FreeFile()
Dim LeTexte As String
Dim lignelue As Integer
'=======================================================
'Contrairement à l'instruction Print #,
'l'instruction Write # insère des virgules entre les éléments
'et des guillemets doubles de part et d'autre des chaînes de caractères
'au moment de leur écriture dans le fichier.
'L'instruction Write # insère un caractère de passage à la ligne,
'c'est-à-dire un retour chariot-saut de ligne (Chr(13) + Chr(10)),
'après l'écriture dans le fichier du dernier caractère '
'contenu dans l'argument outputlist.
'=======================================================
'*****
' CONCLUSION : il ne faut pas utiliser l'instruction WRITE #
' voir également la rubrique d'aide concernant PRINT # (probleme pour relecture !)
'=======================================================
Open "temporaire.htm" For Output As #numfic
With ActiveSheet
lignelue = 1
While Not IsEmpty(.Cells(lignelue, 1))
LeTexte = ActiveSheet.Cells(lignelue, 1).Value
Print #numfic, LeTexte
lignelue = lignelue + 1
Wend
Close #numfic ' Ferme le fichier.
End With
End Sub
Laurent Mortézai, GeeDee, (N°1294)
Comment écrire par VBA directement une page HTML à partir de données contenues dans un
classeur. Je ne veux pas enregistrer tout le classeur en HTML, seule une partie des données
doit être exportée.
voici le principe pour éditer une page avec ton éditeur html préféré
Sub html()
Dim plage As Range
Dim cell As Range
Set plage = Range("A1:C6")
'identifiant fichier en A:A
' éléments en B:B Etc...
For Each cell In plage
Open cell.Value & ".html" For Output As #1
Print #1, ""
Print #1, 'ici tu recopies ensuite ligne par ligne les balises head, /head, script, body...
Le contenu de chaque ligne doit être écrit entre guillemets et précédé de Print #1.
(NB le disciplus ne peux pas écrire cela ici, ca fausse l'affichage de cette page !
il a mis quelques lurettes à trouver d'où venait l'erreur !)
Print #1, ""
Print #1, "blabla " & cell.Offset(0, 1) & " "
Print #1, "blabla " & cell.Offset(0, 2) & " "
Print #1, " "
Close #1
Next cell
End Sub
Sub html()
Dim plage As Range
Dim cell As Range
Set plage = Range("A1:C6")
'identifiant fichier en A:A
' éléments en B:B Etc...
For Each cell In plage
Open cell.Value & ".html" For Output As #1
Print #1, ""
Print #1, 'ici tu recopies ensuite ligne par ligne les balises head, /head, script, body...
Le contenu de chaque ligne doit être écrit entre guillemets et précédé de Print #1.
(NB le disciplus ne peux pas écrire cela ici, ca fausse l'affichage de cette page !
il a mis quelques lurettes à trouver d'où venait l'erreur !)
Print #1, ""
Print #1, "blabla " & cell.Offset(0, 1) & " "
Print #1, "blabla " & cell.Offset(0, 2) & " "
Print #1, " "
Close #1
Next cell
End Sub
Pascal, (N°1293)

Comment exporter un fichier excel au format .txt avec la vigule comme séparateur ?
Cette macro fonctionne aussi bien pour mac que pour PC
Sub ExportAvecSeparateurVirgule()
Dim NbLignes As Integer, NbCol As Integer, i As Integer
Dim j As Integer, S As String
' Détermination du nombre de lignes dans le fichier
' en négligeant les éventuels problèmes liés à
' l'emplacement de la dernière cellule.
NbLignes = Selection.SpecialCells(xlCellTypeLastCell).Row
' Création d'un "canal" vers le fichier texte
Open "Export " & ActiveSheet.Name & ".xls" For Output As #1
For i = 1 To NbLignes
' Détermination du nombre de colonnes utiles sur la ligne
NbCol = Cells(i, 1).EntireColumn.Find("*", , , , ,xlPrevious).Row
For j = 1 To NbCol
S = S & "," & Cells(i, j)
Next j
' Suppression de la première virgule, et ajout au fichier texte.
Print #1, Right(S, Len(S) - 1)
' MsgBox S
S = ""
Next i
' Fermeture du "canal"
Close #1
End Sub
Sub ExportAvecSeparateurVirgule()
Dim NbLignes As Integer, NbCol As Integer, i As Integer
Dim j As Integer, S As String
' Détermination du nombre de lignes dans le fichier
' en négligeant les éventuels problèmes liés à
' l'emplacement de la dernière cellule.
NbLignes = Selection.SpecialCells(xlCellTypeLastCell).Row
' Création d'un "canal" vers le fichier texte
Open "Export " & ActiveSheet.Name & ".xls" For Output As #1
For i = 1 To NbLignes
' Détermination du nombre de colonnes utiles sur la ligne
NbCol = Cells(i, 1).EntireColumn.Find("*", , , , ,xlPrevious).Row
For j = 1 To NbCol
S = S & "," & Cells(i, j)
Next j
' Suppression de la première virgule, et ajout au fichier texte.
Print #1, Right(S, Len(S) - 1)
' MsgBox S
S = ""
Next i
' Fermeture du "canal"
Close #1
End Sub
Michel Gaboly, (N°1292)
J'importe des données depuis une autre application mais il doit me rester des signes invisibles
qui m'ennuient. Comment les éliminer ?
Utilisez la fonction EPURAGE qui supprime tous les caractères de contrôle du texte.
Utilisez EPURAGE pour du texte importé d'autres applications contenant des caractères
qui ne pourront peut-être pas être imprimés sous votre système d'exploitation.
Par exemple, la fonction EPURAGE vous permet de supprimer certains codes de bas niveau
généralement placés par le système au début et à la fin des fichiers de données, et qui ne
peuvent pas être imprimés.
Utilisez EPURAGE pour du texte importé d'autres applications contenant des caractères
qui ne pourront peut-être pas être imprimés sous votre système d'exploitation.
Par exemple, la fonction EPURAGE vous permet de supprimer certains codes de bas niveau
généralement placés par le système au début et à la fin des fichiers de données, et qui ne
peuvent pas être imprimés.
Isabelle, (N°1291)
J'importe des fichiers dans Excel, mais dans certains champs je récupère aussi des " ' "
en début de cellule. Le remplacer par est inefficace
Si tu as une de ces données en A1 et que tu mets ailleurs =CODE(A1), tu devrais récupérer
la
valeur 39. Si ce n'est pas le cas c'est que ton programme ajoute un caractère parasite.
Une
solution: sélectionne toute la feuille, Edition/Effacer/formats.
la
valeur 39. Si ce n'est pas le cas c'est que ton programme ajoute un caractère parasite.
Une
solution: sélectionne toute la feuille, Edition/Effacer/formats.
Laurent Mortézai,
Ajouté ou modifié le 25/10/2003 (N°1290)
Ajouté ou modifié le 25/10/2003 (N°1290)