简体   繁体   中英

Dynamic Column Copy/Paste based off of Data Validation List

At the end of every month, we copy/paste forecast sales (where the formulas are) as a hardcode into other columns for reference and reconciliation purposes.
For example, copy Column D (January) through Column F (march) into column Q (Jan hardcoded) through S (March hardcoded)

I'm trying to modify my code so the user can select from two data validation dropdowns which month range (eg Jan - Mar) on each of the forecast tabs to copy/paste as values.
For example, below is something I've added to copy/paste based on the # rows for a formula.

Dim LastRow As Long
With ActiveSheet
    LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Range("T1") = "PPU"
Range("T2") = "=S2/R2"
Range("T2").Copy
Range("T2:T" & LastRow).Select `dynamic row
Selection.PasteSpecial xlFormulas
Range("T:T").Copy
Range("T:T").PasteSpecial xlPasteValues

With my code above, is it possible to alter this so, instead of " & Lastrow", I keep the rows static but make the columns to copy variable, so for lack of a better term firstMonth & secondMonth.
The columns to select would be based off two named ranges where the user chooses from two data validation lists (firstMonth & secondMonth) with each column being assigned a column "letter" (eg Jan is column D, Feb Column E, etc.)

Without being dynamic, it would be something like:

Range("D12:F19").Copy
Range("Q12").PasteSpecial xlValues

But I'd like to have the user select with months, via a data validation list, to have hardcoded by choosing a beginning month (firstMonth) and ending month (secondMonth)

Something along the lines of:

Range(firstMonth &"12": secondMonth & "19").Copy `firstMonth in theory is the column letter so, "D12" and secondMonth is the second column letter (F12)

Range("pasteFirstMonth &"12").PasteSpecial xlValues `the firstMonth will be paired with the column letter, say "Q" where it will paste those values.  A second column range isn't needed here since only the copied range will paste, not overlapping anything else.  This is the "hardcoded" area.

Update: Slightly reconfigured Tim's answer below.

Sub copyColumns()

Dim months, m1, m2, sht

    months = Split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", ",")
    Set sht = ActiveSheet
    
    m1 = Application.Match(sht.Range("Month1").Value, months, 0)
    m2 = Application.Match(sht.Range("Month2").Value, months, 0)
    
    sht.Range(sht.Cells(8, 3 + m1), sht.Cells(16, 3 + m2)).Copy
    sht.Range(sht.Cells(8, 16 + m1), sht.Cells(16, 16 + m2)).PasteSpecial xlValues
    
End Sub

Something like this should work:

Sub DoCopy()

    Dim months, m1, m2, sht

    months = Split("Jan,Feb,Mar,Apr,May,June,July,Aug,Sept,Oct,Nov,Dec", ",")
    Set sht = ActiveSheet

    m1 = Application.Match(sht.Range("Month1").Value, months, 0)
    m2 = Application.Match(sht.Range("Month2").Value, months, 0)

    If Not IsError(m1) And Not IsError(m2) Then
        'copy range - use offset (3 here) depending on where months begin
        sht.Range(sht.Cells(12, 3 + m1), sht.Cells(19, 3 + m2)).Copy
        'etc
    End If

End Sub

You can prompt the user for selecting the desired months and you can use the Selection object, like

Set rng=Selection
Cells(rng.row, rng.column) gives you the top left cell of the selection, 
rng.Columns.Count gives you the number of columns, etc.

From a users perpective it is much easier to select an area on the screen and press a button than entering values or selecting them from list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM