Excel VBA 行取得循環

Excel VBA 行取得循環

我有三張表:「bom」、「MPS」和「DData」。我想做的是先從「MPS」讀取儲存格 A2 的值,然後從「bom」中取得 A 列中具有該值的所有行,並將它們列出到「DData」。

同時,我需要將「MPS」中的 C 列和 D 列中的值提取到對應的行。因此,如果「MPS」儲存格 A2 值中的值與「bom」中的 4 行匹配,則儲存格 C2 和 D2 中的值應放在這 4 行之後。目前這還不能正常運作。

一旦這個循環完成,它應該會移動到“MPS”中的單元格值 A3 等等......下面的程式碼有些工作。我嘗試添加第二個 for 循環以及想到的所有其他內容,但沒有好運。最大的問題是,如果MPS!A2值為 1, A3= 2 並且A4再次為 1,則不會再次列出「bom」中的值。

程式碼最初是基於此:https://stackoverflow.com/a/26912176

Public Sub CommandButton1_Click()

    Dim countRows1 As Long, countRows2 As Long
    countRows1 = 2  'the first row of your dataset in sheet1
    endRows1 = 50   'the last row of your dataset in sheet1
    countRows2 = 2  'the first row where you want to start writing the found rows
    For j = countRows1 To endRows1

        Dim keyword As String: keyword = Sheets("MPS").Cells("A2, A100").Value
        If Sheets("bom").Range("A2, A100").Value = keyword Then
            Sheets("DData").Rows(countRows2).Value = Sheets("bom").Rows(j).Value
            Sheets("DData").Rows(countRows2).Cells(6).Value = Sheets("MPS").Rows(countRows2).Cells(3).Value
            Sheets("DData").Rows(countRows2).Cells(7).Value = Sheets("MPS").Rows(countRows2).Cells(4).Value
            countRows2 = countRows2 + 1


        End If

    Next j

End Sub

我的想法是,這肯定需要兩個循環,但我就是無法讓它工作。

我無法發布圖像,但我會嘗試在下面更好地說明需要什麼和發生什麼。

工作表「bom」結構與資料(範圍 A1:E7):

id       desc   id_part   desc_part   qty
30010   build1  10200     part1        1
30010   build1  23002     part2        3
30010   build1  21003     part3       500
30010   build1  21503     part4       400
20010   build2  10210     part5       100
20010   build2  10001     part6        5

工作表「MPS」結構與資料(範圍 A1:D4):

 id     desc    week    batches
30010   build1  1         2
20010   build2  2         4
30010   build1  2         0

工作表「DData」結構(範圍 A1:H3)以及代碼 panhandel 傳回的內容:

id      desc    id_part    desc_part    qty     week     batches    total(=qty*batches)
30010                                             1          2  
30010                                             2          0  

我的目標是這樣的:

id      desc    id_part   desc_part     qty     week     batches    total (=qty*batches)
30010   build1  10200     part1          1       1          2   
30010   build1  23002     part2          3       1          2   
30010   build1  21003     part3         500      1          2   
30010   build1  21503     part4         400      1          2   
20010   build2  10210     part5         100      2          4   
20010   build2  10001     part6          5       2          4
30010   build1  10200     part1          1       2          0   
30010   build1  23002     part2          3       2          0   
30010   build1  21003     part3         500      2          0   
30010   build1  21503     part4         400      2          0

....例如,H2 的值為 E2 * G2。

*** 我試著改變

Sheets("DData").Range("A" & countRows2).Value = Sheets("bom").Range("A" & lCount).Value

Sheets("DData").Rows(countRows2).Value = Sheets("bom").Rows(lCount).Value

例如,但 Excel 開始嚴重崩潰。使用範圍而不是行更明智嗎?

答案1

編輯:一個循環逐行遍歷 MPS 列 A,第二個循環將每個 MPS 列 A 值與所有「bom」列 A 值進行比較。一旦找到匹配項,每個單元格都會複製到DData 表(我確信有一種更快的方法可以做到這一點,但這很好地說明了發生的情況),並且H 列得到一個公式來計算總數。

這些選項卡的設定與您現在的設定相同,並產生您期望/需要的結果。

Sub Button1_Click()
    Dim countRows2 As Long
    countRows2 = 2 'the first row where you want to start writing the found rows

    Dim szMPSValues As Variant
    Dim szbomValues As Variant
    Dim lCount As Long
    Dim lCountbom As Long
    Dim MPSRng As Range
    Dim bomRng As Range
    Dim szConcatString As Variant
    Dim strKeyword As String

    'gets range of used cells
    Set MPSRng = Intersect(Columns("A").Cells, Worksheets("MPS").UsedRange)
    If MPSRng Is Nothing Then MsgBox "Nothing to do"

    'have to switch sheets to set the second loop's range of "bom" values
    Worksheets("bom").Activate
    Set bomRng = Intersect(Columns("A").Cells, Worksheets("bom").UsedRange)
    Worksheets("MPS").Activate

    'saves range values into arrays
    szMPSValues = MPSRng.Value
    szbomValues = bomRng.Value

    'double check a to be sure its an array and of proper size
    If Not IsArray(szMPSValues) Then ReDim a(1, 1): szMPSValues = MPSRng.Value

    'loop through array concatenating cell values with a space after cell value
    'NOTE: Changed this to start at 2 in case you have a header row**
    For lCount = 2 To UBound(szMPSValues)
        strKeyword = Sheets("MPS").Range("A" & lCount).Value            'gets MPS.A2, MPS.A3, etc

        For lCountbom = 2 To UBound(szbomValues)
            If Sheets("bom").Range("A" & lCountbom).Value = strKeyword Then    'compares to bom.A2, bom.A3, etc

                    Sheets("DData").Range("A" & countRows2).Value = Sheets("bom").Range("A" & lCountbom).Value
                    Sheets("DData").Range("B" & countRows2).Value = Sheets("bom").Range("B" & lCountbom).Value
                    Sheets("DData").Range("C" & countRows2).Value = Sheets("bom").Range("C" & lCountbom).Value
                    Sheets("DData").Range("D" & countRows2).Value = Sheets("bom").Range("D" & lCountbom).Value
                    Sheets("DData").Range("E" & countRows2).Value = Sheets("bom").Range("E" & lCountbom).Value
                    Sheets("DData").Range("F" & countRows2).Value = Sheets("MPS").Range("C" & lCount).Value
                    Sheets("DData").Range("G" & countRows2).Value = Sheets("MPS").Range("D" & lCount).Value
                    Sheets("DData").Range("H" & countRows2).Formula = "=$F" & countRows2 & "*$G" & countRows2
                    countRows2 = countRows2 + 1
            End If
        Next lCountbom
    Next lCount
End Sub

相關內容