我想获得一些反馈如何编写我想要的VBA模块。 在我的文件中,我有多个列,当从外部源(Bloomberg)收集新数据时,值会发生变化。接下来,如果这些范围中的一个值大于两个始终相同的单元格的乘积($ A $ 1和$ A $ 2),我想收到一条消息。另外,我有多张纸,所以我想确保该模块适用于每张纸。
在搜索互联网和Stackoverflow之后,我想出了两个选择:
第一种选择:
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
With Sh
Set r1 = Sh.Range("N1:N50")
Set r2 = Sh.Range("AA1:AA50")
Set r3 = Sh.Range("AN1:AN50")
Set r4 = Sh.Range("BA1:BA50")
Set r5 = Sh.Range("BN1:BN50")
Set r6 = Sh.Range("CA1:CA50")
Set myMultipleRange = Union(r1, r2, r3, r4, r5, r6)
Dim myMultipleRange as Range
Dim Cell as Range
For Each Cell in myMultipleRange.Cells
With Cell
If .Value2 > 0.1 * $A$1 * $A$2 Then
MsgBox ("Ticker: " & Sh.Name & ", Today's volume in the " & Cells(row,column -1) " & " serie is " & Cells" & " contracts")
然而,当我探索互联网时,我看到类似的问题,答案包括“相交”功能。据我所知,Intersect将返回一个Range对象,它表示两个或更多范围的交集。但是,与我的模块有什么区别?哪种方法更快?我想要最快的模块,因为我的文件很大!
我尝试使用Intersect函数编写第二个模块
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
With Sh
Dim r1, r2, r3, r4, r5, r6, my MultipleRange as Range
Set r1 = Sh.Range("N1:N50")
Set r2 = Sh.Range("AA1:AA50")
Set r3 = Sh.Range("AN1:AN50")
Set r4 = Sh.Range("BA1:BA50")
Set r5 = Sh.Range("BN1:BN50")
Set r6 = Sh.Range("CA1:CA50")
Set myMultipleRange = Union(r1, r2, r3, r4, r5, r6)
If Target.Value > (0.1 * sh.Range("A1").Value * sh.Range("A2").Value
If Not Intersect(Target, myMultipleRange) Is Nothing Then
MsgBox ("Ticker: " & Sh.Name & ", Today's volume in the " & Cells(row,column -1) " & " serie is " & Cells" & " contracts
您更喜欢哪种设置,您是否看到了改进的空间?
非常感谢帮助!
答案 0 :(得分:0)
我希望这些示例只是伪代码并向您展示解决方案。如果这是有效的VBA代码,请参阅我对以下错误的说明
Sub Workbook_SheetCalculate(ByVal Sh As Object)
' Assign range to an array for speed, could just use the range object in a similar way
Dim myRange As Range
Dim myArray As Variant
Set myRange = Sh.Range("N1:N50,AA1:AA50,AN1:AN50,BA1:BA50,BN1:BN50,CA1:CA50")
myArray = myRange.Cells
' Just calculate the product once
Dim product As Double
product = Sh.Range("A1").Value * Sh.Range("A2").Value
' Loop through range, message if value is greater than product
Dim n As Long
For n = 1 To UBound(myArray)
If myArray(n, 1) > product Then
MsgBox "Sheet name: " & Sh.Name & ", Cell address: " & myRange.Cells(n).Address
End If
Next n
End Sub
请注意,您不需要与范围的交集或并集有任何关系,只需将它们全部列在一个范围对象中即可...
弹出多个消息框对用户不友好,特别是如果您的“文件很大”并且可能存在很多消息框。我建议将所有需要的地址存储在一个字符串中,然后在工作簿的某处输出一个字符串。
错误:还有其他一些小问题,但每个问题都会导致您的sub出现致命错误。
End Sub
,End With
,End If
的块和if结尾。 Next loopvariable
结尾。 row
和column
。 $A$1
Sh.Range("A1").Value
MsgBox
除非您将返回的值分配给某些内容,否则不会在括号中包含字符串,只需使用MsgBox "my message"
而不是MsgBox ("my message")
With Sh
时,您无需使用Sh.
开始任何操作,只需使用.
,例如Set r1 = .Range("A1")
。这不会导致错误,但会使With
毫无意义。