使用相对引用来为控件重用macros

我正在尝试为同事编写Excel 2007macros,但是我的VBA技能是非常基本的(赦免双关语)。 本质上,需要发生的是,当单击一个checkbox时,右侧的相邻单元格将填写login人员的用户名。

到目前为止,这里是我提出的代码,允许我这样做:

Sub CheckBox1_Click() Range("J4").Activate If ActiveCell.Offset(0, 18).Value = True Then ActiveCell.Offset(0, 1).Value = Environ("UserName") Else ActiveCell.Offset(0, 1).Clear End If End Sub 

只是为了参考,“ActiveCell.Offset(0,18)”指的是一个链接到有问题的checkbox并包含其真/假值的单元格。

(编辑:另外,单元格J4被激活的原因是因为在这种情况下,它是包含ActiveXcheckbox的单元格)

这很好,但这不是我的问题。 我的问题是:在这一行中有49多个checkbox,在这个表上有三个多行,在这本书中还有45多个表。 我不想复制粘贴相同的代码到一个唯一的macros只是为了改变活动单元格。 更重要的是,作为一名优秀的程序员,我不应该像这样重复代码。 我应该怎么写,这样我就不必每次都提到一个独立的单元格了?

编辑2:神圣烟,兰斯刚刚帮我意识到我错了。 该工作表使用表单控件,而不是ActiveX控件。 非常抱歉,大家。

虽然使用Sheet对象很容易,但使用ActiveX控件对象很难。 你不能在事件中自己引用一个ActiveX控件的名字,除非它被传递给它,你也不能引用事件子例程的名字来提取名字,你不能引用它的名字调用例程的例程。

我也尝试触发“工作表更改”和“select更改”事件,但是这些事件不会触发checkbox更改,即使它具有更改的LinkedCell

我最后想到的是点击事件的通用包装,你必须修改string以匹配checkbox名称:

 Private Sub CheckBox1_Click() NameCopy Me, "CheckBox1" End Sub 

然后是NameCopy函数,它将LinkedCell左侧的单元格-7设置为名称值。

 Public Sub NameCopy(wsheet As Worksheet, cname As String) If wsheet.OLEObjects(cname).Object.Value = True Then Range(wsheet.OLEObjects(cname).LinkedCell).Offset(0, -7).Value = Environ("UserName") End If End Sub 

使用“表单”checkbox更容易,您可以将此macros用于所有checkbox。 只要记住将macros设置为:

 Public Sub NameCopy() Dim shp As Shape Set shp = ActiveSheet.Shapes(Application.Caller) If shp.ControlFormat.Value = xlOn Then ActiveSheet.Range(shp.ControlFormat.LinkedCell).Offset(0, -7).Value = Environ("UserName") End If End Sub 

既然你正在使用表单控件,这真的很容易。 您可以使用Application.Caller让代码访问点击checkbox,然后使用它的TopLeftCell属性来获取checkbox的位置,然后您可以执行任何您想要的操作。 在你的情况下,这样的事情我猜测:

 Sub Checkbox_Click() With ActiveSheet.CheckBoxes(Application.Caller) If .Value = 1 Then 'Checkbox is checked .TopLeftCell.Offset(, 1).Value = Environ("UserName") Else .TopLeftCell.Offset(, 1).ClearContents End If End With End Sub