none
word文書が開くまでの間に「お待ちください」のメッッセージをだしたい。 RRS feed

  • 質問

  • 皆さんに教えていただいた宛名印刷アプリですが,word文書が開くまでに5秒近くの時間を要します。
    それで「お待ちください」とのメッセージを表示したいと考えています。

    Public Class Form1
        Dim Futou As String
        Dim Meibo As String
        Dim tbxStr As String
    
        'Form2の操作のために
        Dim f As New Form2
    
        ' wordのファイルを開く
        Dim tbxNum As String
        Dim Path As String
        Dim wdApp As Object
        Dim wdToggle As Object
         
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            '封筒の選択
       
            '宛先の選択
      
            '封筒にメモを書くとき
            If RadioButton6.Checked = True Then
                'form2を呼び出す
                If f.ShowDialog(Me) = DialogResult.OK Then
                    Me.tbxStr = f.RichTextBox1.Text
                End If
            End If
            '------------ここでForm1を閉じて-------Form3を表示----------
            '差し込み
            Path = "C:\AtenaPrint\"
            wdApp = CreateObject("Word.Application")
            wdToggle = Nothing
    
            With wdApp
                'word文書を開く
                .visible = True
                .documents.open("C:\AtenaPrint\" & Futou)
    
                '差し込み
                .ActiveDocument.MailMerge.OpenDataSource(
    
                )
                '結果のプレビューを表示
                .ActiveDocument.MailMerge.ViewMailMergeFieldCodes = wdToggle
                'メモ書き
                .ActiveDocument.Shapes("Text Box " & tbxNum).TextFrame.TextRange.Text = tbxStr
            End With
            '----------------------ここでForm3を閉じる
            Me.Close()
        End Sub
    End Class

    ネット上の情報を探してみましたが’プログレスバー’の紹介がやたらと多く,肝心の情報を見つけることができませんでした。

    処理中に「Form3」を表示しておいて,処理終了時にform3を閉じる方法を考えていますが,Form1の扱いはこれでよいのか?と考えあぐねています。

    どうぞご教授いただけますようお願いいたします。。

    <追記>Form1を非表示にして,最後にForm3,Form1の順に閉じるとできそうな気もしますが……。


    • 編集済み goodwave 2019年7月6日 5:47 追記
    2019年7月6日 5:34

回答

  • プログレスバーと書いてあったので進捗表示させたいのかと思いましたが、そうでないならForm3をShowでも構わないです。

    別スレッドにしない場合はFormやControlが操作できない状態になるので、フリーズしているようには見えることもあります。
    VisualStudioからのデバッグ実行では判り難いですが、Windowsからフリーズしていると判定されてしまいます。(数秒間なら問題ないですがある程度長く無反応になると)

    逆に別スレッドにしておくとフリーズしている判定されず、進捗表示などでコントロールの表示更新も可能になります。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク goodwave 2019年7月7日 19:21
    2019年7月7日 2:21
  • gekka さんのコードは UI スレッドをブロックしません。

    どういう利点があるかというと、gekka さんのコードを

    Private Sub Work()
        Threading.Thread.Sleep(30000)
    End Sub

    goodwave さんのコードを

        Form3.Show()
        Me.Visible = False
        Threading.Thread.Sleep(30000)
        Me.Close()
        Form3.Close()

    のように変えて実行して比較していただいたほうが良いと思います。

    表示された Form3 をマウスで触るとどうなりますか?

    • 回答としてマーク goodwave 2019年7月7日 19:21
    2019年7月7日 1:00

すべての返信

  • Wordに対する処理を別スレッドで行わせるようにします

    Public Class Form1 Dim Futou As String Dim Meibo As String Dim tbxStr As String 'Form2の操作のために Dim f As New Form2 ' wordのファイルを開く Dim tbxNum As String 'Dim Path As String 'Dim wdApp As Object 'Dim wdToggle As Object Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click If RadioButton6.Checked = True Then If f.ShowDialog(Me) = DialogResult.OK Then Me.tbxStr = f.RichTextBox1.Text End If End If 'Form3を表示させる Dim f3 As New Form With {.Text = "お待ちください 0", .Width = 200, .Height = 50, .StartPosition = FormStartPosition.CenterParent, .ControlBox = False, .ShowInTaskbar = False, .FormBorderStyle = FormBorderStyle.FixedSingle} AddHandler f3.Shown, AddressOf Form3_Shown f3.ShowDialog(Me) '処理が終わるまで表示し続けさせる Me.Close() End Sub Async Sub Form3_Shown(ByVal sender As Object, ByVal e As EventArgs) 'Form3が表示されたら処理を開始する Dim f3 As Form = CType(sender, Form) 'タイマーを定期的に呼ばせることで状態表示を更新する Dim timer As New Timer Dim startTime As DateTime = DateTime.Now AddHandler timer.Tick _ , Sub(ts, te) Dim elapsed = DateTime.Now - startTime f3.Text = "お待ちください " & elapsed.TotalSeconds.ToString("0") End Sub timer.Interval = 1000 timer.Start() Try 'Wordに対する処理を別スレッドで実行させて、それが終了するまで待つ Await Task.Run(New Action(AddressOf Work)) Catch ex As Exception MessageBox.Show(f3, ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End Try timer.Stop() f3.Close() '処理が終わったらForm3を閉じる End Sub Private Sub Work() '別スレッドで行う処理 '別スレッドからFromにあるコントロールはさわれないので注意すること 'Throw New ApplicationException("Test") '消し忘れ Dim Path As String Dim wdApp As Object Dim wdToggle As Object Path = "C:\AtenaPrint\" wdApp = CreateObject("Word.Application") wdToggle = Nothing With wdApp .visible = True Return '動作テストのためここで終わる .documents.open("C:\AtenaPrint\" & Futou) .ActiveDocument.MailMerge.OpenDataSource() .ActiveDocument.MailMerge.ViewMailMergeFieldCodes = wdToggle .ActiveDocument.Shapes("Text Box " & tbxNum).TextFrame.TextRange.Text = tbxStr End With End Sub End Class

    #BackgroundWorkerなどを使用でもいいですが、async/awaitの方が処理の流れが判り易くなります

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2019年7月7日 2:22 例外発生を消し忘れていた
    2019年7月6日 10:03
  • gekkaさん,いつもありがとうございます。

    '------------ここでForm1を閉じて-------Form3を表示---------- の位置に
    Form3.Show()
    Me.Visible = False

    '----------------------ここでForm3を閉じる-----------の位置に
    Me.Close()
    Form3.Close()

    としたところ,一応は思いどおりにいきました。

    お示しくださったコードは私の頭では読むことができないのですが,上記のようにすることと比べて,どのような利点がおありなのか2・3お聞かせ頂けますと勉強になります。

    よろしくお願いします。

    2019年7月6日 18:13
  • gekka さんのコードは UI スレッドをブロックしません。

    どういう利点があるかというと、gekka さんのコードを

    Private Sub Work()
        Threading.Thread.Sleep(30000)
    End Sub

    goodwave さんのコードを

        Form3.Show()
        Me.Visible = False
        Threading.Thread.Sleep(30000)
        Me.Close()
        Form3.Close()

    のように変えて実行して比較していただいたほうが良いと思います。

    表示された Form3 をマウスで触るとどうなりますか?

    • 回答としてマーク goodwave 2019年7月7日 19:21
    2019年7月7日 1:00
  • プログレスバーと書いてあったので進捗表示させたいのかと思いましたが、そうでないならForm3をShowでも構わないです。

    別スレッドにしない場合はFormやControlが操作できない状態になるので、フリーズしているようには見えることもあります。
    VisualStudioからのデバッグ実行では判り難いですが、Windowsからフリーズしていると判定されてしまいます。(数秒間なら問題ないですがある程度長く無反応になると)

    逆に別スレッドにしておくとフリーズしている判定されず、進捗表示などでコントロールの表示更新も可能になります。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク goodwave 2019年7月7日 19:21
    2019年7月7日 2:21
  • gekkaさん,koz6.0さん,ありがとうございます。

    >Form3をShowでも構わないです。

    取り敢えずは,現在のコードでセットアッププロジェクトを作成しておいた後に,教えてくださいましたやり方をコピペして,じっくりと勉強して別のセットアッププロジェクトを作ってみます。

    2019年7月7日 19:21