Pb conversion VBA vers VB.net

Sebcode Messages postés 11 Date d'inscription vendredi 15 juillet 2011 Statut Membre Dernière intervention 17 juillet 2014 - 25 juil. 2011 à 20:13
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 - 28 juil. 2011 à 21:04
Bonjour à tous,

Je "débute" en programmation et j'ai actuellement un petit soucis de conversion vba->vb.net.

J'ai créé une macro vba (à l'aide de bouts de codes trouvés ici, merci à vous) et qui me permet de lire en continue un fichier txt, et de me prévenir par mail lorsque qu'un mot (définie par l'utilisateur) est enregistré dans ce fichier par un autre logiciel.

Deux problemes se posent lors du portage en vb.net:

-La boucle "Do while" qui bouffe des ressources comme pas permis...
-Le fait qu'il est impossible à un logiciel tier d'enregistrer dans le txt tant qu'il est lu.

j'utilise visual basic 2010 express et pour info, la macro vba marche très bien.

Voila, je soumet mon code à vos lumières, puissent elles m'éclairer... :

Imports System.IO

Public Class Form1

Dim Arret As Boolean
Dim tmp As String 'variable pour stocker chaque ligne du fichier
Dim mot As String 'variable pour stocker le mot à rechercher
Dim place1 As String 'variable pour socker l'emplacement du fichier
Dim scan As StreamReader 'variable de lecture fichier
Dim strLine As String 'variable de lecture fichier
Dim objMessage As Object



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


ListBox1.Items.Clear()

mot = TextBox1.Text 'stock le mot à rechercher dans la variable
place1 = TextBox2.Text 'stock le chemin du fichier


If TextBox1.Text = "" Then 's'assure qu'il y a bien un mot à chercher
MsgBox("Il n'y a rien à chercher!")


ElseIf place1 = "" Then 's'assure qu'il y a bien un emplacement pour le mot a rechercher
MsgBox("Aucun fichier n'a été sélectionné")

Else 'si tous est ok on continue


Arret = False

Do While Arret = False



Call recherche()

'System.Windows.Forms.Application.DoEvents()
'ou
Application.DoEvents()

Loop

End If 'End if de test textbox vide

MsgBox("Fin")

End Sub

'Sub de gestion envois email

Sub email()
Dim messageHTML
On Error GoTo errorHandler

objMessage = CreateObject("CDO.Message")
objMessage.Subject = "Alerte ScanFile: " & mot
objMessage.From = "adressmail" 'adresse mail de l'expéditeur n'est pas obligatoire
objMessage.To = "adressmail" 'Email du destinataire doit-être correct ici
objMessage.TextBody = "Bonjour," & vbCrLf & vbCrLf & "Le mot " & mot & " a été trouvé dans le fichier ci-joint." & vbCrLf & vbCrLf & "Cordialement,"

messageHTML = "Ceci est un message en HTML"

objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "serveur SMTP"
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Update()

objMessage.AddAttachment(place1) 'On ajoute la piéce jointe

objMessage.Send()

MsgBox("Le fichier contient " & mot & vbCrLf & vbCrLf & "Un mail d'alerte a été envoyé!")

'si erreur on sort de la procédure
Exit Sub
errorHandler:

'description de l'erreur survenue
MsgBox(Err.Description)

End Sub


Private Sub recherche()
ListBox1.Items.Clear()


scan = New StreamReader(place1) 'Pass the file path and the file name to the StreamReader constructor.

strLine = scan.ReadLine 'Lire la 1ere ligne du fichier et la stocker dans "strline"

Do While Not strLine Is Nothing 'Continue la lecture tant que "strline" n'est pas vide donc que l'on n'a pas atteint la fin du fichier.


If ((InStr(strLine, mot)) > 0) Then 'on vérifie si le mot recherché est dans la ligne


ListBox1.Items.Add(strLine) 'on ajoute la ligne dans la listbox

Call email()

Arret = True

Else

ListBox1.Items.Add(strLine) 'on ajoute la ligne dans la listbox

End If 'End if à l'interieur de la boucle "DO LOOP"


strLine = scan.ReadLine 'lit la ligne suivante.

Loop

scan.Close() 'ferme le fichier

End Sub

'Sub de commande arret boucle

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Arret = True
End Sub


End Class

7 réponses

cs_bendidon Messages postés 1 Date d'inscription lundi 22 novembre 2010 Statut Membre Dernière intervention 25 juillet 2011
25 juil. 2011 à 20:47
Bonjour,

Il est certain que lire systématiquement en boucle de cette manière, boucle assortie de DoEvents et boucle qui ne s'arrêtera pas tant que le mot n'a pas été trouvé, ton processeur va chauffer !
Utilise donc un timer pour lancer de temps à autre ta fonction recherche.
Personnellement, je ne relancerais par ailleurs cette fonction que si la taille du fichier texte a été modifiée depuis la lecture précédente.
J'ignore quel était le code écrit sous VBA, mais il devait lui aussi générer les mêmes problèmes s'il lançait en boucle similaire et sans "timer" (ou son équivalent OnTime) la même fonction de recherche !
0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
25 juil. 2011 à 20:47
Bonjour,

On commence par mettre au clair le code :
- Quand tu postes un code, utilises la coloration syntaxique (3ième icône à droite )
- Actives Option Strict et Option Explicit et corriges les erreurs.

Améliorations de code :
Call recherche()
Pas besoin du Call

Do While Arret = False
Peut se remplacer par
Do Until Arret


Sinon, il est normal que ton programme prenne un peu de RAM, car les objets inutilisés sont parqués pour être supprimés, mais ne seront supprimés qu'àprès passage du GC (GarbageCollector), donc quand le programme se repose.

Sinon, pour le point 2, j'attendrais que ton code soit plus clair pour chercher.

Mon site
0
Sebcode Messages postés 11 Date d'inscription vendredi 15 juillet 2011 Statut Membre Dernière intervention 17 juillet 2014
25 juil. 2011 à 22:37
Merci pour vos réponses.
Je vais essayer la solution de Bendidon d'utiliser un timer et de relire le fichier uniquement si il a été modifier (taille ou date de derniere modif).
Du coup ça devrait résoudre les 2 pb d'un coup.

@NHenry: c'est mon 1er post sur le forum, et je ne savais pas comment colorer le texte.
Merci de ton aide
0
Sebcode Messages postés 11 Date d'inscription vendredi 15 juillet 2011 Statut Membre Dernière intervention 17 juillet 2014
25 juil. 2011 à 22:38
Imports System.IO

Public Class Form1

Dim Arret As Boolean
Dim tmp As String 'variable pour stocker chaque ligne du fichier
Dim mot As String 'variable pour stocker le mot à rechercher
Dim place1 As String 'variable pour socker l'emplacement du fichier
Dim scan As StreamReader 'variable de lecture fichier
Dim strLine As String 'variable de lecture fichier
Dim objMessage As Object



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


ListBox1.Items.Clear()

mot = TextBox1.Text 'stock le mot à rechercher dans la variable
place1 = TextBox2.Text 'stock le chemin du fichier


If TextBox1.Text = "" Then 's'assure qu'il y a bien un mot à chercher
MsgBox("Il n'y a rien à chercher!")


ElseIf place1 = "" Then 's'assure qu'il y a bien un emplacement pour le mot a rechercher
MsgBox("Aucun fichier n'a été sélectionné")

Else 'si tous est ok on continue


Arret = False

Do While Arret = False



Call recherche()

'System.Windows.Forms.Application.DoEvents()
'ou
Application.DoEvents()

Loop

End If 'End if de test textbox vide

MsgBox("Fin")

End Sub

'Sub de gestion envois email

Sub email()
Dim messageHTML
On Error GoTo errorHandler

objMessage = CreateObject("CDO.Message")
objMessage.Subject = "Alerte ScanFile: " & mot
objMessage.From = "adressmail" 'adresse mail de l'expéditeur n'est pas obligatoire
objMessage.To = "adressmail" 'Email du destinataire doit-être correct ici
objMessage.TextBody = "Bonjour," & vbCrLf & vbCrLf & "Le mot " & mot & " a été trouvé dans le fichier ci-joint." & vbCrLf & vbCrLf & "Cordialement,"

messageHTML = "Ceci est un message en HTML"

objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "serveur SMTP"
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Update()

objMessage.AddAttachment(place1) 'On ajoute la piéce jointe

objMessage.Send()

MsgBox("Le fichier contient " & mot & vbCrLf & vbCrLf & "Un mail d'alerte a été envoyé!")

'si erreur on sort de la procédure
Exit Sub
errorHandler:

'description de l'erreur survenue
MsgBox(Err.Description)

End Sub


Private Sub recherche()
ListBox1.Items.Clear()


scan = New StreamReader(place1) 'Pass the file path and the file name to the StreamReader constructor.

strLine = scan.ReadLine 'Lire la 1ere ligne du fichier et la stocker dans "strline"

Do While Not strLine Is Nothing 'Continue la lecture tant que "strline" n'est pas vide donc que l'on n'a pas atteint la fin du fichier.


If ((InStr(strLine, mot)) > 0) Then 'on vérifie si le mot recherché est dans la ligne


ListBox1.Items.Add(strLine) 'on ajoute la ligne dans la listbox

Call email()

Arret = True

Else

ListBox1.Items.Add(strLine) 'on ajoute la ligne dans la listbox

End If 'End if à l'interieur de la boucle "DO LOOP"


strLine = scan.ReadLine 'lit la ligne suivante.

Loop

scan.Close() 'ferme le fichier

End Sub

'Sub de commande arret boucle

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Arret = True
End Sub


End Class 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
25 juil. 2011 à 22:49
Bonjour,

Regardes aussi mes commentaires concernant le code en général, ils te seront utiles pour la suite.

Mon site
0
Sebcode Messages postés 11 Date d'inscription vendredi 15 juillet 2011 Statut Membre Dernière intervention 17 juillet 2014
26 juil. 2011 à 23:36
Bonsoir,

J'ai revu mon code, mais quelques pb subsistent...
-pb de sortie de boucle apres envois mail
-mange encore des ressources (boucle do until remplacé par condition de clic?)

Voici le code modifié:

Option Strict On
Option Explicit On

Imports System.IO
Imports System.Threading

Public Class Form1

    Dim Arret As Boolean
    Dim tmp As String 'variable pour stocker chaque ligne du fichier
    Dim mot As String 'variable pour stocker le mot à rechercher
    Dim place1 As String 'variable pour socker l'emplacement du fichier
    Dim scan As StreamReader 'variable de lecture fichier
    Dim strLine As String 'variable de lecture fichier
    Dim objMessage As Object



    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


        Timer1.Interval = 10000 'timer de 10 sec


        ListBox1.Items.Clear()

        mot = TextBox1.Text 'stock le mot à rechercher dans la variable
        place1 = TextBox2.Text


        If TextBox1.Text = "" Then 's'assure qu'il y a bien un mot à chercher
            MsgBox("Il n'y a rien à chercher!")

            ElseIf place1 = "" Then 's'assure qu'il y a bien un emplacement pour le mot a rechercher
            MsgBox("Aucun fichier n'a été sélectionné")

        Else 'si tous est ok on continue


            Arret = False

            Do Until Arret = True

                Application.DoEvents()

                Timer1.Enabled = True

                ProgressBar1.Increment(1)

            Loop

        End If 'End if de test textbox vide

        MsgBox("Fin")

    End Sub

    Private Sub recherche() Handles Timer1.Tick

        ListBox1.Items.Clear()

        scan = New StreamReader(place1) 'Pass the file path and the file name to the StreamReader constructor.

        strLine = scan.ReadLine 'Lire la 1ere ligne du fichier et la stocker dans "strline"

        Do While Not strLine Is Nothing And Arret = False 'Continue la lecture tant que "strline" n'est pas vide donc que l'on n'a pas atteint la fin du fichier.


            If ((InStr(strLine, mot)) > 0) Then 'on vérifie si le mot recherché est dans la ligne


                ListBox1.Items.Add(strLine) 'on ajoute la ligne dans la listbox

                email() 'vers sub "email"
                'Exit Sub
            Else

                ListBox1.Items.Add(strLine) 'on ajoute la ligne dans la listbox

            End If 'End if à l'interieur de la boucle "DO LOOP"


            strLine = scan.ReadLine 'lit la ligne suivante.

        Loop

        scan.Close() 'ferme le fichier

        ProgressBar1.Value = 0

    End Sub

    'Sub de gestion envois email
    Sub email()
        Dim messageHTML

        objMessage = CreateObject("CDO.Message")
        objMessage.Subject = "Alerte: " & mot
        objMessage.From = "adressmail" 'adresse mail de l'expéditeur n'est pas obligatoire
        objMessage.To = "adressmail" 'Email du destinataire doit-être correct ici
        objMessage.TextBody = "Bonjour," & vbCrLf & vbCrLf & "Le mot " & mot & " a été trouvé dans le fichier ci-joint." & vbCrLf & vbCrLf & "Cordialement,"

        messageHTML = "Ceci est un message en HTML"

        objMessage.Configuration.Fields.Item _
        ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
        objMessage.Configuration.Fields.Item _
        ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp"
        objMessage.Configuration.Fields.Item _
        ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
        objMessage.Configuration.Fields.Update()

        objMessage.AddAttachment(place1) 'On ajoute la piéce jointe
        objMessage.Send()

        MsgBox("Le fichier contient " & mot & vbCrLf & vbCrLf & "Un mail d'alerte a été envoyé!")
        Arret = True
        fin()

    End Sub

    'Sub de commande arret boucle
    Private Sub fin() Handles Button2.Click
        Arret = True
        ProgressBar1.Value = 0
        Timer1.Enabled = False
    End Sub

    'Sub d'effacement de listBox1
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        ListBox1.Items.Clear()
    End Sub

End Class
0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
28 juil. 2011 à 21:04
Bonjour,

Le code :
Private Sub recherche() Handles Timer1.Tick
Fonctionne ?
Il ne manquerait pas des paramètres ?

Sinon, à la place de gérer un StreamReader, tu peux directement utiliser : System.Io.File.ReadAllLines(...)

Sinon, pour le problème de conso des ressources, c'est normal, tu tires à fond sur le processeur.
Si tu parles de la mémoire, quand on code en .NET, on ne s'en soucie pas spécialement (sinon, on ferais du C/C++ :D )

Tu pourrais aussi utiliser un thread si ça ralenti trop ton interface.

Il y a déjà une classe pour gérer l'envoi de mail SMTP dans le framework, il me semble.

Sinon, tu n'as pas activé Option Strict (Je ne sais pas si Option Explicit l'est aussi).

Quel est ton pb en sortie de boucle ?

Mon site
0
Rejoignez-nous