当目标单元格通过表单控件选项button更改时,VBAmacros不会触发

我简直就是用VBA弄湿了我的脚,因为这是我的第一个macros。 经过几个小时的search,我似乎无法find一个答案,有一个解决scheme,为我工作,所以我在这里。

在Sheet3上,我有3个选项button在一个combobox中链接到Sheet4上的单元格“B18”(如果你愿意,Sheet4对用户是隐藏的,后台是隐藏的)。 当select了三个选项button中的任何一个时,“Sheet4!B18”会被更新(例如1,2或3)。 我想要发生的是根据“Sheet4!B18”中的值改变“Sheet3!B17”,或者实际上: IF('Sheet4!B18'=2,SET('Sheet3!B17'="Some Text Here:"),SET('Sheet3!B17'="0%")) ,但仍允许用户在”Sheet3!B17“中input。 我有以下代码在Sheet4上的一个VBAmacros:

 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Worksheet.Range("B18") = 2 Then Worksheets("Sheet3").Range("B17") = "Some Text Here:" Else Worksheets("Sheet3").Range("B17") = "0%" End If End Sub 

如果我手动更新“Sheet4!B18”,那么macros将被触发并显示所需的结果。 如果使用Sheet3上的3个选项button中的任何一个,即使目标单元格正在更新,macros也不会被触发。

在我的search我似乎无法find具体的东西,但从我可以告诉“Worksheet_Change”function没有看到从窗体控制单元格的变化,因为链接单元格的更改被视为“重新计算”,就好像它是从一个公式。 我不知道这是多么正确,但我的search导致我相信,我将需要在3个button和/或组框中分配的另一个macros,当其中任何一个被选中/改变,它会以某种方式触发工作的macros在Sheet4上。

我想也许我可以创build一个新的macros,我将分配给组框或选项button本身,所以我试过了,不能得到任何工作。 我试着将上面的macros代码添加到另一个子Sub mode()并只分配给组框,然后只有button,但在任何情况下都没有发生。 我继续尝试调整代码,以防万一引用不正确,但不pipe我如何指定引用,都没有改变。 我没有收到任何错误消息,但除非手动更改“Sheet4!B18”中的值,否则不会触发任何错误消息。

有没有办法让我在Sheet4上工作的第一个macros触发改变目标单元格值的选项button,就像强迫它只能看到一个特定的单元格进行更改一样? 我坚持做的另一个macros的button和/或组框来触发Sheet4上的macros? 我是否过度复杂这一点,有一些内置的Excel表function,我可以使用?

如果/然后是一个很好的方法来做到这一点。 VBA还支持具有IIFfunction的三元逻辑,如下所示:

 Worksheets("Sheet3").Range("B17") = IIF(Worksheets("Sheet4").Range("B18") = 2, "Some Text Here:", "0%") 

这可能看起来有些难以理解,但理解这个概念是一个很好的概念,因为它存在于许多语言中,并且通常具有更简化的实现,使其非常有用和简洁。

此外,我build议做一些其他的改动,可能会使你的代码更易于编写,阅读和维护(特别是当它变得更复杂时)。

首先,别名工作表,如下所示:

 Dim this as Worksheet: Set this = Worksheets("Sheet3") Dim that as Worksheet: Set that = Worksheets("Sheet4") 

现在你可以像这样重写你的代码:

 If that.Range("B18") = 2 Then this.Range("B17") = "Some Text Here:" Else this.Range("B17") = "0%" End If 

而三元的方法现在是:

 this.Range("B17") = IIF(that.Range("B18") = 2, "Some Text Here:", "0%") 

而且你可以根据你的喜好获得具体的别名。 例如,你可以实现范围,而不仅仅是工作表,如下所示:

 Dim this as range: Set this = Worksheets("Sheet3").Range("B17") Dim that as range: Set that = Worksheets("Sheet4").Range("B18") this = IIf(that = 2, "Some Text Here:", "0%") 

另外,我发现比range属性更容易使用cells属性,特别是当你开始做单元格math的时候。 在这种情况下, Range("B17")变成Cells(17, 2) Range("B17") Cells(17, 2)

您还可以通过在即时窗口中键入Application.ReferenceStyle = xlR1C1来更改电子表格中单元格的引用方式。 这样你就不必在A2风格范围和笛卡尔风格(2,1)之间进行精神转换。

有时候你只需要经历整个思维过程,然后把所有的东西都打出来,然后再做一个“啊哈”! 因为那正是我所发生的。 我对自己说:“为什么我不能只有一个macros被selectbutton触发,检查我的链接单元,然后继续更新我想要的单元? 那么,最终我能够find正确的代码,这是完美的工作:

 Sub mode() ' mode is the name of this macro If Worksheets("Sheet4").Range("B18") = 2 Then Worksheets("Sheet3").Range("B17") = "Some Text Here:" Else Worksheets("Sheet3").Range("B17") = "0%" End If End Sub 

事实certificate,我忽视了简单的解决scheme,上面的macros是我所需要的,只要我将它分配给我的组框中的3个选项button,而不是组框。 由于用户无法访问隐藏的Sheet4,因此“Sheet4!B18”将不会有用户手动input,因此我首先在Sheet4上使用的macros可以安全地移除。 由于所select的选项button是所分配的macros的触发器,所以每次更改选项时都会执行该选项,并且只有在选项更改时才会执行。 完善!

编辑:

感谢Chris Strickland提供更好的代码的一些提示! 我继续修改上面的内容,将其改为稍微好一点的性能(使用Cells()而不是Range() ),将原始值保存到另一个单元格,如果select了选项1或3,则使用别名,最后是IIf运营商。

 Sub mode() ' mode is the name of this macro Dim S3 As Worksheet: Set S3 = Worksheets("Sheet3") Dim S4 As Worksheet: Set S4 = Worksheets("Sheet4") If IsNumeric(Cells(17, 2)) = True Then S3.Activate S4.Cells(18, 3) = Cells(17, 2).Value End If S3.Cells(17, 2) = IIf(S4.Cells(18, 2) = 2, "Some Text Here:", S4.Cells(18, 3)) End Sub