我是VBA的新手,我开始做一些基本的编码。
我目前的最终目标是根据两个经过数据验证的单元格的输入,将表格中的单元格清零。
我目前有一张表,我已成功实现了我想要做的事情,但代码很长,我相信它可以通过使用Find函数来简化。在实施此变通方法之前,我尝试实施Find几个小时。
用户通过单元格B4中的验证列表选择当前的预测月份。然后,他们可以通过在单元格B5中选择是/否来选择将所需单元“清零”。几个月从B7:M7开始。我最初的目标是让VBA从B4中选择一个月,在B7中找到那个月:M7,返回该列,然后使用列数据转到第15行并将该单元归零。但是,我找不到合适的方法将其编码到find函数中而不会导致编译错误。
以下是我认为可以简化的当前代码:
Private Sub Worksheet_Change_B(ByVal Target As Range)
If Target.Address(False, False) = "B5" Then
If Range("B5").Value = "Yes" Then
If Range("B4").Value = "Oct" Then
Range("B15").Value = "0"
ElseIf Range("B4").Value = "Nov" Then
Range("C15").Value = "0"
ElseIf Range("B4").Value = "Dec" Then
Range("D15").Value = "0"
ElseIf Range("B4").Value = "Jan" Then
Range("E15").Value = "0"
ElseIf Range("B4").Value = "Feb" Then
Range("F15").Value = "0"
ElseIf Range("B4").Value = "Mar" Then
Range("G15").Value = "0"
ElseIf Range("B4").Value = "Apr" Then
Range("H15").Value = "0"
ElseIf Range("B4").Value = "May" Then
Range("I15").Value = "0"
ElseIf Range("B4").Value = "Jun" Then
Range("J15").Value = "0"
ElseIf Range("B4").Value = "Jul" Then
Range("K15").Value = "0"
ElseIf Range("B4").Value = "Aug" Then
Range("L15").Value = "0"
ElseIf Range("B4").Value = "Sep" Then
Range("M15").Value = "0"
End If
ElseIf Range("B5").Value = "No" Then
If Range("B4").Value = "Oct" Then
Range("B15").Value = Range("B35").Value
ElseIf Range("B4").Value = "Nov" Then
Range("C15").Value = Range("C35").Value
ElseIf Range("B4").Value = "Dec" Then
Range("D15").Value = Range("D35").Value
ElseIf Range("B4").Value = "Jan" Then
Range("E15").Value = Range("E35").Value
ElseIf Range("B4").Value = "Feb" Then
Range("F15").Value = Range("F35").Value
ElseIf Range("B4").Value = "Mar" Then
Range("G15").Value = Range("G35").Value
ElseIf Range("B4").Value = "Apr" Then
Range("H15").Value = Range("H35").Value
ElseIf Range("B4").Value = "May" Then
Range("I15").Value = Range("I35").Value
ElseIf Range("B4").Value = "Jun" Then
Range("J15").Value = Range("J35").Value
ElseIf Range("B4").Value = "Jul" Then
Range("K15").Value = Range("K35").Value
ElseIf Range("B4").Value = "Aug" Then
Range("L15").Value = Range("L35").Value
ElseIf Range("B4").Value = "Sep" Then
Range("M15").Value = Range("M35").Value
End If
End If
End If
End Sub
我最初用Find函数思考的是这样的,但我无法正确编译。
Sub Test()
Dim rFind As Range
If Target.Address(False, False) = "B5" Then
If Range("B5").Value = "Yes" Then 'If the user wants to zero out the cell on row 15
With Range("B7:M7") 'Range of Months
Set rFind = .Find(What:=("B4"), LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False)
Range("rFind.Column,15").Value = "0" 'Set Value of cell in row 15 of referenced column to zero
End With
If Range("B5").Value = "No" Then 'If the user doesn't want to zero out cell on row 15
With Range("B7:M7") 'Range of Months
Set rFind = .Find(What:=("B4"), LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False)
Range("rFind.Column,15").Value = Range("rFind.Column,35").Value 'Pulls in Previous Value
End With
End If
End Sub
我正在走上正轨吗?如何在我想要更改的单元格地址中引用月份列?
答案 0 :(得分:3)
这些语句中的语法错误:
Range("rFind.Column,15").Value = 0
Range("rFind.Column,15").Value = Range("rFind.Column,35").Value
应该是:
Cells(15, rFind.Column).Value = 0
Cells(15, rFind.Column).Value = Cells(35, rFind.Column).Value
此处出现另一种语法错误:
What:=("B4"), ...
应该是
What:=Range("B4").Value, ...
为了完整起见,您可以通过以下方式简化第一个版本:
Private Sub Worksheet_Change_B(ByVal Target As Range)
' we're only interested when cell B5 changes
If Target.address <> "$B$5" Then Exit Sub
' First we will get the month's number from its name. We use the Month
' method of VBA but it needs a date. so we append a 1 to the month (i.e. Sep 1)
Dim col As Long
col = Month(Range("B4").value & " 1")
' Getting the column. Since First cell is in column 2 (B) we start at column 2
' Month 10 (Oct) comes first so we count from that using modulo
col = 2 + ((col + 2) Mod 12) ' since you start with Oct. at column B
' Finally we set the value at row 15 according to cell B5 (Target)
' We can shorten the If statement using IIF(condition, trueValue, falseValue)
Cells(15, col).value = IIf(Target.value = "Yes", 0, Cells(35, col).value)
End Sub
答案 1 :(得分:2)
一些Select Case语句和一些基本数学可以快速完成所有条件。找到模式后,某些日期函数会达到顺序月份,并根据您的偏移量进行调整。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(False, False) = "B5" Then
On Error GoTo Safe_exit
Application.EnableEvents = False
If LCase(Range("B5").Value2) = "yes" Then
Select Case LCase(Range("B4").Value2)
Case "jan", "feb", "mar", "apr", "jun ", "jul", "aug", "sep", "oct", "nov", "dec"
Cells(15, Month(DateSerial(2017, Month(DateValue("1-" & Range("B4").Value2)) + 3, 1)) + 1) = 0
Case Else
'do nothing
End Select
ElseIf LCase(Range("B5").Value2) = "no" Then
Select Case LCase(Range("B4").Value2)
Case "jan", "feb", "mar", "apr", "jun ", "jul", "aug", "sep", "oct", "nov", "dec"
Cells(15, Month(DateSerial(2017, Month(DateValue("1-" & Range("B4").Value2)) + 3, 1)) + 1) = _
Cells(35, Month(DateSerial(2017, Month(DateValue("1-" & Range("B4").Value2)) + 3, 1)) + 1).Value
Case Else
'do nothing
End Select
End If
End If
Safe_exit:
Application.EnableEvents = True
End Sub
不要担心限定父工作表。您位于工作表代码表的私有子目录中。假定任何不合格的范围或单元格引用属于代码表的工作表(有关详细信息,请参阅Is the . in .Range necessary when defined by .Cells?)。
答案 2 :(得分:0)
我对你的月份序列不太确定。 你可以尝试:
Private Sub Worksheet_Change_B(ByVal Target As Range)
If Target.address <> "$B$5" Then Exit Sub
With Range("B7:M7").Find(What:=Range("B4").Value, lookin:=xlValues, lookAt:=xlWhole)
Cells(15, .Column).value = IIf(Target.value = "Yes", 0, Cells(35, .Column).value)
End With
End Sub