Si vous exécutez le code suivant, vous verrez que vous ne pouvez pas cliquer sur Button2 pendant que l'instruction Do[...]Loop est en cours d'exécution:

Imports Microsoft.Office.Interop

Public Class Form1

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

        Dim xlApp As New Excel.Application
        xlApp.Visible = True
        Dim wb1 As Excel.Workbook
        wb1 = xlApp.Workbooks.Open("C:\Book1.xlsx")


        Dim wsSheet1 As Excel.Worksheet
        wsSheet1 = CType(wb1.Sheets(1), Excel.Worksheet)

        Do
            wsSheet1.Cells.Copy()
            wsSheet1.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
        Loop

    End Sub

    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        MsgBox("Hello")
    End Sub

End Class

Comment gardez-vous Form1 réactif pendant l'exécution de l'instruction Do[...]Loop?

0
user7747311 6 avril 2017 à 09:02

2 réponses

Meilleure réponse

Afin de garder votre formulaire réactif pendant que l'instruction Do[...]Loop est en cours d'exécution, vous devez l'exécuter sur un thread distinct à l'aide de classe Tâche.

Créez d'abord une nouvelle méthode et placez l'instruction Do[...]Loop dans cette méthode:

Private Sub CopyCells(ByVal worksheet As Excel.Worksheet)

    Do
        worksheet.Cells.Copy()
        worksheet.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
    Loop

End Sub

Vous pouvez ensuite appeler cette méthode à l'aide de Task.Factory. StartNew:

Task.Factory.StartNew(Sub() CopyCells(wsSheet1))

Je voudrais également abandonner l'utilisation de MsgBox et utiliser MessageBox.Show. MsgBox existe pour VB6 et finit par déléguer à MessageBox de toute façon, il est donc logique d'utiliser MessageBox.Show:

MessageBox.Show("Hello")

Dans son intégralité, votre code ressemblerait à ceci:

Public Class Form1

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

        Dim xlApp As New Excel.Application
        xlApp.Visible = True

        Dim wb1 As Excel.Workbook
        wb1 = xlApp.Workbooks.Open("C:\Book1.xlsx")

        Dim wsSheet1 As Excel.Worksheet
        wsSheet1 = CType(wb1.Sheets(1), Excel.Worksheet)

        Task.Factory.StartNew(Sub() CopyCells(wsSheet1))

    End Sub

    Private Sub CopyCells(ByVal worksheet As Excel.Worksheet)

        Do
            worksheet.Cells.Copy()
            worksheet.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
        Loop

    End Sub

    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        MessageBox.Show("Hello")
    End Sub

End Class

Notez que vous devrez importer System.Threading.Tasks pour utiliser la classe Task.

0
Bugs 6 avril 2017 à 14:07

D'après ce que j'ai lu, il semble que votre interface utilisateur ne répond plus lorsque vous demandez à votre programme d'effectuer une tâche particulière

Dans ce cas, vous devriez consulter les Background Worker exemples sur msdn ou vous pouvez utiliser un autre fil sans utiliser le Background Worker, c'est vraiment votre choix.

Voici un exemple rapide que j'ai écrit qui dessinera des boîtes rectangulaires sur l'écran dans une position aléatoire en utilisant un fil différent, cela vous permettra de déplacer la fenêtre pendant qu'elle se dessine vers l'écran et d'interagir avec d'autres composants et de les faire fonctionner correctement sans qu'elle ne se fige comme un MessageBox.

Imports System.ComponentModel
Public Class Form1
Dim random0 As New Random
Dim thread0 As New Threading.Thread(New Threading.ThreadStart(AddressOf threadDrawing0))

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    thread0.Start()
End Sub
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    thread0.Abort()
End Sub

Private Sub threadDrawing0()
    For i = 0 To 1000
        System.Threading.Thread.Sleep(100)
        Me.CreateGraphics().DrawRectangle(New Pen(Brushes.Blue, 4), New Rectangle(random0.Next(0, Me.Width), random0.Next(0, Me.Height), 20, 20))
    Next
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    MessageBox.Show("Hello World")
End Sub
End Class

Parce que je n'ai pas le fichier Excel avec lequel vous travaillez, je ne peux pas tester le code selon vos besoins précis, mais cela devrait bel et bien vous mettre sur la bonne voie.

MSDN Background Worker Link: https://msdn.microsoft.com/es -es / library / cc221403 (v = vs.95) .aspx

1
user1234433222 6 avril 2017 à 07:32