Setting Dynamic Ranges in VBA

2019-09-14 16:25发布

I have the following code below. Instead of using stagnant ranges (i.e., Range("AF9:AF50") & Range(AK9:BI50")) I'm looking to implement a dynamic range that runs the code starting at row 9 through the last row of data for those columns. I've been reading on how to set dynamic ranges but I can't get it to work. Any advice/assistance is greatly appreciated.

Private Sub Worksheet_Change(ByVal target As Range)

Dim cell As Range
Dim controlRng As Range, nRng As Range

Set cell = Range("AK9:BI50")
Set controlRng = Range("AF9:AF50")
Set nRng = Intersect(controlRng, target)

Application.EnableEvents = False

If Not nRng Is Nothing Then
    Select Case target.Value
        Case "No Promotion"
            target.Offset(, 1).Value = Range("M" & target.Row).Value
            target.Offset(, 4).Value = Range("P" & target.Row).Value
            target.Offset(, 9).Value = ""
        Case "Promotion"
            target.Offset(, 1).Value = ""
            target.Offset(, 4).Value = ""
            target.Offset(, 9).Value = 0.07
        Case "Demotion", "Partner", ""
            target.Offset(, 1).Value = ""
            target.Offset(, 4).Value = ""
            target.Offset(, 9).Value = ""
    End Select
End If

If Not Application.Intersect(cell, target) Is Nothing Then
    Select Case target.Column
        Case 37, 39, 43
            target.Offset(, 1).Value = target.Value / Range("V" & target.Row).Value
        Case 38, 40, 44
            target.Offset(, -1).Value = WorksheetFunction.RoundUp((target.Value * Range("V" & target.Row).Value), -2)
        Case 41, 60
            target.Offset(, 1).Value = WorksheetFunction.RoundUp((target.Value * Range("V" & target.Row).Value), -2)
        Case 42, 61
            target.Offset(, -1).Value = target.Value / Range("V" & target.Row).Value
    End Select
End If

Application.EnableEvents = True

End Sub

2条回答
【Aperson】
2楼-- · 2019-09-14 16:46

I'm assuming your problem is dealing with the letter aspect of ranges and trying to make that dynamic? If so the syntax you may be looking for is.

Set MyRange = MySheet.Range(MySheet.Cells(TopRow, LeftCol), MySheet.Cells(LastRow, RightCol))

So For example, these two ranges will be equivalent but the first can be generated dynamically.

TopRow = 1
LeftCol = 2
LastRow = 100
RightCol = 3
Set MyRange = MySheet.Range(MySheet.Cells(TopRow, LeftCol), MySheet.Cells(LastRow, RightCol))

Set MyOtherRange = mysheet.range("B1:C100")

There are several methods to find the last row of a column, some work better in other circumstances then others. Look here https://www.thespreadsheetguru.com/blog/2014/7/7/5-different-ways-to-find-the-last-row-or-last-column-using-vba

I usually use this

LastRow = sht.Cells(sht.Rows.Count, ColumnNumber).End(xlUp).Row
查看更多
Root(大扎)
3楼-- · 2019-09-14 17:08

If I understand the question correctly, the columns and starting rows are static and only a dynamic last row reference is needed.

In Worksheet_Change event:

Set cell = Range("AK9:" & LastRow("BI"))
Set controlRng = Range("AF9:" & LastRow("AF"))

Choose a row number larger than any number of rows your data will likely have (e.g.1000). Then, in the same module:

function LastRow(strColumn as string) as long
  LastRow=range(strColumn & 1000).end(xlup).row
end function

VBA will re-calculate the LastRow every time the Worksheet_Change event is raised, thus making your ranges dynamic.

查看更多
登录 后发表回答