我的Excel在运行宏时变得无响应,它使用分页通过API从JIRA获取所有问题。

huangapple go评论91阅读模式
英文:

my excel becomes unresponsive while running a macro, it gets all the issues from JIRA using api using pagination

问题

Here's the translated code without the comments:

  1. Sub Jira_for_all_issues_v6()
  2. Dim http As New MSXML2.XMLHTTP60, url As String, response As String, json As Object, startAt As Integer, batchSize As Integer, totalIssues As Integer, _
  3. issuesCount As Integer, has_subtsk As Boolean, print_row As Long, data As Object, ok_yes As Object, totalIssues5 As Integer, last_row_print As Long, _
  4. http1 As New MSXML2.XMLHTTP60, url1 As String, response1 As String, json1 As Object, user_name_password_in_base64_encoding As String, i As Integer
  5. Dim issues As Collection, StartTime As Double, SecondsElapsed As Double
  6. StartTime = Timer
  7. user_name_password_in_base64_encoding = UserPassBase64()
  8. Application.ScreenUpdating = False
  9. Worksheets("Sheet2").Cells(1, 1).Value = "Issue id"
  10. Worksheets("Sheet2").Cells(1, 2).Value = "Issue key"
  11. Worksheets("Sheet2").Cells(1, 3).Value = "Status"
  12. Worksheets("Sheet2").Cells(1, 4).Value = "Priority"
  13. Worksheets("Sheet2").Cells(1, 5).Value = "Reporter"
  14. Worksheets("Sheet2").Cells(1, 6).Value = "Reporter Id"
  15. Worksheets("Sheet2").Cells(1, 7).Value = "Creator"
  16. Worksheets("Sheet2").Cells(1, 8).Value = "Creator"
  17. url1 = "https://jira/rest/api/2/search?jql=project=project AND issuetype in (Bug)&maxResults=" & 1 & "&startAt=" & 0
  18. With http1
  19. .Open "GET", url1, False
  20. .setRequestHeader "Content-Type", "application/json"
  21. .setRequestHeader "Accept", "application/json"
  22. .setRequestHeader "Authorization", "Basic " & user_name_password_in_base64_encoding
  23. .send
  24. End With
  25. response1 = http1.responseText
  26. Set json1 = JsonConverter.ParseJson(response1)
  27. totalIssues = json1("total")
  28. startAt = 0
  29. batchSize = 100
  30. Set ok_yes = json1("issues")
  31. Do While startAt < totalIssues
  32. url = "https://jira-/rest/api/2/search?jql=project=project AND issuetype in (Bug)&maxResults=" & batchSize & "&startAt=" & startAt
  33. http.Open "GET", url, False
  34. http.setRequestHeader "Content-Type", "application/json"
  35. http.setRequestHeader "Authorization", "Basic " & user_name_password_in_base64_encoding
  36. http.send
  37. response = http.responseText
  38. Set json = JsonConverter.ParseJson(response)
  39. issuesCount = json("issues").Count
  40. totalIssues5 = json("total")
  41. last_row_print = Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
  42. Set issues = json("issues")
  43. For i = 1 To issuesCount
  44. Worksheets("Sheet2").Cells(last_row_print, 1).Value = issues(i)("id")
  45. Worksheets("Sheet2").Cells(last_row_print, 2).Value = issues(i)("key")
  46. Worksheets("Sheet2").Cells(last_row_print, 3).Value = issues(i)("fields")("status")("name")
  47. Worksheets("Sheet2").Cells(last_row_print, 4).Value = issues(i)("fields")("priority")("name")
  48. Worksheets("Sheet2").Cells(last_row_print, 5).Value = issues(i)("fields")("reporter")("displayName")
  49. Worksheets("Sheet2").Cells(last_row_print, 6).Value = issues(i)("fields")("reporter")("name")
  50. Worksheets("Sheet2").Cells(last_row_print, 7).Value = issues(i)("fields")("creator")("name")
  51. Worksheets("Sheet2").Cells(last_row_print, 8).Value = issues(i)("fields")("creator")("displayName")
  52. last_row_print = last_row_print + 1
  53. Next i
  54. startAt = startAt + batchSize
  55. Loop
  56. SecondsElapsed = Round(Timer - StartTime, 2)
  57. MsgBox "All issues have been retrieved."
  58. Application.ScreenUpdating = True
  59. MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
  60. End Sub

To prevent Excel from becoming unresponsive, you can consider using background threading for the HTTP requests, so they don't block the main application. You can use multi-threading libraries available in VBA, like vbWatchdog or Async VBA, to achieve this. Additionally, you've already mentioned turning off Application.ScreenUpdating, which is a good practice to improve performance. Increasing the batch size can also help optimize the code further.

英文:
  1. Sub Jira_for_all_issues_v6()
  2. Dim http As New MSXML2.XMLHTTP60, url As String, response As String, json As Object, startAt As Integer, batchSize As Integer, totalIssues As Integer, _
  3. issuesCount As Integer, has_subtsk As Boolean, print_row As Long, data As Object, ok_yes As Object, totalIssues5 As Integer, last_row_print As Long, _
  4. http1 As New MSXML2.XMLHTTP60, url1 As String, response1 As String, json1 As Object, user_name_password_in_base64_encoding As String, i As Integer
  5. Dim issues As Collection, StartTime As Double, SecondsElapsed As Double
  6. StartTime = Timer
  7. user_name_password_in_base64_encoding = UserPassBase64()
  8. Application.ScreenUpdating = False
  9. Worksheets(&quot;Sheet2&quot;).Cells(1, 1).Value = &quot;Issue id&quot;
  10. Worksheets(&quot;Sheet2&quot;).Cells(1, 2).Value = &quot;Issue key&quot;
  11. Worksheets(&quot;Sheet2&quot;).Cells(1, 3).Value = &quot;Status&quot;
  12. Worksheets(&quot;Sheet2&quot;).Cells(1, 4).Value = &quot;priority&quot;
  13. Worksheets(&quot;Sheet2&quot;).Cells(1, 5).Value = &quot;reporter&quot;
  14. Worksheets(&quot;Sheet2&quot;).Cells(1, 6).Value = &quot;reporter Id&quot;
  15. Worksheets(&quot;Sheet2&quot;).Cells(1, 7).Value = &quot;creator&quot;
  16. Worksheets(&quot;Sheet2&quot;).Cells(1, 8).Value = &quot;creator&quot;
  17. url1 = &quot;https://jira/rest/api/2/search?jql=project=project AND issuetype in (Bug)&amp;maxResults=&quot; &amp; 1 &amp; &quot;&amp;startAt=&quot; &amp; 0
  18. &#39;Set the HTTP request properties
  19. With http1
  20. .Open &quot;GET&quot;, url1, False
  21. .setRequestHeader &quot;Content-Type&quot;, &quot;application/json&quot;
  22. .setRequestHeader &quot;Accept&quot;, &quot;application/json&quot;
  23. .setRequestHeader &quot;Authorization&quot;, &quot;Basic &quot; &amp; user_name_password_in_base64_encoding
  24. &#39;Send the HTTP request and retrieve the response
  25. .send
  26. End With
  27. response1 = http1.responseText
  28. &#39;Parse the JSON data using a JSON parser library
  29. Set json1 = JsonConverter.ParseJson(response1)
  30. totalIssues = json1(&quot;total&quot;)
  31. startAt = 0
  32. batchSize = 100
  33. &#39; print_row = 2
  34. Set ok_yes = json1(&quot;issues&quot;)
  35. Do While startAt &lt; totalIssues
  36. &#39;Set the URL to the JIRA REST API endpoint with the startAt and maxResults parameters
  37. url = &quot;https://jira-/rest/api/2/search?jql=project=project AND issuetype in (Bug)&amp;maxResults=&quot; &amp; batchSize &amp; &quot;&amp;startAt=&quot; &amp; startAt
  38. &#39;Set the HTTP request properties
  39. http.Open &quot;GET&quot;, url, False
  40. http.setRequestHeader &quot;Content-Type&quot;, &quot;application/json&quot;
  41. http.setRequestHeader &quot;Authorization&quot;, &quot;Basic &quot; &amp; user_name_password_in_base64_encoding
  42. &#39;Send the HTTP request and retrieve the response
  43. http.send
  44. response = http.responseText
  45. &#39;Parse the JSON data using a JSON parser library
  46. Set json = JsonConverter.ParseJson(response)
  47. &#39;Extract the desired data from the parsed JSON data and insert it into your Excel worksheet
  48. issuesCount = json(&quot;issues&quot;).Count
  49. totalIssues5 = json(&quot;total&quot;)
  50. last_row_print = Worksheets(&quot;Sheet2&quot;).Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
  51. Set issues = json(&quot;issues&quot;)
  52. For i = 1 To issuesCount
  53. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 1).Value = issues(i)(&quot;id&quot;)
  54. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 2).Value = issues(i)(&quot;key&quot;)
  55. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 3).Value = issues(i)(&quot;fields&quot;)(&quot;status&quot;)(&quot;name&quot;)
  56. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 4).Value = issues(i)(&quot;fields&quot;)(&quot;priority&quot;)(&quot;name&quot;)
  57. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 5).Value = issues(i)(&quot;fields&quot;)(&quot;reporter&quot;)(&quot;displayName&quot;)
  58. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 6).Value = issues(i)(&quot;fields&quot;)(&quot;reporter&quot;)(&quot;name&quot;)
  59. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 7).Value = issues(i)(&quot;fields&quot;)(&quot;creator&quot;)(&quot;name&quot;)
  60. Worksheets(&quot;Sheet2&quot;).Cells(last_row_print, 8).Value = issues(i)(&quot;fields&quot;)(&quot;creator&quot;)(&quot;displayName&quot;)
  61. last_row_print = last_row_print + 1
  62. Next i
  63. &#39;Update the startAt parameter for the next batch of search results
  64. startAt = startAt + batchSize
  65. Loop
  66. SecondsElapsed = Round(Timer - StartTime, 2)
  67. MsgBox &quot;All issues have been retrieved.&quot;
  68. Application.ScreenUpdating = True
  69. MsgBox &quot;This code ran successfully in &quot; &amp; SecondsElapsed &amp; &quot; seconds&quot;, vbInformation
  70. End Sub

so this is my code. there are about 1000 issues in all and it takes about 16 mins to run. while this runs the excel app becomes unresponsive, how can prevent this and also any tips on how to optimize this code?

i tried turning off the appliction.screenupdating and it kinda works brought it down from 18 mins to 16 mins, also i had increased the batch size from 50 to 100.

答案1

得分: 1

在循环中适当加入 DoEvents,如下所示

  1. ...
  2. startAt = startAt + batchSize
  3. DoEvents
  4. Loop
  5. ...
英文:

Squeeze in a DoEvents somewhere in the loop, like this

  1. ...
  2. startAt = startAt + batchSize
  3. DoEvents
  4. Loop
  5. ...

huangapple
  • 本文由 发表于 2023年4月17日 19:25:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76034642.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定