簡體   English   中英

根據多個條件有效地復制和粘貼單元格塊

[英]Efficiently copy and paste block of cells based on multiple criteria

我有一個很大的數據集,並想根據另一張表的一組條件查詢列。 我有一個有效的方法,該方法使用循環查找起點,並使用循環查找終點以獲取所需的行,但這很慢。

我想避免find函數所需的唯一列,因為這會使數據的結尾很難查找。 我已經考慮過嘗試使用某種FindAll函數,但似乎無法弄清楚如何啟動它。

我已經看過很多有關過濾器的內容,但是這些似乎可以通過復制整個行來起作用,我想避免這種情況。

就像我說的那樣,這段代碼可以完美地運行,但是它會減慢速度,因為它將在模型運行期間運行1000次。 我也有幾個類似的潛艇,希望能夠將解決方案

Sub Join(CI, FI, FSD)
Dim a, b, LastRow As Long

LastRow = Fcst_Cust.Range("a1048576").End(xlUp).Row + 1

'find all values for that customer ID for dates greater than the forecast start date and copy onto forecast tab.

    a = 3
    b = 2

    Do Until ((Raw_IFcst.Cells(b + 1, 2) = CI) And (Raw_IFcst.Cells(b + 1, 3) >= FSD))
        a = a + 1
        b = b + 1
    Loop
    Do Until Raw_IFcst.Cells(b + 1, 2) <> CI
        b = b + 1
    Loop

    Raw_IFcst.Range("A" & a & ":AZ" & b).Copy
        Fcst_Cust.Range("C" & LastRow).PasteSpecial xlPasteValues
    Raw_IFcst.Range("BB" & a & ":CW" & b).Copy
        Fcst_Cust.Range("BG" & LastRow).PasteSpecial xlPasteValues

End Sub

Range對象的AdvancedFilter方法可能是最有效的...,而且它絕對不需要復制完整的行。 您可以選擇所需的列。

但是,我重構了您的代碼,而沒有利用AdvancedFilter。 這應該明顯更快:

Sub Join_(CI, FI, FSD)
    Dim a&, b&, LastRow&, v

    LastRow = Fcst_Cust.[a1048576].End(xlUp).Row + 1

    a = 3
    b = 2

    With Raw_IFcst
        v = .Cells(1, 2).Resize(.[b1048576].End(xlUp).Row, 2).Value2

        Do
            If If v(b + 1, 1) = CI Then
                If v(b + 1, 2) >= FSD Then
                    Exit Do
                End If
            End If
            a = a + 1
            b = b + 1
        Loop

        Do Until v(b + 1, 1) <> CI
            b = b + 1
        Loop

        .Range("A" & a & ":AZ" & b).Copy
            Fcst_Cust.Range("C" & LastRow).PasteSpecial xlPasteValues

        .Range("BB" & a & ":CW" & b).Copy
            Fcst_Cust.Range("BG" & LastRow).PasteSpecial xlPasteValues
    End With

End Sub

注意:我尚未對此進行測試,請這樣做。

注意:我已經更改了Sub的名稱。 除非您確實希望覆蓋該功能,否則將現有VBA函數的名稱用作過程的名稱不是一個好習慣。

注意:我更改了Dim行。 您將ab作為變體,但它們應為long。

注意:使程序運行最慢的原因是逐行讀取第2列和第3列。一次讀取和寫入一個單元格可能是Excel開發人員可用的最無效的過程。 我的代碼所做的是將第2列和第3列的使用部分轉移到數組v 這非常快,並且訪問數組中的各個元素(與單個單元相反)非常快。

注意:我更改了第一個Do While循環。 VBA表達式求值不會使多個子句短路。 因此,如果clause 1clause 2必須為真(如您的情況),那么即使clause 1為false, clause 2也會被求值。 這是浪費,零收益的加工。 在您的原始設置中,由於讀取單個細胞的速度較慢,浪費的廢物被放大了。 優化是將子句分成幾行。 這樣,如果第一個失敗,則永遠不會評估第二個。 通過將最有可能失敗的子句放在第一行,可以進一步體現這一概念。 我不知道哪種最有可能在您的方案中失敗,因此我將您的第一條放在第一行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM