How do you make the value in a control box update live in VBA? - excel

I have a bare minimum of VBA experience, and I have to edit a tool someone else made a while ago. The values in the textbox for the form control will not update in real time. There are multiple textboxes (I think form control, not sure how to check.) where the user inputs values. However, the box does not update the value inside until a cell is selected.
I don't see anything in the code for this that would affect this. Here's an example from one of the Textboxes.
Private Sub SysA_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
With Sheets("SysA")
If KeyCode = 13 Then
If Len(.SysA.Value) = 5 Then
.SysANum.Activate
Else
MsgBox "Enter in a valid number!"
.SysANum.Value = ""
.SysANum.Activate
End If
End If
End With
End Sub
I've also looked in the properties for the textbox and don't see anything that might affect it. (AutoLoad is set to False and Enabled is set to True)

Related

How to prevent Userform Combobox show the drop down list if the item is only one?

I have an array which contains customer's names as arrNama variable
I use a code to filter as I type which I've found in the internet (I am sorry I don't remember the link), something like this :
Sub cbNama_Populate(Optional fltr As String)
cbNama.List = Filter(arrNama, fltr, , vbTextCompare)
End Sub
Private Sub cbNama_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Call cbNama_Populate(cbNama.Text)
If cbNama.ListCount = 1 Then cbNama.ListIndex = 0 Else cbNama.DropDown
End Sub
The If cbNama.ListCount = 1 Then cbNama.ListIndex = 0 Else cbNama.DropDown line is my modification, the original I found in the internet is just cbNama.DropDown.
I modified that line, because I thought with that IF conditon, it won't show the drop-down list if the list count of the combo box is only one. Yet it still show the drop-down list with that one item only, just like as if in the original code which has no IF condition.
Below is the example of what I mean :
At the time the combobox has only one item, the cbNama.ListIndex = 0 trigger the cbNama_Click sub. But the combobox still show the drop-down list, highlighted with blue on that one item.
My question:
How to prevent it showing the drop-down list when there is only one item?
Any kind of response would be greatly appreciated.
Thank you in advanced.
For the time being, I use cbNama.Enabled = False, this prevent the dropdown shows if there is one item only.

Pass subroutine name as string to use subs as general purpose input validation

I read through several posts about similar problems and tried many solutions offered by this and other communities. I cannot tailor any of these to my specific needs.
I have an Excel workbook that generates a timesheet and a detailed job report based on the information provided in a userform.
The job report and the timesheet are exported to an Access table (or imported from said table to be edited or deleted).
I have a working version with repetitive code for validating the userform inputs.
There are eight inputs that must meet criteria.
i) must be a number
ii) must not be less than a minimum value
iii) must not be greater than a maximum value
I have a subroutine for each of these inputs that checks these criteria using BeforeUpdate, and calls another subroutine to make visible changes to the userform to alert the user of an invalid entry (alter the label color and caption, textbox or dropbox color, etc.).
Using AfterUpdate, I have a subroutine for each of the eight inputs that reverts these changes once a valid entry has been made.
This means I have 24 subroutines with basically the same code, where I feel there should only be three subroutines that can be used more generally.
Here is the code I have for these subroutines, as it is being used for one specific input:
Sub #1
Private Sub NumberOfTechs_BeforeUpdate(ByVal CAncel As MSForms.ReturnBoolean)
If Not IsNumeric(numberOfTechs) Then
Call NumberOfTechsInvalid("Must be a number!", numberOfTechsLabel, numberOfTechs)
CAncel = True
Else
If numberOfTechs < 1 Then
Call NumberOfTechsInvalid("Cannot be less than 1!", numberOfTechsLabel, numberOfTechs)
CAncel = True
ElseIf numberOfTechs > 6 Then
Call NumberOfTechsInvalid("Cannot exceed 6!", numberOfTechsLabel, numberOfTechs)
CAncel = True
End If
End If
End Sub
Sub #2
Private Sub NumberOfTechsInvalid(errorCaption As String, targetLabel As Object, targetControl As Object)
targetLabel.caption = errorCaption
targetLabel.ForeColor = rgbRed
targetControl.BackColor = rgbPink
targetControl.SelStart = 0
targetControl.SelLength = Len(targetControl)
End Sub
Sub # 3
Private Sub NumberOfTechs_AfterUpdate()
numberOfTechsLabel.ForeColor = Me.ForeColor
numberOfTechsLabel = "Number Of Techs"
numberOfTechs.BackColor = rgbWhite
' Call next subroutine
End Sub
I have a comment at the bottom of sub#3 that says "call next subroutine". This is where I am having difficulty.
I can pass the minimum and maximum values as variables, as well as specify the target control and label based on which user input triggers the call to sub#1.
The issue is passing the next subroutine as a string.
I tried placing these subroutines in their own module and using Application.Run. I tried using CallByName with these subs within the userform code.

Editing percentage value in Userform TextBox

I am attempting to create a textbox which allows users to input a percentage between 1-5% in my Excel-VBA Userform. I have created the textbox and added code to restrict the formatting to always show as a percentage. My problem is that when I attempt to edit the default percentage in the textbox by pressing backspace the decimal moves two spaces to the right instead of deleting any present values. Below is a copy of my code. Please note that the Textbox is not locked.
Private Sub PV_change()
PV.Text = Format(PV.Value, "Percent")
End Sub
You could do your code in the PV_Exit procedure rather than the _Change procedure, but I still think you're asking for trouble this way :)
Private Sub PV_Exit(ByVal Cancel As MSForms.ReturnBoolean)
PV.Value = Format(PV.Value, "Percent")
End Sub
I agree with the objections made previously, but to show a simple solution without error trapping try this:
Private Sub tbPV_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Dim dblPV As Double
' don't allow backspace
If KeyCode = Asc(vbBack) Then Exit Sub
' Change string to Double value (without percent sign)
dblPV = CDbl(Replace(Me.tbPV.Text, "%", ""))
' Show the formatted result
Me.tbPV.Text = Format(dblPV, "0.00") & "%"
End Sub
Further Remark Naming a text box 'PV' only doesn' t seem to be state of the art. Adding a prefix - e.g. 'tb' or 'txt'- to all your text boxes gives a hint to to control's original type and could give your code a comprehensible structure.
There are number of naming conventions and divergent opinions, but just to give you an impression have a look at
Hungarian in VBA okay? or search within the Stack Overflow's "naming-conventions" tag.
Best Regards

OnKey "Delete" clear combobox

I have a userform with multiple comboboxes. User can type in a new item or pick one from the list.
He can start typing first letters of wanted item but when he makes a mistake and starts with e.g. "b" instead of "n" he has to clear the combobox manually or find the item on the list using mouse or arrows.
I would like to quickly clear the box using the delete key so the user can start typing again. But I don't know where to put this line of code if correct (enter event, change event, some other maybe?).
Application.OnKey "{Delete}", "WyczyscPole"
First Excel needs to know which box the user is in, and then clear it.
I tried to create separate module with a variable that finds out the current combobox name and clear it in next step. But I don't know whether called sub below is even correct.
Sub WyczyscPole()
Dim NazwaPola As ComboBox
NazwaPola = frmZakupy.ActiveControl.Name
NazwaPola.Clear
End Sub
You can use the KeyDown event to capture the Delete key (KeyCode = 46) when the user is in the combobox.
Private Sub NazwaPola_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 46 Then
Me.NazwaPola.Value = vbNullString
End If
End Sub
Please try: frmZakupy.value=''
It's a good practice to don't use special characters like 'ś','ć' in any names.

Disable button on a userForm

I'm trying to figure out how to disable a button within my userForm if a certain cell within my spreadsheet equals a certain number. I tried the code stated below, but it isn't working.
Private Sub UserForm_Initialize()
Label2 = Sheets("DATA").Range("AM2").Value
Label4 = Sheets("DATA").Range("AO2").Value
Label7 = Format(Sheets("DATA").Range("R8").Value, "Currency")
If Sheets("DATA").Range("AL10").Value = 10 Then
ActiveSheet.Shapes("CommandButton1").Select
UserFormact_Upgrade.CommandButton1.Enabled = False
Else
End If
End Sub
Your code should be working, as you're on the right path.
To test it, simply create a new form and add this code, you'll see it should work. Maybe you're having problems within the IF clause?
Besides, you don't need to select the shape prior to disabling it; just disable it right away.
Private Sub UserForm_Initialize()
CommandButton1.Enabled = False
End Sub
I know this is old, but got to this thread trying to solve my problem, and found a solution that wasn't mentioned here. So in case someone gets here like I did, and this didn't quite get them where they needed to go, I thought this might help.
I had a userform with a drop down box called cmdADAMFields, and I didn't want my submit button called FieldsSubmitButton to be enabled until I selected something from the dropdown box.
I had to break up my argument into two different private subs vs one larger If-Then-Else statement.
First, I put:
Private Sub UserForm_Activate()
If cmbADAMFields.ListIndex = -1 Then FieldsSubmitButton.Enabled = False
End Sub
Then when for my pulldown's private sub when it's value changed I wrote:
Private Sub cmbADAMFields_Change()
FieldsSubmitButton.Enabled = True
End Sub
The proper place for setting Enabled property is in Activate event (associated with Show method) and not Initialize event (associated with Load instruction).
The below code disable the button CommandButton1 when AL10 cell >= 10.
Private Sub UserForm_Activate()
CommandButton1.Enabled = ( Sheets("DATA").Range("AL10") < 10 )
End Sub
For buttons you can choose between normal buttons (property Enabled=False and property Visible=true), disabled buttons (property Enabled=False and property Visible=true) and invisible buttons (property Enabled=False and property Visible=False), that it is a cleaner interface, in most cases.
Concerning text boxes, besides normal, disabled and invisible status, there is a locked status, that is enabled and visible, but cannot be user edited. (property Locked = True)
A locked control only can be changed by VBA code. For instance, someone can includes date text boxes, that it's filled using a secondary popup date form with Calendar control.

Resources