有没有更有效的方式编写以下内容:
Private Sub ConvertDatesToValue_Click()
Dim Rng1 As Range, Rng2 As Range, Rng3 As Range, Rng4 As Range
Set Rng1 = Range("Q8:Q12")
Set Rng2 = Range("Q16:Q20")
Set Rng3 = Range("T8:T12")
Set Rng4 = Range("T16:T20")
Rng1.Value = Rng1.Value
Rng2.Value = Rng2.Value
Rng3.Value = Rng3.Value
Rng4.Value = Rng4.Value
End Sub
它的外观和感觉有点过时。
答案 0 :(得分:4)
尝试直接还原值。
Private Sub ConvertDatesToValue_Click()
With Worksheets("sheet9")
.Range("Q8:Q12") = .Range("Q8:Q12").Value
.Range("Q16:Q20") = .Range("Q16:Q20").Value
.Range("T8:T12") = .Range("T8:T12").Value
.Range("T16:T20") = .Range("T16:T20").Value
End With
End Sub
您真的应该知道您正在使用的工作表。
答案 1 :(得分:4)
Private Sub ConvertDatesToValue_Click()
因此,我们正在查看控件的Click
处理程序,大概是工作表上的ActiveX按钮,在这种情况下,我们位于该工作表的代码隐藏模块中。
该按钮意味着调用一个命令,该命令将在包含日期的特定单元格区域中转换公式及其值。
在给定Range.Value
的情况下,我将从负责将Range
分配到自身的过程开始:
Public Sub FreezeFormulaResult(ByVal target As Range)
target.Value = target.Value
End Sub
接下来,我们需要确定将传递给该过程的范围。
Dim Rng1 As Range, Rng2 As Range, Rng3 As Range, Rng4 As Range Set Rng1 = Range("Q8:Q12") Set Rng2 = Range("Q16:Q20") Set Rng3 = Range("T8:T12") Set Rng4 = Range("T16:T20")
为避免隐式Variant
陷阱而为这些变量中的每一个声明显式类型的荣誉。
它的外观和感觉有点僵硬
这是因为变量具有该数字后缀。 Rng1...RngN
确实是一种代码气味:它是解决需要一堆东西 的问题的肮脏解决方案。
通常,更优雅的解决方案是使用数组:
Dim ranges As Variant
ranges = Array(Range("Q8:Q12"), Range("Q16:Q20"), Range("T8:T12"), Range("T16:T20"))
有很多方法可以给猫皮毛,但是联合的脱节Range
1 不会产生预期的结果。因为需要4个不同的区域,所以需要4个不同的操作。
操作方式点击处理程序需要提取范围,取决于该处理程序在哪里。
如果我们正在查看MSForms.CommandButton
上的Worksheet
(ActiveX)按钮,则单击处理程序位于我们要从中获取单元格的同一张纸中。
在那种情况下,我们可以处理当前对象Me
-实际上,通过不限定Range
的调用,我们可以精确地完成 隐式。
换句话说:
Set Rng1 = Range("Q8:Q12")
表示:
Set Rng1 = Me.Range("Q8:Q12")
在标准模块中没有按钮Click
处理程序,但是如果要在一个模块中编写它:
Set Rng1 = Range("Q8:Q12")
然后这将是隐式的:
Set Rng1 = ActiveSheet.Range("Q8:Q12")
请注意区别:这就是为什么隐式代码是邪恶的,而上下文是一切的原因-通过编写显式代码,您可以通过使上下文 local 而不是 ambient 来减轻认知负担。 em>。
我们需要能够为我们提供Range
对象数组的某物。让我们尝试抽象-它可能是工作表代码背后的公共财产:
Public Property Get ImportantDateRanges() As Variant
ImportantDateRanges = Array( _
Me.Range("Q8:Q12"), _
Me.Range("Q16:Q20"), _
Me.Range("T8:T12"), _
Me.Range("T16:T20"))
End Property
现在按钮的Click
处理程序不再需要关心单元格是什么,并且抽象级别就是完美的选择:
Private Sub ConvertDatesToValues_Click()
FreezeDateFormulas
End sub
Private Sub FreezeDateFormulas()
Dim dateRanges As Variant
dateRanges = Me.ImportantDateRanges
Dim i As Long
For i = LBound(dateRanges) To UBound(dateRanges)
FreezeFormulaResult dateRanges(i)
Next
End Sub
如果我们在MSForms.CommandButton
上查看UserForm
,则它是完全相同的ActiveX按钮... but it's an entirely different story,因为虽然您没有{{1 }}实例(Excel确实),您确实拥有一个Worksheet
实例-这就带来了太多的含义,在这里无法解释(该链接指向我写的一篇有关表单如何不起作用的文章不需要进行表演)。
答案 2 :(得分:4)
您可以遍历4个区域:
Dim r As Range
For Each r In Range("Q8:Q12,Q16:Q20,T8:T12,T16:T20").Areas
r = r.Value
Next