วิธีเพิ่มความเร็วของโค้ดโดยใช้โครงสร้างข้อมูลแทนที่จะเป็นลูปต่อไป


1

ฉันได้รับการแก้ไขแล้วอื่น ๆ อีกหลายที่ใช้Application.IndexกับApplication.WorksheetFunction.Matchที่และเวลาในการดำเนินการประมาณ 7-8 วินาทีเพื่อมิลลิวินาทีลดลง แต่ฉันรู้สึกว่ายังมีห้องพักสำหรับการปรับปรุง

ฉันควรใช้อาร์เรย์ด้วยIndexและMatch?

ฉันได้รับคำสั่งให้ใช้Scripting.Dictionaryเช่นกัน แต่ฉันกำลังมองหาคนที่สามารถสาธิตวิธีการใช้งานได้ทันทีในสถานการณ์นี้ เพราะในหัวของฉันฉันต้องใส่พจนานุกรมด้วยการวนซ้ำก่อนที่ฉันจะสามารถใช้มันได้ดังนั้นมันจะไม่เหมือนกันในแง่ของความเร็ว?

'Production Quantity for Dashboard
For i = 2 To Total_rows_Prod
    For j = 2 To Total_rows_Dash
        If ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5) = ThisWorkbook.Worksheets("Dashboard").Cells(j, 1) Then
           ThisWorkbook.Worksheets("Dashboard").Cells(j, 4) = ThisWorkbook.Worksheets("Dashboard").Cells(j, 4) + ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 31) / ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 4)
        End If
    Next j
Next i

หลังจากทำการทดสอบคอขวดตามที่แสดงด้านล่าง (เวลารันโค้ดแสดงในแถวที่ 10): ป้อนคำอธิบายรูปภาพที่นี่

อย่างไรก็ตามเมื่อใช้IndexและMatchในขณะที่ใช้เพียง 1 for-nextวงดังที่แสดงในรหัสด้านล่าง:

'Production Quantity for Dashboard
For i = 2 To Total_rows_Prod
    m = Application.Match(ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5), ThisWorkbook.Worksheets("Dashboard").Range("A:A"), 0)
    If Not IsError(m) Then
        ThisWorkbook.Worksheets("Dashboard").Cells(Application.WorksheetFunction.Match(ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5), ThisWorkbook.Worksheets("Dashboard").Range("A:A"), 0), 4) = ThisWorkbook.Worksheets("Dashboard").Cells(Application.WorksheetFunction.Match(ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 5), ThisWorkbook.Worksheets("Dashboard").Range("A:A"), 0), 4) + ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 31) / ThisWorkbook.Worksheets("Prod. Qty.").Cells(i, 4)
    End If
Next i

เวลาทำงานจะเล็กน้อยตามที่แสดงด้านล่าง (ยังอยู่ที่แถว 10):

ป้อนคำอธิบายรูปภาพที่นี่

ครั้งสุดท้ายที่ฉันสามารถทำให้ทุกอย่างทำงานด้วยIndexและการMatchทดแทนคือ 2 วินาที:

ป้อนคำอธิบายรูปภาพที่นี่

แต่ในเน็ตบุ๊กที่ช้ากว่าที่ใช้โปรเซสเซอร์ Pentium Atom จะใช้เวลา 26 วินาทีในการดำเนินการกับรหัสเดียวกัน ดังนั้นฉันสงสัยว่ามีวิธีที่จะลดความเร็วลง 26 วินาทีนั้นหรือไม่

การปรับปรุงใด ๆ ที่จะทำให้เวลาในการดำเนินการลดลงอย่างเหมาะสมนั้นเหมาะสมที่สุด พิจารณาพจนานุกรม แต่ฉันไม่รู้ว่าจะใช้อย่างไรเนื่องจากมีKeyและValueพารามิเตอร์สำหรับ.Addและในหัวของฉันมันต้องใช้ 2 for-nextลูปในการทำสิ่งเดียวกันหรือไม่


ฉันไม่แน่ใจว่าทำไมคุณจึงคิดIndexและMatchเป็นวิธีที่ดีที่สุดในการเข้าถึงสิ่งนี้ จัดเก็บคีย์ที่เกี่ยวข้องจากแผ่นงานที่คุณต้องการจับคู่ใน a Scripting.Dictionaryจากนั้นใช้.Existsเมื่อคุณวนซ้ำอีกปุ่มหนึ่ง การพยายามเขียน VBA เหมือนกับฟังก์ชั่นของ Excel นั้นไม่ใช่วิธีที่จะทำให้ได้ประสิทธิภาพที่ดีที่สุด
Comintern

@Comintern ขอบคุณฉันเพียงแค่มันไม่ได้ขึ้นอยู่กับการทดสอบของฉันและมันเป็นวิธีเดียวที่ฉันรู้วิธีการทำ
Pherdindy

@Comintern ฉันสงสัยว่าถ้าฉันเติมScripting.Dictionaryด้วยkeysไม่ต้องวิ่งfor-nextวนไปทำเช่นนั้น? งั้นฉันจะต้องเรียกใช้for-nextลูปอื่นเพื่อตรวจสอบพจนานุกรม.Existsเหรอ? ในขณะที่IndexและMatchควรจะต้องมีfor-nextวงเดียวที่จะทำสิ่งทั้งหมด ในแง่ของความเร็วไหนเร็วกว่ากัน?
Pherdindy

คุณยังต้องเรียกใช้ลูปต่อไป แต่จะไม่ซ้อนกันอีกต่อไป สิ่งที่คุณต้องทำคือการใช้ประโยชน์จากความจริงที่ว่าการDictionaryค้นหาแบบแฮชแทนที่จะทำการสำรวจทั้งชุด ดูคำตอบนี้บน CRเพื่อให้ได้แนวคิดที่ดีขึ้นเกี่ยวกับสิ่งที่ฉันกำลังพูดถึง
Comintern

คำตอบ:


1

โดยทั่วไปเวลาส่วนใหญ่ของรหัส VBA คือการอ่านและเขียนค่าจาก / ไปยังแผ่นงาน คุณควรลดให้มากที่สุด

วิธีที่ง่ายที่สุดในการลดการดำเนินการดังกล่าวคือการอ่านข้อมูลอินพุตของคุณลงในอาร์เรย์จัดการกับมันตามที่คุณต้องการแล้วเขียนผลลัพธ์กลับมา
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับสิ่งนั้นได้ที่นี่: http://www.cpearson.com/Excel/ArraysAndRanges.aspx

รหัสที่อัปเดตของคุณจะมีลักษณะดังนี้:

Dim arr_prodQty5 As Variant
Dim arr_DashBoard1 As Variant
Dim arr_DashBoard4 As Variant
Dim arr_prodQty31 As Variant
Dim arr_prodQty4 As Variant

arr_prodQty5 = ThisWorkbook.Worksheets("Prod. Qty.").Range(Cells(2, 5), Cells(Total_rows_Prod, 5))
arr_prodQty4 = ThisWorkbook.Worksheets("Prod. Qty.").Range(Cells(2, 4), Cells(Total_rows_Prod, 4))
arr_prodQty31 = ThisWorkbook.Worksheets("Prod. Qty.").Range(Cells(2, 5), Cells(Total_rows_Prod, 5))
arr_DashBoard1 = ThisWorkbook.Worksheets("Dashboard").Range(Cells(2, 1), Cells(total_rows_dash, 1))
arr_DashBoard4 = ThisWorkbook.Worksheets("Dashboard").Range(Cells(2, 4), Cells(total_rows_dash, 4))

For i = 2 To Total_rows_Prod
    For j = 2 To total_rows_dash
        If arr_prodQty5(i, 1) = arr_DashBoard1(j, 1) Then
           arr_DashBoard4(j, 1) = arr_DashBoard4(j, 1) + arr_prodQty31(i, 1) / arr_prodQty4(i, 1)
        End If
    Next j
Next i

ThisWorkbook.Worksheets("Dashboard").Range(Cells(2, 4), Cells(total_rows_dash, 4)) = arr_DashBoard4

(ฉันไม่มีข้อมูลของคุณดังนั้นฉันไม่สามารถตรวจสอบได้ว่ามันใช้งานได้จริงหรือไม่ส่วนใหญ่คุณจะต้องแก้ไขข้อบกพร่องก่อนเรียกใช้)

การใช้พจนานุกรมแทนที่จะเป็นอาร์เรย์เป็นวิธีที่ซับซ้อนกว่าเพื่อให้ได้ผลลัพธ์เดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.