How to restart the macro when changing in userform - excel

I do not know how to explain the problem, hope you understand
I use the code to force the user to fill out the form in order
The problem I have is 4 combobox
The 1 opens the 3 or 4 by the value of 1
If I change the value of 1, I have to write the value again in 2 to open the 3 or 4
My problem is that he does not constantly check what the value is in 1, only when there is a change in 2
How can I force the 2 to constantly check the value in 1?
That's the code I have
Private Sub ComboBox2_Change()
Dim lLoc As Long
lLoc = Me.ComboBox2.ListIndex
If lLoc = -1 Then
Me.ComboBox2.SetFocus
ComboBox3.Enabled = False
ComboBox4.Enabled = False
Else
ComboBox3.Enabled = True
End If
If ComboBox1.Text = "abc" Then
ComboBox4.Enabled = True
Else
ComboBox4.Enabled = False
End If
End Sub

Related

Excel VBA: Hide Pages based on Combobox selection

I have a Combobox with values: "none", "1", "2", "3" and "4". And I want to have visible the number of pages shown by the Combobox. How can I achieve that? i.e. combobox = 3 - Pages 1, 2 and 3 become visible.
An alternative:
Private Sub ComboBox1_Change() ' Could also use a number spinner to control user input
Dim pgCount as Short
' Some data validation
pgCount = IIf(isnumeric(ComboBox1.Text),CShort(ComboBox1.Text),0)
pgcount = iif(pgCount >= 0 and pgCount < 5, pgCount,0)
Me.MultiPage2(0).Visible = pgCount > 0
Me.MultiPage2(1).Visible = pgCount > 1
Me.MultiPage2(2).Visible = pgCount > 2
Me.MultiPage2(3).Visible = pgCount > 3
End Sub
Data validation for user input is always important - how can you handle bad input? A better question is: how can you prevent bad input in the first place.
A little explanation:
The data validation firstly checks if the user has put in something representing a number
If the input resembles a number then convert it to a number. In this case converting it to an Short removes any decimal places the user may have entered.
If the input does not resemble a number, use 0 instead (a soft fail)
If the converted number is between 0 ("None") and 4, then OK, otherwise set it to 0 (another soft fail).
[End of data conversion]
The next four lines use simple Boolean logic to determine if the tab should be shown. I used your answer code to determine the logic.
Finally got it
Private Sub ComboBox1_Change()
Select Case ComboBox1.Text
Case "none"
Me.MultiPage2(0).Visible = False
Me.MultiPage2(1).Visible = False
Me.MultiPage2(2).Visible = False
Me.MultiPage2(3).Visible = False
Case "1"
Me.MultiPage2(0).Visible = True
Me.MultiPage2(1).Visible = False
Me.MultiPage2(2).Visible = False
Me.MultiPage2(3).Visible = False
Case "2"
Me.MultiPage2(0).Visible = True
Me.MultiPage2(1).Visible = True
Me.MultiPage2(2).Visible = False
Me.MultiPage2(3).Visible = False
Case "3"
Me.MultiPage2(0).Visible = True
Me.MultiPage2(1).Visible = True
Me.MultiPage2(2).Visible = True
Me.MultiPage2(3).Visible = False
Case "4"
Me.MultiPage2(0).Visible = True
Me.MultiPage2(1).Visible = True
Me.MultiPage2(2).Visible = True
Me.MultiPage2(3).Visible = True
End Select
End Sub

How do I have one Userform event procedure (checkbox click) control multiple IF THEN statements?

Hey so I am a beginner with VBA but here is my dilemma:
Creating an excel userform with VBA -
I have a combobox with the numbers 1-8, the number of textboxes shown for the user to fill out is based off of the number selected in the combobox.
I also have a checkbox which, when "TRUE", enables the user to create a custom title for the output of the textbox.
Ex:
Number of Goals = 2
Custom Label Goals? [x] (True)
Goal 1 : $1,000,000
"New Home"
Goal 2 : $50,000
"Boat"
My issue is that I cannot get the number of custom label boxes to be the same as the number of goals selected. So when Number of goals is 2, 8 custom goal textboxes still show up if the checkbox is TRUE.
I found a way using the code below, but when I enter the second IF THEN statement, the first no longer responds to the clicking the checkbox:
Private Sub cbIMPLBL_Click()
If cboIMP.Value = "1" And cbIMPLBL.Value = "True" Then
txtIMPLBL1.Visible = True
txtIMPLBL2.Visible = False
txtIMPLBL3.Visible = False
txtIMPLBL4.Visible = False
txtIMPLBL5.Visible = False
txtIMPLBL6.Visible = False
txtIMPLBL7.Visible = False
txtIMPLBL8.Visible = False
Else
txtIMPLBL1.Visible = False
txtIMPLBL2.Visible = False
txtIMPLBL3.Visible = False
txtIMPLBL4.Visible = False
txtIMPLBL5.Visible = False
txtIMPLBL6.Visible = False
txtIMPLBL7.Visible = False
txtIMPLBL8.Visible = False
End If
If cboIMP.Value = "2" And cbIMPLBL.Value = "True" Then
txtIMPLBL1.Visible = True
txtIMPLBL2.Visible = True
txtIMPLBL3.Visible = False
txtIMPLBL4.Visible = False
txtIMPLBL5.Visible = False
txtIMPLBL6.Visible = False
txtIMPLBL7.Visible = False
txtIMPLBL8.Visible = False
Else
txtIMPLBL1.Visible = False
txtIMPLBL2.Visible = False
txtIMPLBL3.Visible = False
txtIMPLBL4.Visible = False
txtIMPLBL5.Visible = False
txtIMPLBL6.Visible = False
txtIMPLBL7.Visible = False
txtIMPLBL8.Visible = False
End If
End Sub
Any help here would be greatly appreciated.
As I am just beginning is there a different way I am supposed to be doing this, e.g. not writing all of this out individually, but as a control or function (not sure what the term would be) of some sort?
Thank you so much!!!!
Currently both if statements will fire. So if cboIMP.Value = "1" then it first runs through the first if statement and unhides the first text box. But it immediately runs the second if statement and because it does not = "2" it re hides the text box.
There are two choices a select case statement or else if statements.
Select Case:
If cbIMPLBL.Value = "True" Then
Select Case cboIMP.Value
Case 1
'hide/unhide for 1
Case 2
'hide/unhide for 2
Case Else
'Hide all
End Select
End If
Else if
If cbIMPLBL.Value = "True" Then
if cboIMP.Value = 1 then
'do your stuff
Else if cboIMP.Value = 2 then
'do your stuff
Else
'hide everything
end if
End If
This way once the code finds a true it ignores all others. If it does not find any true statements it runs the else.

Loop Through CheckBox Controls in VBA UserForm

I have a user form in Excel VBA with a check box for each month.
Selecting one or more cause the required month to be shown on the sheet, I copy-pasted the code 12 times and it works but I'm sure there is a better way doing it with a For loop.
This is a part of my code (it goes on 12 times):
If CheckBox1.Value = True Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("1").Visible = True
Else
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("1").Visible = False
End If
If CheckBox2.Value = True Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("2").Visible = True
Else
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems("2").Visible = False
End If
I tried writing:
for i in range 1 to 12
and then writing my code but there seem to be a problem when I put "i" instead of the numbers.
Assuming you aren't using Tristate checkboxes, then the .Value can only be True or False, so we should be able to get away with something like this:
(Assumes your code runs inside the UserForm, so that Controls is directly accessible)
Dim mthIdx as Long
Dim nm as String
Dim c As Control
With ActiveSheet.PivotTables("PivotTable1").PivotFields("month")
For mthIdx = 1 To 12
nm = "CheckBox" & mthIdx
Set c = Controls(nm)
.PivotItems(mthIdx).Visible = c.Value
Next
End With
(The With clause isn't strictly necessary, but it's usually a good idea to resolve nested COM references as infrequently as possible)
Try this ..
Dim i As Integer
Dim sN As String
Dim chx As MSForms.CheckBox
Dim obj As OLEObject
For i = 1 to 12
sN = format(i)
Set obj = OLEObjects("CheckBox" & sN)
Set chx = obj.Object
If chx.Value = True Then
ActiveSheet.PivotTables("PivotTable" & sN).PivotFields("month").PivotItems(sN).Visible = True
Else
ActiveSheet.PivotTables("PivotTable" & sN).PivotFields("month").PivotItems(sN).Visible = False
End If
Next
I've not checked the code but this should put you along thr right path if it's not spot on though...
For i = 1 to 12
If CheckBox(i).Value = True Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems(i).Visible = True
Else
ActiveSheet.PivotTables("PivotTable1").PivotFields("month").PivotItems(i).Visible = False
End If
Next i

Why does my BASIC project get an "unexpected <" error?

' Gambas class file
' Math Drill by William Teder. Feel free to use parts of the code, but please give me credit.
' Declare Variables
' Define number of times user has pressed the Give Up button
PRIVATE givenuptimes AS Integer
' Define how many questions the user has answered
PRIVATE questionsanswered AS Integer
' Define what level the user is on
PRIVATE level AS Integer
' Define the number of points the user has
PRIVATE points AS Integer
' Define whether ot not addition, subtraction, multiplication, and division are enabled. This value is changed whrn the textboxes are togglrd.
PRIVATE additionenabled AS Boolean
PRIVATE subtractionenabled AS Boolean
PRIVATE multiplicationenabled AS Boolean
PRIVATE divisionenabled AS Boolean
'Set an integer for counting the number of times the program resets, for use in email.
PRIVATE resetcount AS Integer
' Define variable to help in detrmining the problem type
PRIVATE problemtype AS Integer
' Define number of numbers to add when using an addition problem
PRIVATE currentproblem AS String
PRIVATE currentanswer AS String
PRIVATE currentproblempointvalue AS Integer
PRIVATE add1 AS Integer
PRIVATE add2 AS Integer
PUBLIC SUB Form_Open()
'Set inital values
givenuptimes = 0
questionsanswered = 0
level = 1
points = 0
additionenabled = TRUE
subtractionenabled = TRUE
multiplicationenabled = TRUE
divisionenabled = TRUE
' GET RID OF THE FOLLOWING LINE WHEN USED IN BUILDING OR THE PROGRAM WILL NOT WORK!
' currentanswer = 0
makeproblem()
END
PUBLIC SUB btnClearAnswer_Click()
'clear the contents of txtAnswer and give it the focus
txtAnswer.Text = ""
txtAnswer.SetFocus
END
PUBLIC SUB chkGiveUp_Click()
' Check to see if the Give Up button's visible property is set to true, and if it is, hide the button. If it is hidden, show it again.
IF btnGiveUp.Visible = FALSE THEN
btnGiveUp.visible = TRUE
lblhGiveUp.visible = TRUE
lblGivenUp.visible = TRUE
expSettings.Raise
RETURN
END IF
IF btnClearAnswer.Visible THEN
btnGiveUp.Visible = FALSE
lblGivenUp.Visible = FALSE
lblhGiveUp.Visible = FALSE
expSettings.Raise
RETURN
END IF
END
PUBLIC SUB btnGiveUp_Click()
'Increment the counter that shows the number pf times the user has given up by 1
givenuptimes = givenuptimes + 1
lblGivenUp.Text = givenuptimes
'Display the right answer
txtAnswer.Text = currentanswer
WAIT 2
txtAnswer.Text = ""
points = points - 10
lblPoints.Text = points
makeproblem()
END
PUBLIC SUB chkLevels_Click()
' Check to see if the Level label's visible property is set to true, and if it is, hide the label. If it is hidden, show it again.
IF lblLevel.Visible = FALSE THEN
lblhLevel.Visible = TRUE
lblLevel.visible = TRUE
'Move the answered section down one place, if it is not already
lblhAnswered.Top = 150
lblAnswered.Top = 143
'For some odd reason, when the new objects appear they move themselves forward. Re-lowering the Settings container fixes this.
IF lblGivenUp.Visible = FALSE OR lblAnswered.Visible = TRUE THEN
lblhGiveUp.Top = 200
lblGivenUp.Top = 193
END IF
expSettings.Raise
RETURN
END IF
IF lblLevel.Visible THEN
lblLevel.Visible = FALSE
lblhLevel.Visible = FALSE
'Move the answered section up one place
lblhAnswered.Top = 105
lblAnswered.Top = 98
'Check to see if the GiveUp section needs to be moved
IF lblGivenUp.Visible = TRUE AND lblhLevel.Visible = FALSE THEN
lblhGiveUp.Top = 150
lblGivenUp.Top = 143
END IF
'See above comment
expSettings.Raise
RETURN
END IF
END
PUBLIC SUB btnReset_Click()
' Notify user the program is working
lblProblem.Text = "Resetting, please wait..."
'First, reset variables
givenuptimes = 0
questionsanswered = 0
level = 1
points = 0
'Clear the answer textbox.
txtAnswer.Text = ""
'Next, clear interface.
lblAnswered.Text = "0"
lblLevel.Text = "0"
lblPoints.Text = "0"
lblGivenUp.Text = "0"
' Notify user that the reset has finished and that the program is generating a new problem
lblProblem.Text = "Reset complete, generating new problem..."
makeproblem()
END
' These four subs are the same code with different variables. Changes state of variable the checkbox is assigned to, makes it the opposite of it's current state.
PUBLIC SUB chkAddition_Click()
IF divisionenabled = FALSE AND subtractionenabled = FALSE AND multiplicationenabled = FALSE THEN
PRINT Message("You must select at least one option.")
additionenabled = TRUE
chkAddition.Value = TRUE
RETURN
END IF
' Set the boolean additionenabled to be true or false based on it's current state
IF additionenabled = TRUE THEN
additionenabled = FALSE
RETURN
END IF
IF additionenabled = FALSE THEN
additionenabled = TRUE
RETURN
END IF
END
PUBLIC SUB chkSubtraction_Click()
IF additionenabled = FALSE AND divisionenabled = FALSE AND multiplicationenabled = FALSE THEN
PRINT Message("You must select at least one option.")
subtractionenabled = TRUE
chkSubtraction.Value = TRUE
RETURN
END IF
' Set the boolean subtractionenabled to be true or false based on it's current state
IF subtractionenabled = TRUE THEN
subtractionenabled = FALSE
RETURN
END IF
IF subtractionenabled = FALSE THEN
subtractionenabled = TRUE
RETURN
END IF
END
PUBLIC SUB chkMultiplication_Click()
IF additionenabled = FALSE AND subtractionenabled = FALSE AND divisionenabled = FALSE THEN
PRINT Message("You must select at least one option.")
multiplicationenabled = TRUE
chkMultiplication.Value = TRUE
RETURN
END IF
' Set the boolean multiplicationenabled to be true or false based on it's current state
IF multiplicationenabled = TRUE THEN
multiplicationenabled = FALSE
RETURN
END IF
IF multiplicationenabled = FALSE THEN
multiplicationenabled = TRUE
RETURN
END IF
END
PUBLIC SUB chkDivision_Click()
IF additionenabled = FALSE AND subtractionenabled = FALSE AND multiplicationenabled = FALSE THEN
PRINT Message("You must select at least one option.")
divisionenabled = TRUE
chkDivision.Value = TRUE
RETURN
END IF
' Set the boolean divisionenabled to be true or false based on it's current state
IF divisionenabled = TRUE THEN
divisionenabled = FALSE
RETURN
END IF
IF divisionenabled = FALSE THEN
divisionenabled = TRUE
RETURN
END IF
END
' Subroutine to make a problem
SUB makeproblem()
' This is the code that determines a new problem for the user based on a number of factors, including how many problems of that type they have done,
' whether or not the type is enabled or disabled, how quickly they can answer the question, thier points and level, and how many times they have
' given up on that type of problem. The rest is random. DO NOT MESS WITH THIS CODE UNLESS YOU KNOW WHAT YOU ARE DOING! It is very easy to mess up the program,
' as well as generate stack overflow errors.
' Engine version : 0.0.0.1
' Engine by William Teder
' ------------------------------------
' Generates a random number for the Problem Type, 1 - 4
problemtype = Rnd(1, 5)
IF problemtype = 1 THEN
' Problem Type: Addition
lblProblem.Text = "Problem Type: Addition"
' Determine the number of numbers to add together
IF level <= 5 THEN
' Determine how high the number should be
IF points <= 200 THEN
add1 = Rnd(1, 10)
add2 = Rnd(1, 10)
currentanswer = add1 + add2
currentproblem = add2 & " + " & add1
lblProblem.Text = currentproblem
RETURN
END IF
IF points > 200 AND < 400 THEN
add1 = Rnd(1, 20)
add2 = Rnd(1, 20)
add1 + add2 = currentanswer
currentproblem = add2 & " + " & add1
lblProblem.Text = currentproblem
RETURN
END IF
IF points > 400 AND < 500 THEN
add1 = Rnd(1, 30)
add2 = Rnd(1, 30)
add1 + add2 = currentanswer
currentproblem = add2 & " + " & add1
lblProblem.Text = currentproblem
RETURN
END IF
END IF
IF level <= 10 AND >= 6 THEN
' Code for three numbers
END IF
IF level <= 15 AND >= 11 THEN
'Code for 4 numbers
END IF
IF level <= 20 AND >= 16 THEN
' Code for 5 numbers
END IF
IF problemtype = 2 THEN
' Problem Type: Subtraction
lblProblem.Text = "Problem Type: Subtraction"
END IF
IF problemtype = 3 THEN
' Problem Type: Multiplication
lblProblem.Text = "Problem Type: Multiplication"
END IF
IF problemtype = 4 THEN
' Problem Type: Division
lblProblem.Text = "Problem Type: Division"
END IF
END
PUBLIC SUB gotright()
' Increment questions answered counter
questionsanswered = questionsanswered + 1
' Increment Points
points = points + currentproblempointvalue
' For every 100 points, increment the level counter by 1.
IF level = 1 AND points = 200 THEN level = 2
IF level = 2 AND points = 300 THEN level = 3
IF level = 3 AND points = 400 THEN level = 4
IF level = 4 AND points = 500 THEN level = 5
IF level = 5 AND points = 600 THEN level = 6
IF level = 6 AND points = 700 THEN level = 7
IF level = 7 AND points = 800 THEN level = 8
IF level = 8 AND points = 900 THEN level = 9
IF level = 9 AND points = 1000 THEN level = 10
IF level = 10 AND points = 1100 THEN level = 11
IF level = 11 AND points = 1200 THEN level = 12
IF level = 12 AND points = 1300 THEN level = 13
IF level = 13 AND points = 1400 THEN level = 14
IF level = 14 AND points = 1500 THEN level = 15
IF level = 15 AND points = 1600 THEN level = 16
IF level = 16 AND points = 1700 THEN level = 17
IF level = 17 AND points = 1800 THEN level = 18
IF level = 18 AND points = 1900 THEN level = 19
IF level = 19 AND points = 2000 THEN level = 20
' Change font color of the textbox to green to let the user know he/she got the problem right
txtAnswer.Foreground = &H579524&
' Create delay to let the user know they got the answer right
WAIT 1
' Change back to regular color
txtAnswer.Foreground = &HFF004&
END
PUBLIC SUB txtAnswer_KeyRelease()
IF txtAnswer.Text = currentanswer THEN
txtAnswer.Foreground = &H579524&
questionsanswered = questionsanswered + 1
lblAnswered.Text = questionsanswered
WAIT 0.25
txtAnswer.Text = ""
' Change back to regular color
txtAnswer.Foreground = &HFF0004&
lblPoints.text = points
makeproblem()
END IF
END
PUBLIC SUB Button1_Click()
makeproblem()
END
At line 251, there is an unexpected >. Why does it fail to compile? Thanks.
IF points > 400 AND < 500 THEN
That doesn't look quite right to me, unless your BASIC is really advanced (and it appears GAMBAS isn't quite that advanced). It should be:
IF points > 400 AND points < 500 THEN
You have the right idea with this line, for example:
IF lblGivenUp.Visible = TRUE AND lblhLevel.Visible = FALSE THEN
Same for all the variations you have of this, you need to include the variable on the right hand side of the and as well):
IF points > 200 AND < 400 THEN
IF points > 400 AND < 500 THEN
IF level <= 10 AND >= 6 THEN
IF level <= 15 AND >= 11 THEN
IF level <= 20 AND >= 16 THEN

Excel Diagramm Seriesnames in VBA

I'm programming a Makro for a Excel xy-Diagramm
The diagramm is nearly correct, but i have dublicate DataSeriesNames;
I already tried to go through all Series and Compare the Names.
There were no Errors, but it didn't work.
Code was like that:
For a=1 to Count
If ActiveChart.SeriesCollection(Count).Name = Range("A2").Value Then
Name = true
End If
a = a + 1
Next
If Name = false Then
ActiveChart.SeriesCollection.NewSeries
End If
ActiveChart.SeriesCollection(Count).Name = "='Tasks'!$D$" & i
ActiveChart.SeriesCollection(Count).XValues = "='Tasks'!$B$" & i
ActiveChart.SeriesCollection(Count).Values = "='Tasks'!$C$" & i
Mfg Robin
There are a couple of things wrong here.
First of all, you're always looking at the same series! I think you want to replace Count with a in your If statement.
If ActiveChart.SeriesCollection(a).Name
Secondly, once that is corrected, even if your Name variable gets set to True at some point, it may get reset to False later as the For...Next loop continues iterating through the remainder of the series collection. To prevent this, add an Exit For like this:
For a = 1 To Count
If ActiveChart.SeriesCollection(a).Name = Range("A2").Value Then
Name = True
Exit For
End If
a = a + 1
Next
Also, I suspect you haven't declaring Name as a Boolean variable, so by default it's a Variant so its value isn't False to start with! You should declare the variable at the top of your procedure with Dim Name as Boolean, and then if you want Name to be False by default, you should really say so explicitly: Put Name = False before the loop. Moreover, Name is a terrible name for a variable... and so is Count Argh! I think your code should look like this:
Option Explicit
Sub MySub()
Dim a As Long
Dim NameExists As Boolean
Dim SeriesCount As Long
SeriesCount = ActiveChart.SeriesCollection.Count
NameExists = False
For a = 1 To SeriesCount
If ActiveChart.SeriesCollection(a).Name = Range("A2").Value Then
NameExists = True
Exit For
End If
a = a + 1
Next
If NameExists = False Then
' Rest of your code goes here...
End Sub

Resources