J'ai un formulaire très simple avec un bouton qui déclenche un sous-programme que j'ai créé et qui recueille les données d'ActiveDirectory et les ajoute à une feuille Excel.
Le problème est que, lorsque je clique sur ce bouton, tout le formulaire se bloque. J'ai donc pensé que l'opération qui rassemble les données et les ajoute à la feuille Excel devrait être exécutée dans son propre thread, afin que le formulaire ne se bloque pas. Il serait peut-être bon d'ajouter également une barre de progression. Cependant, la barre de progression se trouve dans le formulaire principal qui s'ouvre une fois le projet lancé.
Que dois-je faire pour que tout se passe comme je le souhaite ?
Edit : J'ai ajouté une partie de mon code. J'ai un MainForm.vb et un CodeFile.vb. Je veux que la plupart du code soit dans le CodeFile.vb pour que ce soit plus ordonné.
MainForm.vb
Imports User_edit.CodeFile
Imports System.ComponentModel
Public Class MainForm
Private Sub btnImportData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportData.Click
If MyBackgroundWorker.IsBusy <> True Then
MyBackgroundWorker.RunWorkerAsync()
End If
End Sub
Private Sub BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles MyBackgroundWorker.DoWork
ExportADUsers()
End Sub
Private Sub BackgroundWorker_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles MyBackgroundWorker.ProgressChanged
statusBarLabel.Text = (e.ProgressPercentage.ToString)
End Sub
Private Sub BackgroundWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles MyBackgroundWorker.RunWorkerCompleted
statusBarLabel.Text = "Finished"
End Sub
End Class
CodeFile.vb
Imports System.DirectoryServices
Imports System.ComponentModel
Imports System.Threading
Module CodeFile
Public Sub ExportADUsers()
MainForm.MyBackgroundWorker.WorkerReportsProgress = True
MainForm.MyBackgroundWorker.WorkerSupportsCancellation = True
Dim i As Integer
Dim objRootDSE, strRoot, strfilter, strAttributes, strScope
objRootDSE = GetObject("LDAP://RootDSE")
strRoot = objRootDSE.GET("DefaultNamingContext")
strfilter = "(&(objectCategory=Person)(objectClass=User))"
strAttributes = "mail,userPrincipalName,givenName,sn," & _
"initials,displayName,physicalDeliveryOfficeName," & _
"telephoneNumber,mail,wWWHomePage,profilePath," & _
"scriptPath,homeDirectory,homeDrive,title,department," & _
"company,manager,homePhone,pager,mobile," & _
"facsimileTelephoneNumber,ipphone,info," & _
"streetAddress,postOfficeBox,l,st,postalCode,c"
'Scope of the search. Change to "onelevel" if you didn't want to search child OU's
MainForm.statusBarLabel.Text = "Collecting data"
strScope = "subtree"
Dim cn, cmd, rs
cn = CreateObject("ADODB.Connection")
cmd = CreateObject("ADODB.Command")
cn.open("Provider=ADsDSOObject;")
cmd.ActiveConnection = cn
cmd.commandtext = "<LDAP://" & strRoot & ">;" & strfilter & ";" & _
strAttributes & ";" & strScope
rs = cmd.EXECUTE
Dim objExcel, objWB, objSheet
objExcel = CreateObject("Excel.Application")
objWB = objExcel.Workbooks.Add
objSheet = objWB.Worksheets(1)
For i = 0 To rs.Fields.Count - 1
MainForm.MyBackgroundWorker.ReportProgress(i * 10)
objSheet.Cells(1, i + 1).Value = rs.Fields(i).Name
objSheet.Cells(1, i + 1).Font.Bold = True
Next
Dim strExportFile
strExportFile = "C:\users\vsando\desktop\export.xls"
objSheet.Range("A2").CopyFromRecordset(rs)
objSheet.SaveAs(strExportFile)
'Clean up
rs.Close()
cn.Close()
objSheet = Nothing
objWB = Nothing
objExcel.Quit()
objExcel = Nothing
End Sub
Remarquez le ExportFromAD
Le sous-marin que j'ai dans le CodeFile.vb
. C'est ce qui fait réellement le travail. Dans la boucle "For each" qui ajoute les données à Excel, j'ai placé la balise MainForm.MyBackgroundWorker.ReportProgress(i * 10)
.
Le problème est que cela ne met pas réellement à jour l'étiquette sur le formulaire. Ce que je trouve assez bizarre car le formulaire n'est pas vraiment suspendu ou autre. Est-ce qu'il essaie d'accéder à un autre thread ou quelque chose comme ça ? En d'autres termes, le formulaire est exécuté sur son propre thread qui n'est pas accessible depuis mon second thread ?