การคัดลอกช่วงโดยใช้เกณฑ์ Combo Box


2

ฉันพยายามที่จะคัดลอกช่วงที่ตรงกับสองเกณฑ์จากสองกล่องคำสั่งผสมบนแบบฟอร์มผู้ใช้

ComboBox1 มีเกณฑ์ 1 สาขา
ComboBox2 มีเกณฑ์ 2 ไตรมาส

คอลัมน์Aต้องตรงกับเกณฑ์สาขาและแถว1ต้องตรงกับเกณฑ์ไตรมาส

รูปภาพของช่วง

ฉันไม่สามารถใช้รหัสได้อย่างถูกต้อง เพียงคัดลอกข้อมูลจากคอลัมน์2และไม่ได้ตรวจสอบทั้งแถวสำหรับเกณฑ์ไตรมาส

ตัวอย่างเช่นถ้าฉันเลือกสาขาเพิร์ลและไตรมาสที่ 1 รหัสควรคัดลอก "แอปเปิ้ล" และ "8"

นี่คือรหัส:

Private Sub CommandButton1_Click()

Dim LastRow As Long, i As Long, ws2 As Worksheet

With Worksheets("Sheet1")
    LastRow = .Range("A" & .Rows.Count).End(xlUp).Row

    For i = 2 To LastRow

        If .Cells(i, 1) = ComboBox1 And .Cells(1, 2) = ComboBox2 Then
            With Worksheets("Sheet4")
                .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0) = _
                     Worksheets("Sheet1").Cells(i, 2).Value
            End With
        End If

    Next i
End With
Unload Me

End Sub

มีคำถามที่ดีกว่ารุ่นก่อนมาก! คุณสามารถแก้ไขได้แทนที่จะสร้างขึ้นมาใหม่
robinCTS

@JoseCortez คุณมีข้อมูลในสองแผ่นงานที่แตกต่างกันหรือไม่ 1 ถึง 4 หรือในแผ่นงานเดียวเท่านั้นเนื่องจากฉันพบWith Worksheets("Sheet1")& ลงไปที่บรรทัดคือWith Worksheets("Sheet4")อะไร?
Rajesh S

คำตอบ:


2

ปัญหาหลักของโค้ดคือแม้ว่าคุณจะวนลูปไปตามแถวอย่างถูกต้อง แต่คุณไม่ได้วนลูปผ่านคอลัมน์

การเพิ่มวงในจะแก้ปัญหานี้ อย่างไรก็ตามทางออกที่ดีกว่าคือการใช้ฟังก์ชั่นแผ่นงานMATCH()เพื่อค้นหาแถวที่ตรงกันและวนซ้ำผ่านคอลัมน์แทน:

Private Sub CommandButton1_Click()

Dim LastColumn As Long
Dim i As Long

With Worksheets("Sheet1")
    LastColumn = .Cells(1, Columns.Count).End(xlToLeft).Column
    Dim lngMatchingRow As Long
    lngMatchingRow = Excel.WorksheetFunction.Match(ComboBox1.Value, .Range("A:A"), 0)

    For i = 2 To LastColumn

        If .Cells(1, i).Value2 = ComboBox2.Value Then
            With Worksheets("Sheet4")
                .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0) = _
                     Worksheets("Sheet1").Cells(lngMatchingRow, i).Value2
            End With
        End If

    Next i
End With
Unload Me

End Sub

โปรดทราบว่าฉันมีเสรีภาพในการแก้ไขส่วนอื่น ๆ ของรหัสเพื่อปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุด:

  • ตัวแปรควรถูกประกาศหนึ่งรายการต่อบรรทัด
  • ตัวแปรควรถูกประกาศว่าใกล้เคียงกับการใช้งานครั้งแรกเท่าที่จะเป็นไปได้
  • .Value2การแสดงจะถูกนำมาใช้เสมอ.Valueเมื่อต้องการดึงข้อมูลจากสเปรดชีต
  • แทนที่จะต้องพึ่งพาคุณสมบัติเริ่มต้นควรระบุไว้อย่างชัดเจนเช่นComboBox1.Valueแทนที่จะเป็นComboBox1

ตอนนี้ถ้าฉันกำลังเขียนโค้ดตั้งแต่เริ่มต้นและหาก Quarters รับประกันว่าจะถูกจัดกลุ่มเข้าด้วยกันฉันจะแจกจ่ายให้กับการวนซ้ำคอลัมน์เช่นกัน

แต่ฉันจะใช้MATCH()และCOUNTIF()ค้นหาการ จำกัด คอลัมน์และคัดลอกข้อมูลทั้งหมดในครั้งเดียว:

Private Sub CommandButton1_Click()
        Dim ƒ As Excel.WorksheetFunction: Set ƒ = Excel.WorksheetFunction

  With Worksheets("Sheet1")
    Dim lngMatchingRow As Long
    lngMatchingRow = ƒ.Match(ComboBox1.Value, .Range("A:A"), 0)
    Dim lngStartCol As Long
    lngStartCol = ƒ.Match(ComboBox2.Value, .Range("1:1"), 0)
    Dim lngColCount As Long
    lngColCount = ƒ.CountIf(.Range("1:1"), "Q1")

    Worksheets("Sheet4").Cells(Rows.Count, "A").End(xlUp).Offset(1).Resize(lngColCount) _
    = ƒ.Transpose(.Cells(lngMatchingRow, lngStartCol).Resize(1, lngColCount).Value2)

  End With
  Unload Me

End Sub

ที่ดีเยี่ยม! รหัสของคุณทำสิ่งที่ฉันต้องการให้ทำ ขอขอบคุณ!!
Jose Cortez

@JoseCortez ไม่เป็นไร :) อย่าลืมตอนนี้คุณมี 15+ ชื่อเสียงแล้วคุณสามารถโหวตคำตอบใด ๆ (หรือคำถาม) รวมถึงคำตอบที่คุณยอมรับ ;-)
robinCTS

1
@JoseCortez ฉันได้เพิ่มโค้ดที่ไม่ใช่ลูปถ้าคุณสนใจ
robinCTS

มีวิธีการวนรอบข้อมูลตามแถวหรือไม่ ฉันอัพโหลดภาพสิ่งที่ฉันพยายามจะทำ ถ้า ComboBox1 เป็น "ตัวอย่าง 1" และ ComboBox 2 เป็น "Q1" ดังนั้นควรคัดลอก 12,150 และ 10,750 วิธีแก้ปัญหาแรกของคุณใช้งานได้ แต่ตอนนี้ฉันแยกข้อมูลออกไปต่างกัน ขอบคุณสำหรับความช่วยเหลือของคุณ!
Jose Cortez

@JoseCortez ใช่ ตามที่อธิบายไว้ในตอนต้นของคำตอบของฉันการเพิ่มลูปภายในจะใช้งานได้และในความเป็นจริงเป็นสิ่งสำคัญหากมีแถวที่ตรงกันหลายแถวรวมถึงคอลัมน์ ตัวอย่างเช่นการใช้รหัสแรกของฉันการแก้ปัญหาที่ง่ายที่สุดคือการวนซ้ำแถวทั้งหมดเมื่อพบคอลัมน์ที่ตรงกัน เทคนิคที่เร็วกว่าและก้าวหน้ากว่าคือการใช้การMATCH()เริ่มต้นที่แถวล่างการแข่งขันก่อนหน้าเพื่อค้นหาการแข่งขันครั้งต่อไป §ที่ถูกกล่าวว่านี่เป็นคำถามใหม่ไม่ใช่การแก้ไขในปัจจุบัน (ซึ่งฉันได้เปลี่ยนกลับ) ลองใช้วิธีแก้ปัญหาและ…
robinCTS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.