Problème récupération info dans fichier textes

[Résolu]
Signaler
Messages postés
118
Date d'inscription
lundi 6 novembre 2000
Statut
Membre
Dernière intervention
12 mai 2010
-
Messages postés
118
Date d'inscription
lundi 6 novembre 2000
Statut
Membre
Dernière intervention
12 mai 2010
-
Bonsoir à tous,

Dans le cadre de la création d'un logiciel de supervision au seins de mon entreprise, je suis confronté au problème suivant :

J'utilise l'utilitaire WMIC afin de récupérer des informations sur les disques durs et lecteurs DAT.
Cet utilitaire me génère un fichier texte, alimenté de toutes les données. la première ligne indique le nom des colonnes, et les informations suivent sur les lignes suivants, colonnes par colonnes.
Tout d'abord j'ai pensé récupérer toutes ces informations par rapport à leurs position, mais le problème est que lorsque j'interroge des serveurs ayant par exemple un disque ou lecteur de marque différente, les colonnes sont agrandies.
Résultat : les informations que je récupère sont fausses car il y a un décalage.
Ma question est donc : Comment puis-je faire pour à coup sur récupérer les bonnes informations même si les colonnes n'ont pas la même taille d'un fichier à l'autre ?
Car à la base j'avais pensé créé un type, mais le problème d'un type est qu'il faut déclarer la longueur champs.
J'ai ensuite penser à splitter tout les espace pour récupérer les valeurs dans un tableau, mais le problème est que je peux avoir plusieurs dizaines d'espaces si le nom de la colonne est long.
Donc soit j'enlève un espace a chaque fois, et il en reste une multitude d'autres, soit je les supprimes tous, et la ma chaine de caractère est complètement collée donc inexploitable.
Existe-t-il un moyen de récupérer toutes ces infos dans un tableau même si la longeur des colonnes est variable ?
Ou bien j'ai pensé à copier le contenu du fichier texte dans un fichier excel, pour récupérer les meme colonnes partout, mais mon problème est le même, so I need Help please !!!
Merci
Cordialement,

Paul

6 réponses

Messages postés
22
Date d'inscription
mardi 23 janvier 2007
Statut
Membre
Dernière intervention
31 mars 2010

Bonjour,

La position et la longueur des colonnes est effectivement variable en fonction des valeurs contenues dans chaque fichier. Par contre, ce qui est intéressant, c'est que les libellés des entêtes ne contiennent pas d'espace et que les colonnes sont bien alignées à gauche.

entete1 entete2 entete3
x yyyyy yyyy zzz

Voici donc un exemple de code (certainement optimisable) qui devrait fonctionner (je l'ai notamment testé sur le résultat de la commande wmic /OUTPUT:<nomfichier> DISKDRIVE et le résultat m'a semblé correct)
Pour que cela fonctionne, il faut rajouter dans le projet VBA une référence à la bibliothèque Microsoft Scripting Runtime.


Sub RecupInfosFichierWMIC(strNomFichier As String)
Dim objFSO As FileSystemObject
Dim objTxtStream As TextStream
Dim strFic As String
Dim strLignes() As String, Colonnes() As String
Dim nbColonnes As Integer
Dim PositionColonnes() As Integer, Position As Integer
Dim LongueurColonnes() As Integer, LngColonne As Integer
Dim iLigne As Integer, iColonne As Integer
Dim strValeur As String

'Ouverture du fichier et récupération des lignes '
'(fichier créé par une commande du type WMIC /OUTPUT:strNomFichier )
Set objFSO = New FileSystemObject
Set objTxtStream = objFSO.OpenTextFile(Filename:=strNomFichier, _
Format:=TristateUseDefault)
strFic = objTxtStream.ReadAll
objTxtStream.Close
Set objFSO = Nothing
strLignes = Split(strFic, vbCrLf)

'Détermination de la postion de début de chaque colonne
'heureusement, le libellé d'une colonne ne contient pas d'espace
Colonnes = Split(strLignes(0), Chr(32))
'Le problème c'est que les entêtes de Colonnes sont séparés par un nombre variable
'd'espaces (fonction de la longueur des valeurs)
Position = 1
nbColonnes = 0
ReDim PositionColonnes(0)
For iColonne = 0 To UBound(Colonnes)
LngColonne = Len(Colonnes(iColonne))
If LngColonne = 0 Then ' C'était un espace
Position = Position + 1
Else 'C'est un libellé de colonne
ReDim Preserve PositionColonnes(nbColonnes)
PositionColonnes(nbColonnes) = Position
nbColonnes = nbColonnes + 1
Position = Position + LngColonne + 1
End If
Next
nbColonnes = UBound(PositionColonnes)

'Détermination de la longueur de chaque colonne
ReDim LongueurColonnes(nbColonnes)
For iColonne = 0 To nbColonnes - 1
LongueurColonnes(iColonne) = PositionColonnes(iColonne + 1) _
- PositionColonnes(iColonne)
Next
LongueurColonnes(nbColonnes) = Len(strLignes(0)) - PositionColonnes(nbColonnes)

'On a maintenant la position et la longueur de chaque champ
For iLigne = 0 To UBound(strLignes)
For iColonne = 0 To nbColonnes
strValeur = Trim(Mid$(strLignes(iLigne), PositionColonnes(iColonne), _
LongueurColonnes(iColonne)))
ActiveSheet.Cells(iLigne + 1, iColonne + 1).Value = strValeur
Next
Next
End Sub
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
80
Salut
Pourrais-tu donner un exemple de la ligne d'entête et d'une ligne de données ?
-1- Es-tu sûr que les espaces entre colonnes soient vien des espaces ?
Se pourrait-il que, selon l'outil avec lequel tu affiche ce fichier texte, il remplace de lui-même des caractères 'non-imprimables' en espace ?
Cela peut arriver avec WordPad, par exemple.
--> Envoie ton fichier texte dans un éditeur hexadécimal comme "Hackman" et vérifie que le caractère qui précède la première lettre d'une colonne est un espace = Ascii 32 ou 20 hexa

-2- Est-ce que la largeur des colonnes est aussi respectée dans la ligne des noms de colonnes ?
Exemple
Colonne 1       Colonne 2    Colonne 3
Donnée 1        Donnée 2     Donnée 3
c'est à dire, est-ce que les emplacements des premières lettres des noms de colonnes coincide avec les premières lettres des données des lignes suivantes

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
118
Date d'inscription
lundi 6 novembre 2000
Statut
Membre
Dernière intervention
12 mai 2010

Merci beaucoup pour ta réponse.
Je vais vérifier pour s'il s'agit de caractères 'non imprimable' mais à priori non, je ne pense pas car les espaces sont la pour monter qu'il y a une colonne mais qu'elle est vide, ou bien c'est pour séparer les colonnes, ou lorsque le contenu de la colonne est plus petit que la donnée qui l'alimente.
Par contre oui, les emplacements des premières lettres des noms de colonnes coïncident avec les premières lettres des données des lignes suivantes.

Voici un exemple du fichier texte :

Availability  Capabilities  CapabilityDescriptions  Caption                             
3                 {2, 7}                                             Dell (tm) PowerVault (tm) 100T DAT72

Mon souci est qu'il y a encore des colonnes à droite des celles-ci, au moins une vingtaine.
Et lorsque par exemple le nom du lecteur dans la colonne caption est différent de celui-ci, toutes mes autres données sont décalées et je ne peux donc pas récupérer les infos par rapports aux positions...
Je chercher désespérément !!!
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
80
Re
Pas eu le courage de tout lire (pressé)

Si la 1ere ligne donnant le nom des colonnes est au même endroit que les données, alors il te faut détecter la position du premier caractère de chaque colonne pour en connaitre la largeur.
Il faudra surement supprimer un (ou deux) espace car il doit y avoir une séparation naturelle entre les colonnes.

Ce que je ferai :
- un tableau avec les noms de colonnes + un Split pour les récupérer
   Dim sTemp As String
   Dim NomColonne() As String
   sTemp = maLigne
   Do While Instr(sTemp, "  ")   ' 2 espaces
      sTemp = Replace(sTemp, "  ", " ") ' Remplace 2 spaces par un seul
   Loop
   NomColonne = Split(sTemp, " ")
- un autre tableau avec les longueurs, sachant que son index se réfère à celui du 1er tableau
   Dim Largeur() As Long
   Redim Largeur(0 To UBound(NomColonne))
- une méthode d'analyse :
   Un boucle pour rechercher dans la ligne à quel emplacement on trouve les lettres qui suivent un espace
   Dim DernierChar As String
   Dim DernierPos As Long
   Dim monIndex As Integer
   DernierChar = " "   ' espace
   DernierPos = 0
   monIndex = 0
   For r = 1 To Len(maLigne)
      sTemp = Mid$(maLigne, r, 1)
      If sTemp <> " " Then
         If DernierChar = " " Then
            ' NomColonne commence
            If DernierPos <> 0 Then
               Largeur(monIndex) = r - DernierPos - 1
               monIndex = monIndex + 1
            End If
            DernierPos = r
         End If
      End If
      DernierChar = sTemp
   Next r
   Largeur(monIndex) = r - DernierPos - 1
   
A retravailler, surement
A partir de là, le découpage à la lecture des champs dans les lignes suivantes doit reposer sur le contenu de Largeur()

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
118
Date d'inscription
lundi 6 novembre 2000
Statut
Membre
Dernière intervention
12 mai 2010

Un énorme merci à vous deux, je vais tester ces deux solutions dès ce soir et vous ferai parvenir mes résultats demain.
Encore un grand merci à vous deux

Paul
Messages postés
118
Date d'inscription
lundi 6 novembre 2000
Statut
Membre
Dernière intervention
12 mai 2010

R1r2, un grand merci pour ton code, il fonctionne à merveille, et j'ai pu réussir à le comprendre. C'est vraiment super sympa de ta part, je te remercie vraiment beaucoup.

Merci également à Jack, qui m'a permis de comprendre le principe de fonctionnement, l'algo de ce que je voulais représenter.

Vraiment merci, les membres de ce site sont toujours aussi efficace !!!

Cordialement,

Paul
[auteur/R1R2/962925.aspx ]