Why UserForm is “Not Responding” During Run Time in VBA Excel?

五迷三道 提交于 2019-12-07 00:33:30

问题


I'm very new with VBA Excel and i only know the things as far as i need for this report formatting task.

I'm almost done with my task but when i run the program and start the progress, eventhough it works successfully, GUI is not responding for a minute. I share my code here, is something wrong with it? Can you suggest me any best-practice? I don't want it to freeze because it will look bad to my manager.

Just to make it clear, by "not responding" i mean it freezes on the screen and says "Not Responding" on it's windows frame and when i click on it, it gives a message like this:

*ps: the sheet that i get records has 20997 rows and 7 columns and i make some records to another sheet on same file sized and 20997 lines 23 columns. And my GUI is very simple, it has nothing but a CommandButton that starts the progress.

How can i fix this?


回答1:


You can prevent the freezing of excel window by putting

DoEvents

inside your loop.




回答2:


This happens because your procedure is very busy working. For example your Sub TheLoop() is accessing 20995 x 16 times a cell to write on them a string. The interaction VBA with Excel is slow.

There is a couple of things you can do to make the procedure faster.

1.Disable events handlers, screen updating and calculations before you run your procedure. At the end of the procedure restore the settings again.

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

   '......  Code'

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

2.You can optimize the Sub TheLoop. Instead of writing immediately on the cells, write the values inside an array. After the array is full with the values, assign the values of the array to the range that you need. for example:

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

EDIT:

Given that the columns between the ones that you modify are only text or empty cells, you can:

  1. read the whole range into an array.
  2. Then modify the array in the same way you are currently modifying cells.
  3. After the modifications are done, dump the whole matrix in the range again.'

For example:

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



回答3:


Alright, i believe i found the best solution for this. (a) :)

Instead of using for loop in TheLoop subroutine, i removed the loop and changed it as in below. That makes it incredibly faster when i compare it with my first code eventhough i didn't disable event properties, and now it's not freezing.

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


来源:https://stackoverflow.com/questions/13606651/why-userform-is-not-responding-during-run-time-in-vba-excel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!