7

私はVBAExcelを初めて使用し、このレポートの書式設定タスクに必要な範囲でしか知りません。

タスクはほぼ完了しましたが、プログラムを実行して進行状況を開始すると、正常に機能していても、GUIが1分間応答しません。ここでコードを共有しますが、何か問題がありますか?ベストプラクティスを提案してもらえますか?マネージャーに見栄えが悪いので、フリーズさせたくありません。

明確にするために、「応答しない」とは、画面上でフリーズし、ウィンドウフレームに「応答しない」と表示され、クリックすると次のようなメッセージが表示されることを意味します。

ここに画像の説明を入力してください

* ps:レコードを取得するシートには20997行7列があり、同じファイルサイズで20997行23列の別のシートにいくつかのレコードを作成します。そして私のGUIは非常にシンプルで、進行を開始するCommandButtonしかありません。

どうすればこれを修正できますか?

4

4 に答える 4

20

置くことでExcelウィンドウの凍結を防ぐことができます

DoEvents

ループ内。

于 2013-03-15T12:26:28.640 に答える
4

これは、手順が非常に忙しいために発生します。たとえばSub TheLoop()、セルに20995 x 16回アクセスして、文字列を書き込みます。VBAとExcelの相互作用は遅いです。

手順を高速化するためにできることがいくつかあります。

1.プロシージャを実行する前に、イベントハンドラ、画面の更新、および計算を無効にします。手順の最後に、設定を再度復元します。

   'Disable'
   Application.EnableEvents = False
   Application.ScreenUpdating = False
   Application.Calculation = xlCalculationManual

   '......  Code'

   'Enable'
   Application.EnableEvents = True
   Application.ScreenUpdating = True
   Application.Calculation = xlCalculationAutomatic

2.最適化できますSub TheLoop。セルにすぐに書き込む代わりに、配列内に値を書き込みます。配列が値でいっぱいになったら、配列の値を必要な範囲に割り当てます。例えば:

Dim ResultValues() As String
Dim j As Long

ReDim ResultValues(2 To 20997, 1 To 3)

For j = 2 To 20997
    ResultValues(j, 1) = "New Defect"
    ResultValues(j, 2) = "3"
    ResultValues(j, 3) = "2"
Next j

With ThisWorkbook.Worksheets("myWorksheet")
    .Range(.Cells(2, 3), .Cells(20997, 5)) = ResultValues
End With

編集:

変更する列の間の列がテキストまたは空のセルのみである場合、次のことができます。

  1. 範囲全体を配列に読み込みます。
  2. 次に、現在セルを変更しているのと同じ方法で配列を変更します。
  3. 変更が完了したら、マトリックス全体を範囲内に再度ダンプします。

例えば:

Sub TheLoop()
Dim arrRangeValues() as Variant
Dim j as Long

arrRangeValues= Range("A2:V20997").Value2

For j = 2 To 20997
    arrRangeValues(j, 1) = "Defect" 'Cells(row_index , column_index)'
    arrRangeValues(j, 3) = "New Defect"
    arrRangeValues(j, 4) = "3" ' this one also might be empty'
    arrRangeValues(j, 5) = "2" ' this one also might be empty'

    arrRangeValues(j, 7) = "Name Surname"
    arrRangeValues(j, 8) = arrRangeValues(j, 7)
    arrRangeValues(j, 16) = arrRangeValues(j, 7)
    ...
    arrRangeValues(j, 10) = " http://SERVER_NAME:8888/PROJECT_NAME/ "
Next j

Range("A2:V20997").Value2 = arrRangeValues
End Sub
于 2012-11-28T15:24:20.883 に答える
0

了解しました。これに対する最善の解決策を見つけたと思います。(a):)

TheLoopサブルーチンでforループを使用する代わりに、ループを削除して次のように変更しました。これにより、イベントプロパティを無効にしなかったにもかかわらず、最初のコードと比較すると非常に高速になり、フリーズしなくなりました。

Sub TheLoop()

    Cells(2, 1).Resize(20996) = "Defect"
    Cells(2, 3).Resize(20996) = "New Defect"
    Cells(2, 4).Resize(20996) = "3"
    Cells(2, 5).Resize(20996) = "2"
    Cells(2, 7).Resize(20996) = "Name Surname"
    Cells(2, 8).Resize(20996) = "Name Surname"
    Cells(2, 9).Resize(20996) = "FALSE"


    Cells(2, 10).Resize(20996) = " http://SERVER_NAME:8888/PROJECT_NAME/ "


    Cells(2, 12).Resize(20996) = "Software Quality"
    Cells(2, 13).Resize(20996) = "Unsigned"
    Cells(2, 14).Resize(20996) = "Software Quality"
    Cells(2, 15).Resize(20996) = "1"
    Cells(2, 16).Resize(20996) = "Name Surname"
    Cells(2, 18).Resize(20996) = "Software Quality"
    Cells(2, 20).Resize(20996) = "Development"
    Cells(2, 22).Resize(20996) = " TYPE YOUR MODULE'S NAME TO HERE"

End Sub
于 2012-11-29T13:52:14.577 に答える
0

Application.ScreenUpdating、Application.EnableEvents、Application.Calculation、DoEvents、Application.Wait(Now + TimeValue( "0:00:10"))を試してみましたが、残念ながら、最後のオプションではその問題を解決できません。 MicrosoftのWebページで、プログラムが「応答しない」と言ったら、私に言ってください。

  1. セキュリティ上の理由と
  2. 重すぎるか複雑すぎるため
  3. プログラムは、これから行うユーザーにフィードバックを送信しないためです。

私の場合、Win10オペレーティングシステムと顧客にフィードバックを提供するために最終的にユーザーにMsgBoxを表示してみましたが、ユーザーが[はい]、[はい]、[はい]、[はい]、[OK]、[OK]、[OK]、[OK]、[OK]、[OK]をクリックするほど退屈です。 MsgBoxのVBA(自動的に閉じる)に関する他のフォーラムを見ると、そのコードCreateObject("WScript.Shell").PopUp "Please Wait", 1とtadaが提案されています!! 「応答しないメッセージ」の表示を停止します。ユーザーがメッセージを無効にするためにクリックまたはボタンを押さない場合でも、メッセージが1秒後に閉じた後にプログラムが実行されることを心配しないでください。私の場合、これは解決します。私にはたくさんの問題があります、私はあなたを助けたいと思っています、幸運です。

于 2021-05-17T23:39:52.747 に答える