从不同的复选框中调用类似的函数 [英] Call a similar funcion from different checkboxes

查看:73
本文介绍了从不同的复选框中调用类似的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿伙计们,

我在UserForm中有大约20个复选框。

所有复选框在被检查或取消选中时都必须调用类似的函数:

Hey guys,
I have about 20 checkboxes in a UserForm.
All checkboxes have to call a similar function when they get checked or uncheckt:

Private Sub CheckBox2_Click()
    TextBox4.Visible = True
        If CheckBox2.Value = True Then
        TextBox4.ForeColor = RGB(0, 0, 0)
        TextBox4.Locked = False
    ElseIf CheckBox2.Value = False Then
        TextBox4.ForeColor = RGB(127, 127, 127)
        TextBox4.Locked = True
    End If
End Sub



CheckBox3只有3号而不是2号,所有4号都会被nnumber 5取代。所以TextBox总是复数+ 2的数字。



我的问题:

编写类似函数20次并不聪明。如何在一个或两个函数中执行此操作?

我不知道。我是VBA的初学者


CheckBox3 would just have number 3 instead of 2 and all 4 would be replaced by nnumber 5. So The TextBox is always the number of the checkbox+2.

My problem:
It's not smart to write 20 times a similar function. How can I do this in one or 2 functions?
I have no idea. I'm a beginner in VBA

推荐答案

请看我对这个问题的评论。另请参阅: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself [ ^ ]。



这个问题看起来非常微不足道,但是,要考虑一下,事实并非如此。这就是原因。你的问题不在于编写一个通用函数会很困难。问题是你原则上拥有所有 CheckBox2 TextBox4 。问题是你已经用手工方式创建了 - 使用设计器。这是多次手动点击。你看,你的代码显示 CheckBox2 TextBox2 处于某种关系。但是 CheckBox2 和其他一些控件之间的关系是什么?没有办法自动计算它,因为你所拥有的只是 ad-hoc 控件名称,这意味着什么。



当然,你可以抽象出这两个控件来制作一些函数的两个参数。但无论如何,你必须编写这20个事件处理程序并从这些处理程序调用此函数20次,这将只使每个处理程序的实现代码的一行。也许你对这样的建议感到满意,但我会反感。



你的问题,你已经出错了表格。我会重做它。事实上你有 CheckBox2 TextBox4 是错误代码的一个很好的指标设计(你永远不应该使用自动生成的名称,并使用重构语言重命名所有控件,给出语义名称并遵守良好的Microsoft命名约定,但在这种情况下它无法帮助你)。你必须有控件数组。第一个想法是在复选框和另一个文本框数组上创建数组,然后你的代码将使用索引访问的数组元素,如if checkBox(index).Value then texBox(index) )... 然后你会写一些代码用表单的控件成员填充数组。至少你只能做一次。



但它也不会那么好。为什么你甚至需要那些成员,如果你真的只需要一个数组用于所有这些复选框(可能不是全部,但与文本框数组元素的类似关系),只有一个数组那些文本框等等?设计师不会为你创建这些数组?



答案是:设计得当。也许你不需要那么多复选框(它已经听起来很可疑,也许你可以重新设计它),但是让我们说这是一个合理的设计,所以你真的需要20个复选框和相关的文本框。由于设计师不会做正确的事情,不要使用设计师。 您需要在循环中在代码中创建所有这些控件。这是关键。并且在循环中仅为每个控件添加每个事件实例的一个处理程序。您只需要将索引传递给处理程序方法。处理程序方法只接受两个参数,sender( System.Object )和事件参数( System.EventArgs 或派生类)。一种可能的技巧是:为所有控件创建 TabIndex 的常规值。然后你可以转换 sender 来纠正控件类型(你在处理程序的代码中知道),然后从 TabIndex <中计算数组索引/ code>。或者,您可以使用匿名方法处理程序和关闭 https://en.wikipedia.org/wiki/Closure_%28computer_programming%29 [ ^ ])。



-SA
Please see my comment to the question. See also: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself[^].

The question looks extremely trivial, but, come to think about, it is not. Here is why. Your problem is not that it would be difficult to write one universal function. The problem is that you have all those CheckBox2 and TextBox4 in principle. The problem is that you already created them in a way too manual way — using the designer. It was manual clicking many times. You see, your code shows that CheckBox2 is in certain relationship with TextBox2. But what is the relationship between CheckBox2 and some other control? There is no a way to calculate it automatically, because all you have are only ad-hoc names of controls, which means nothing.

Of course, you can abstract out these two controls to make then two parameters of some function. But anyway, you will have to write those 20 event handlers and call this function 20 times from those handlers, which would make only one line of the implementation code of each handler. Maybe you would be happy with such advice, but I would be disgusted with it.

Your problem that you already gone wrong with the form. I would redo it. Just the fact you have names line CheckBox2 and TextBox4 is a good indicator of wrong code design (you should never use auto-generated names and rename all controls using refactoring language, to give semantic name and observe good Microsoft naming conventions, but it cannot help you in this case). You have to have arrays of controls. First idea is to create array on check boxes and another array, of text boxes, and then your code would use the the arrays elements accessed by index, something like if checkBox(index).Value then texBox(index)… but then you would write some code populating the arrays with the control members of the form. At least you can do it only once.

But it also would be not so good. Why would you even need those members, if you really need only one array for all those check boxes (maybe, not all of them, but those in the similar relationships with the elements of the array of text boxes), and only one array of those text boxes, and so on? The designer won't create those arrays for your?

The answer is: design properly. Perhaps you don't need that many check boxes (it already sounds suspicious, maybe you can redesign it), but let's say this is a reasonable design, so you really need 20 check boxes and related text boxes. As the designer won't do right thing, don't use the designer. You need to create all those controls in code, in a loop. This is the key. And add only one handler of each event instance to each of those controls, in a loop. You only need to pass the index to the handler method. The handler methods takes only two parameters, sender (System.Object) and event arguments (System.EventArgs or derived class). One possible technique is this: create regular values of TabIndex for all controls. Then you can cast sender to correct control type (which you know in the code of the handler), and then calculate the array index out of TabIndex. Alternatively, you could use anonymous methods for handler and closure (https://en.wikipedia.org/wiki/Closure_%28computer_programming%29[^]).

—SA


这篇关于从不同的复选框中调用类似的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆