Manipulation de fichier - recherche d'une chaine

[Résolu]
Signaler
Messages postés
9
Date d'inscription
mercredi 14 mai 2003
Statut
Membre
Dernière intervention
8 mai 2011
-
Messages postés
9
Date d'inscription
mercredi 14 mai 2003
Statut
Membre
Dernière intervention
8 mai 2011
-
Bonjour à tous
je suis assez maniaque avec mes photos et la façon de les nommer, de les ranger.
J'aime bien qu'elle porte les dates et heures de la prise de vue. De nombreux logiciels proposent de récupérer les dates qui sont en attributs du fichiers (date de création, date de dernière modificaiton, de dernier accès) mais celles-ci sont souvent écrasées par les logiciels utilisés pour décharger l'appareil photo ou pivoter ou renommer.


Du coup, j'ai une macro qui me permet d'ouvrir un répertoire en listant les .jpg
d'ouvrir les fichiers JPG et de rechercher "2006" par exemple dans les 1ères lignes du JPG.


ça marche environ 1 fois sur 2, pour des photos prises pourtant avec le même appareil ... je ne comprends pas pourquoi car, en ouvrant les JPG avant un éditeur de texte, j'arrive bien à trouver 2006 dedans ...


pouvez vous m'aidez svp ??  j'utilise Excel 2002 et VB 6.3


je peux vous envoyer par mail une photo pour laquelle ça marche et une pour laquelle ça ne marche pas.




Voici mon code : pour chaque fichier jpg de mon répertoire, j'appelle la fonction recherche_dateheure_1_fichier, en lui passant en paramètre le nom complet du fichier :





Function recherche_dateheure_1_fichier(path_fichier)
   
    Dim FSO As Object
    Dim i As Integer
   
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Dim File As Object
    Set File = FSO.OpenTextFile(path_fichier, 1, False)
    Dim TEMP_Line As String
    Dim strdate As String
    Dim idc_date_ok As Boolean
    idc_date_ok = False
    i = 1
     'And i < 30
     Do While (Not File.AtEndOfStream And idc_date_ok <> True)
        TEMP_Line = File.ReadLine
        'MsgBox TEMP_Line
        If InStr(1, TEMP_Line, "2006", vbTextCompare) Then
             TestPos = InStr(1, TEMP_Line, "2006", vbBinaryCompare)
            'MsgBox "date trouvée ligne n° " & i & " à la position : " & TestPos
            strdate = Mid(TEMP_Line, TestPos, 19)
            'MsgBox strdate
            recherche_dateheure_1_fichier = strdate
            idc_date_ok = True
        End If
       
        i = i + 1
      Loop
     
      File.Close



End Function




merci d'avance pour votre aide !

12 réponses

Messages postés
1812
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
26 octobre 2010
1
Violent Ken
Bonjour, alors :

- la solution (chercher dans le header) est peut être
"fonctionnelle" mais en tout cas pas propre du tout...

- si moi j'avais eu à checker un header, alors j'aurais utilisé ceci (parce que j'aime pas FSO) :

DANS UN MODULE

Option Explicit

'paramètres pour l'API CreateFile
Public Const FILE_READ_ACCESS                   As Long = &H1
Public Const FILE_BEGIN                         As Long = 0&
Public Const FILE_SHARE_READ                    As Long = &H1
Public Const FILE_SHARE_WRITE                   As Long = &H2
Public Const CREATE_NEW                         As Long = 1&
Public Const OPEN_EXISTING                      As Long = 3&
Public Const GENERIC_WRITE                      As Long = &H40000000
Public Const GENERIC_READ                       As Long = &H80000000
Public Const CREATE_ALWAYS                      As Long = 2&
Public Const FILE_END                           As Long = 2&
Public Const TRUNCATE_EXISTING                  As Long = 5&
Public Const FILE_FLAG_WRITE_THROUGH            As Long = &H80000000
Public Const FILE_FLAG_NO_BUFFERING             As Long = &H20000000

Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Public Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Any) As Long
Public Declare Function SetFilePointerEx Lib "kernel32" (ByVal hFile As Long, ByVal liDistanceToMove As Currency, ByRef lpNewFilePointer As Currency, ByVal dwMoveMethod As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

'-------------------------------------------------------
'récupérer des bytes dans un fichier
'-------------------------------------------------------
Public Function GetBytesFromFile(ByVal sFile As String, ByVal curSize As Currency, ByVal curOffset As Currency) As String
Dim tmpText As String
Dim Ret As Long
Dim lFile As Long
   
   'obtient un handle vers le fichier à ouvrir
   lFile = CreateFile(sFile, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_EXISTING, 0, 0)
   
   If lFile = -1 Then
       'fichier inexistant, ou en tout cas inaccessible
       Exit Function
   End If
       
   'créé un buffer qui contiendra les valeurs
   tmpText = String$(curSize, 0)

   'bouge le pointeur sur lr fichier au bon emplacement
   Ret = SetFilePointerEx(lFile, curOffset / 10000, 0&, FILE_BEGIN)  'divise par 10000 pour
   'pouvoir renvoyer une currency DECIMALE (cad du genre 1.4567 pour l'offset 14567)
   
   'prend un morceau du fichier
   Ret = ReadFile(lFile, ByVal tmpText, Len(tmpText), Ret, ByVal 0&)
   
   'affecte à la fonction
   GetBytesFromFile = tmpText
   
ErrGestion:

   'referme le handle
   CloseHandle lFile
   
End Function
[code.aspx?ID=41455 By Renfield]

DANS UNE FORM

Option Explicit

Const BUF_SIZE = 255

Private Sub Command1_Click()
   If InStr(1, GetBytesFromFile("C:\MON FICHIER", BUF_SIZE, 0), "2006") Then
       'alors 2006 dans le header
       MsgBox "trouvé"
   End If
End Sub
[code.aspx?ID=41455 By Renfield]

Bon, tout çà c'est du VB6, mais çà devrait pouvoir se convertir sans problèmes en VBA.

Mais je répète que c'est pas propre du tout.
@+
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
26
"...je suis assez maniaque avec mes photos et la façon de les nommer, de les ranger...."

Tu as raison d'être un maniaque du rangement (il n'y a que comme celà qu'on sen sort convenablement, c'est sur)...

C'est d'ailleurs la raison pour laquelle il existe, sur ce forum également, des rangements...

On y met entres autres ce qui concerne VBA dans le sous-forum VBA et ce qui concerne VB dans le sous-forum VB.

Je vois que tu parles de macro...

As-tu, selon toi, respecté le rangement des autres ?
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
14
Salut Nanou29,

Je pense(avis personnel) que tu pars sur quelque chose de "pas" pratique...
'ai pas compris comment on fait pour sortir une date de celui-ci...je pense que je vais pas tarder à apprendre quelque chose!!lol), tu récupères les attributs de ton fichier :

Date de création
Date de Modification
Date du dernier accés
.....
.....

Ensuite tu peux faire toute les manipes que tu souhaites ?

Ce serai peut-être plus facile à gérer.....

Salut Jmfmarques

A+
Exploreur
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
41
Je suis d'accord avec toi Jacques. mais moi je m'arrete la-dessus : "...j'utilise Excel 2002 et VB 6.3..."

Ce terme de VB6.3 peut effectivement induire en erreur les novices. Tout le monde ne sait pas forcément que VB6.3 est en réalité appelé VBA. Et ce n'est nullement une version suppérieure de VB6 mais au contraire une version allégée adaptée aux applications Office.

Et que dire de l'IDE que ne reprend même pas le terma VBA mais celui de VBE.

Je conclurais donc que comme pour tut rangement bien organisé, on est tout de même pas à l'abris d'une erreur de rangement parfois

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
14
Oulalal...Je ne sais pas ce qui c'est passé dans mon post précédent, mais il manque des lignes!!!


Je voulais dire :
Pourquoi ne pas utiliser les attributs de ton fichiers jpg :
Date de création
Date de Modification
Date du dernier accés

Ainsi tu ne fait qu'une seule opération sur ton fichier, tu récupères la date de création, et tu ranges ou tu veux, non? Une idée parmi tant d'autres..

A+
Exploreur
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
41
Explorer > le but ici est de retrouver dans le header du fichier, la date de prise devue de l'image, et non pas dans les attributs des fichiers, la date de creation du fichier, information qui est loin d'étre fiable car aisément manipulable.

La date de prise de vue faisant partie du fichier est légèrement plus fiable, à moins de faire une edition du header du fichier.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
14
Salut Casy,


C'est bien ce que je disait : J'ai appris quelque chose que je ne savais pas....


Salutations.


Exploreur
Messages postés
9
Date d'inscription
mercredi 14 mai 2003
Statut
Membre
Dernière intervention
8 mai 2011

Effectivement, je ne savais pas que VB6.3 était en fait VBA ... désolée donc pour la faute de rangement !

Sinon, comme l'a très bien compris Casi, je cherche à lire l'entête du fichier JPG car les dates de création et autres attributs du fichier sont souvent mises à jour par les logiciels de traitement d'images et ne reflètent donc pas à tous les coups la date / heure de prise de vue de la photo.

est-ce que quelqu'un accepterait que je lui envoie le header de 2 photos (un avec lequel ça marche, l'autre pas) par exemple ?
Messages postés
3140
Date d'inscription
vendredi 14 mai 2004
Statut
Membre
Dernière intervention
11 mars 2019
31
ou peut-être en récupérant les propriétés de fichiers
    date du cliché --> 25
ou date originale --> 31

    Dim objShell    As Object
    Dim objFolder   As Object
    Dim strFileName As Object
   
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.Namespace(0)
    Set strFileName = objFolder.ParseName("C:\TEMP\GIFS\TFR101.gif")

    MsgBox objFolder.GetDetailsOf(strFileName, 25)   '25 ou 31
   
    Set strFileName = Nothing
    Set objFolder = Nothing
    Set objShell = Nothing

Daniel
Messages postés
9
Date d'inscription
mercredi 14 mai 2003
Statut
Membre
Dernière intervention
8 mai 2011

Merci beaucoup Violent Ken ! ta solution est super ! j'ai juste dû augmenter
Const BUF_SIZE = 500
Par contre, quand tu dis "la solution (chercher dans le header) est peut être "fonctionnelle" mais en tout cas pas propre du tout..." : quelle autre solution s'offre à moi ???

merci aussi à Daniel : je ne connaissais pas les autres attributs du fichier ... et même si dans mes photos, les dates 25 et 31 sont vides, je retiens tout ça pour une prochaine fois.
Messages postés
1812
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
26 octobre 2010
1
Violent Ken

Salut, alors content que çà marche ;)

Attention tout de même : le header du fichier peut très bien contenir "2006" sans que cela réfère à la date de prise de la photo... (çà peut par exemple etre une partie du nom de l'appareil photo ou du logiciel de retouche).

L'autre solution, c'est beaucoup plus propre (c'est ainsi que procèdent Windows et les logiciels de photos professionnels), c'est çà : http://fr.wikipedia.org/wiki/Exchangeable_image_file_format
http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html (anglais)

Pour les sources en VB qui traitent de çà : http://www.vbfrance.com/codes/LIRE-ECRIRE-METADONNEES-EXIF-IPTC-PNG-GIF-FORMAT_38909.aspx
http://www.vbfrance.com/codes/LIRE-ECRIRE-MOTS-IPTC-EXIF-DANS-IMAGES-JPG_17653.aspx

Beaucoup mieux à tous les niveaux, mais beaucoup plus dur à mettre en place. Après, tu peux très bien reprendre ce qui a déjà été fait directement dans ton programme (en particulier la première source vbfrance citée).

Après, pour adapter en VBA, c'est sans doutes faisable facilement, mais je ne sais pas puisque je ne code pas en VBA ^^

@+
Messages postés
9
Date d'inscription
mercredi 14 mai 2003
Statut
Membre
Dernière intervention
8 mai 2011

Et bien, merci de nouveau pour ces infos ... là, je fais une pause dans la programmation mais je regarderai tout ça de plus près rapidement ! j'ai déjà pris les sources !
merci au forum !