简体   繁体   English

Excel-使用VBA更改UserForm文本框和组合框的BackColor

[英]Excel - Change BackColor of UserForm TextBoxes and ComboBoxes with VBA

I am just learning VBA and have used some code from an older book (Excel 2010). 我只是在学习VBA,并使用了一本旧书中的一些代码(Excel 2010)。 It could be that Excel 2016 had some changes that make this code not work anymore. Excel 2016可能进行了一些更改,使此代码不再起作用。

I do not get a compile error for the class or the Subs. 我没有得到该类或Subs的编译错误。 The behavior is that NOTHING happens. 行为是什么都不会发生。 What is supposed to happen is that the BackColor of either a ComboBox or a TextBox should change color as if is in focus or leaves focus. 应该发生的是,ComboBox或TextBox的BackColor应该改变颜色,就像在焦点上或离开焦点一样。

As I said, for some reason when I run the code nothing happens. 如我所说,由于某种原因,当我运行代码时,什么也不会发生。 No errors or warnings appear so it's as if the code is running and then just doing nothing. 没有错误或警告出现,就好像代码正在运行,然后什么也不做。

Here is my code. 这是我的代码。 The comments should make it clear. 这些意见应使其清楚。 I am hoping someone can explain to me what is going on and why this code results in no color changes as the focus changes when I tab through the UserForm. 我希望有人可以向我解释发生了什么,为什么当我通过UserForm进行制表时,由于焦点改变,此代码为什么没有颜色改变。

This first block of code is a stand alone Class Module called "clsCtlColor" 第一部分代码是一个独立的类模块,称为“ clsCtlColor”

Public Event GetFocus()
Public Event LostFucus(ByVal strCtrl As String)
Private strPreCtr As String


'Base Class for chaging Backcolor of ComBoxes and TextBoxes when focus is changed.
Public Sub CheckActiveCtrl(objForm As MSForms.UserForm)

With objForm
    If TypeName(.ActiveControl) = "ComboBox" Or _
        TypeName(.ActiveControl) = "TextBox" Then
        strPreCtr = .ActiveControl.Name
        'On Error GoTo Terminate
        Do
            DoEvents
            If .ActiveControl.Name <> strPreCtr Then
                    If TypeName(.ActiveControl) = "ComboBox" Or _
                    TypeName(.ActiveControl) = "TextBox" Then
                    RaiseEvent LostFucus(strPreCtr)
                    strPreCtr = .ActiveControl.Name
                    RaiseEvent GetFocus
                End If
            End If
        Loop
    End If
End With

Terminate:
    Exit Sub

End Sub

The following Subs are in the UserForm Code 用户表单代码中包含以下子代码

Option Explicit

Private WithEvents objForm As clsCtlColor

'*********************************************************************************************************************
'*Subs for managing the BackColor of comboxes and TextBoxes depending on focus.***************************************
'*********************************************************************************************************************


'initializes the Userform with the clsCtlColor class
Private Sub UserForm_Initialize()
Set objForm = New clsCtlColor
End Sub

'Changes the BackColor of the Active Control when the form is activated.
Private Sub UserForm_Activate()
If TypeName(ActiveControl) = "ComboBox" Or _
    TypeName(ActiveControl) = "TextBox" Then
    ActiveControl.BackColor = &H99FF33
End If
objForm.CheckActiveCtrl Me
End Sub

'Changes the BackColor of the Active Control when it gets the focus.
Private Sub objForm_GetFocus()
ActiveControl.BackColor = &H99FF33
End Sub

'Changes the BackColor back to white when the control loses focus.
Private Sub objForm_LostFocus(ByVal strCtrl As String)
Me.Controls(strCtrl).BackColor = &HFFFFFF
End Sub

'Clears the objForm when the form is closed.
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Set objForm = Nothing
End Sub

In the Class Module the is an On Error Statement that terminates the Sub when an error occurs. 在类模块中,它是一个On Error语句,该语句在发生错误时终止Sub。 However, I commented it out and still, I see no compile errors. 但是,我将其注释掉,但仍然看不到编译错误。 So, I can only conclude it is a runtime issue. 因此,我只能得出结论,这是一个运行时问题。

Any help would be much appreciated. 任何帮助将非常感激。

UPDATE: 更新:

If I use these two subs on a TextBox I get the effect I'm looking for: 如果在TextBox上使用这两个子控件,则会得到我想要的效果:

Private Sub TextBox1_Enter()
TextBox1.BackColor = RGB(153, 255, 51)
End Sub

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
TextBox1.BackColor = RGB(255, 255, 255)
End Sub

What I hate about this is that my UserForm has over one hundred TextBoxes and I would need to write these two subs for each TextBox - so like 200++ Subs! 我讨厌的是我的UserForm有一百多个TextBox,我需要为每个TextBox编写这两个子-就像200 ++的Subs!

I am still trying to get the above more general approach to work. 我仍在尝试使上述方法更通用。
One thing I noticed is that if I change the RGB values in the two subs above to Hex values, they no longer work. 我注意到的一件事是,如果我将上面两个子区域中的RGB值更改为十六进制值,它们将不再起作用。 I tried changing the hex color values in the more general approach to RGB but it made no difference. 我尝试以更通用的RGB方式更改十六进制颜色值,但没有区别。

Yet Another Update: 另一个更新:

It was pointed out that I had a typo in the class LostFucus . 有人指出我在LostFucus课上有错字。 I changed that in two places to LostFocus . 我在两个地方将其更改为LostFocus However, the code still does not work. 但是,该代码仍然无法正常工作。 Then the question was whether or not my code is in the userform module. 然后问题是我的代码是否在userform模块中。 It is. 它是。 Then I tried an experiment. 然后我尝试了一个实验。 I created a new Workbook and imported the code into a brand new class and userform. 我创建了一个新的工作簿,并将代码导入了全新的类和用户窗体。 I added three textboxes. 我添加了三个文本框。 Abracadabra! 胡言乱语! It worked! 有效! However, it does not work in the form I want it to work in. I have scoured the properties for the form itself and the text boxes and I can see nothing different between my form and the dummy form. 但是,它不能在我要使用的表单中工作。我已经搜索了表单本身和文本框的属性,并且看不到表单和虚拟表单之间的任何区别。

This must be something very simple I am over looking! 这一定是我正在寻找的非常简单的东西!

After a great deal of head scratching and screaming at my poor monitor I finally found the solution but as of now, I am totally disappointed in Microsoft for the weirdness of working with UserForms. 在我那头可怜的显示器上经过大量的抓挠和尖叫之后,我终于找到了解决方案,但是到目前为止,由于使用UserForms的怪异之处,我对Microsoft感到完全失望。 Here is what fixed the problem: 解决问题的方法如下:

I had not yet set the tab order! 我尚未设置制表符顺序!

I realized the tab order had my form opening with the first tab stop being set for a TextBox in a MultiPage on my form. 我意识到选项卡顺序打开了我的窗体,并在窗体的MultiPage中为TextBox设置了第一个选项卡停止位置。 I set the tab order so that the first TextBox is active on the UserForm and everything works with the coloring on the main body of the form. 我设置了标签顺序,以便第一个TextBox在UserForm上处于活动状态,并且一切都与表单主体上的颜色一起使用。

Here is where the weirdness begins, in my opinion. 我认为这是怪异开始的地方。

When the last TextBox on the main body of the form is reached and tab is pressed, the multi-page itself is selected. 当到达表单主体上的最后一个TextBox并按下Tab键时,将选择多页本身 Only after you hit tab a second time is the first TextBox within the MultiPage selected and then the colors are not applied as they are in the main body of the form at all. 仅在再次单击选项卡之后,才选择MultiPage中的第一个TextBox,然后才应用颜色,因为它们根本不在表单的主体中。 The same scenario holds true for Frames as well. 同样的情况也适用于框架。 Also, there does not appear to be a good way to simply tab from the end of page 1 to the beginning of page 2. 此外,似乎没有一种简单的方法可以简单地从页面1的末尾到页面2的开始进行制表。

It's very disappointing to me because I would have thought that this is not the way it is. 这让我非常失望,因为我会以为事实并非如此。 I ASSUMED I could set up 1000 TextBoxes, use the Frames and the Multipage to organize things (SO I COULD MAINTAIN THE WINDOW AT ONE SIZE AND NOT HAVE TO SCROLL THE FORM UP AND DOWN) and then set a tab order that would navigate ALL of the TextBoxes regardless of what organizing container they are in. I assumed it would be this way because it MAKES SENSE! 我假设我可以设置1000个文本框,使用“框架”和“多页”来组织事物(因此,我可以一维维护窗口,而不必上下滚动窗体),然后设置将浏览所有 TextBoxes,无论它们位于哪个组织容器中。我都认为是这种方式,因为它具有感觉! I want to click into the first TextBox and simply never touch my mouse until the form is completely filled out. 我想单击第一个TextBox,然后完全不填写表单就永远不要触摸鼠标。 Otherwise, there really is no point in this effort of making a UserForm! 否则,制作UserForm的努力真的没有意义! I could point and click around in the spreadsheet without the hassle of designing a form and writing code! 我可以在电子表格中指向并单击,而无需设计表单和编写代码的麻烦!

What a bummer! 真可惜!

I suppose I can "make it so!" 我想我可以做到这一点! by writing a bunch of code to jump the selection from container to container...MICROSOFT - It should not be this wonky and stupid! 通过编写一堆代码将选择内容从一个容器跳到另一个容器...微软-这不应该是这样的愚蠢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM