New to VBA having checkbox problems - vba

So I'm new to programing(2weeks). I am making a data box to find total a price for a project. I works with text boxes, check boxes and a button to find total.
I input the number of lemons and oranges, when I press the button it calculates how much it will cost based on prices that are pulled from the sheet.
Now I put the check box because there is a set quantity of one. I would like to add the price of "sugar" to the total price when it is checked.
Can some one help me get the check box add to total price?
for example the data box looks like this:
Thanks enter image description here
enter image description here
New code almost works the way I was hoping. thank you for the advice, I tried referencing the sheet and it gave me errors. But it works like this for now.
-When I input numbers in the input boxes and press calculate it gives me the correct total.
-When I check the check box it adds to the total, BUT when I press "Calc" the total is calculated without including checked box.
-When I press more then one checkbox for example: Select "Checksugar" then "checkbox2" the total only adds the value of "Checkbox2". then when I press "Calc" again, the total ignores the checkboxes.
What im wanting it do: When I select more then one check box, I want the totals to add rather then replace eachother. I also want the code to give the total value when I press "Calc" rather then only the totals of the input boxes.
What I think I need to do: Some how add the If statements in the "TxtTotal", but I do not know how to do that. Or have multiple If statements.
Can someone help?
Private Sub Calculate_Click()
TxtTotal = TxtLemon * Range("E21").Value + TxtLime * Range("E20").Value _
+ TxtOranges * Range("E19").Value _
+ TxtApple * Range("E25").Value _
+ TxtCactus * Range("E24").Value
End Sub
Private Sub Checksugar_Click()
If Me.Checksugar.Value = True Then
TxtTotal = TxtLemon * Range("E21").Value + TxtLime * Range("E20").Value _
+ TxtOranges * Range("E19").Value _
+ TxtApple * Range("E25").Value _
+ TxtCactus * Range("E24").Value + Range("E22").Value
End If
End Sub
Private Sub Checkbox2_Click()
If Me.Checkbox2.Value = True Then
TxtTotal = TxtLemon * Range("E21").Value + TxtLime * Range("E20").Value _
+ TxtOranges * Range("E19").Value _
+ TxtApple * Range("E25").Value _
+ TxtCactus * Range("E24").Value + Range("E27").Value
End If
End Sub

IF CheckSugarValue.Value = True Then
'do stuff
TxtTotal.Value = TxtTotal.Value + ThisWorkbook.Sheets("your sheet name).Range("E22").Value
End if
You have a realloy bad habit of non reference stuff correctly. Since youre new its best to understand now while you can form good habits. Converting control objects contents to usable values is often done with ".Value" and often times most people will store those values in a variable. Your lack of explicitly referring to a sheet name will get you into some big trouble later b/c ambiguous references will make the compiler look at wrong sheets. I just got into the habit of doing it the long way like in my example.

Related

How to sum variables in VBA to check input data is correct?

May seem like a stupid question, but how do you sum variables in VBA to check input data is correct?
I'm trying to check the user has inputted data correctly into a UserForm before they continue to the next page. To do this I want to sum some of their input variables. If they don't input it correctly, they get a message box telling them to revise the numbers. My code is:
Dim BinQnt As Double
Dim FillQnt As Double
Dim FineQnt As Double
Dim CoarQnt As Double
Dim RAPQnt As Double
Dim CRQnt As Double
If BinQnt + FillQnt + FineQnt + CoarQnt + RAPQnt + CRQnt = 100 Then
'Code here for inserting values into database. Omitted to save space and confusion.
Else
MsgBox "Error, please check mixture design sums to 100%."
End If
When I'm testing it, it always goes to the error message box and I'm not sure why. Very sure I am adding variables which sum to 100 (haha). I first tried it without defining the variables, and now I have it still doesn't work.
Am I missing something obvious?
Do you want to round it or not?
In your question, you have the variables as Doubles, and in the answer as integers. Having them as integers will make it easier to hit 100%, but it will round to the nearest integer (2,4 = 2 | 2,6 = 3)
I will assume you are using all texboxes in the form, and as such use this code that is universal:
Dim tot As Double
tot = 0
For Each c In Me.Controls
If TypeName(c) = "TextBox" And IsNumeric(c.Value) Then
tot = tot + c.Value
End If
Next c
If tot = 100 Then
'Code here for inserting values into database. Omitted to save space and confusion.
Else
MsgBox "Error, please check mixture design sums to 100%. Currently at " & tot & "%."
End If
This would give us something like this:
However, using Integer or Long, gives us this:
Also, the reason as to why I'm using IsNumeric(c.Value), is to stop the code from failing in case of empty boxes (or filled with invalid entries).
You could also place a check here in case no boxes are allowed to be empty.

How to make textbox inputs numbers with 2 decimal places and then check their sum?

struggling with something in VBA and can't find a clear answer online. Quite new to this. Basically, for the user form below (linked image due to my level), I would like to make all the textbox inputs be numbers (2 decimal places) and then when you click "Next" it checks that all the values sum to 100. If not, error message appears. I've tried lots of different ways of doing this and can't get it to work. I would like for all textbox inputs to be numbers (2dp), and then all the numbers to just add and then check this sum. For each textbox, I've done the following Sub Routine (variable name changes each time for name of textbox):
Private Sub BinQnt_AfterUpdate()
On Error Resume Next
Dim BinQnt As Single
BinQnt = Format(BinQnt, "percent")
End Sub
For the Next button I have done the following:
Private Sub MaterialsData_Next_Click()
'Check mix design = 100%.
'If = 100%, input data to database.
tot = BinQnt + FillQnt + FineQnt + CoarQnt + RAPQnt + CRQnt 'Names of each text box.
If tot = 100 Then
'Code here for inserting values into database. Omitted to save space and confusion.
'Go to next page.
BaseUserForm.MultiPage1.Value = 2
'If doesn't = 100%, then show error MsgBox
Else
MsgBox "Error, please check mixture design sums to 100%. Currently at " & tot & "."
End If
Screenshot of userform.

How to limit a drop down list in a combo box to only show the values that include the letters that the user typed?

I am using Access 2010 database. I have a combo box that gives me a full list of equipment numbers (they have letters and numbers i.e.: sdp1234).
To try to speed up the database I was told to limit the drop down lists in combo boxes.
Currently, users can start typing the equipment # and an item from the list will be highlighted matching with their typed characters.
I want the users to be able to type "12" and the list show should have only the values between "sdp1200" and "sdp1299". Or even just all the items that have "12" inside.
I am not sure if this is done in VBA or in the properties tab for the combo box.
Well a solution would be :
Put this on the top of your VBA..just under Option ...
Dim comboboxOriginal As String
Put this code in the Change Event
Private Sub cboFilterAsType_Change()
If Len(Nz(comboboxOriginal, "")) = 0 Then
comboboxOriginal = Me.cboFilterAsType.RowSource
End If
If Len(Me.cboFilterAsType.Text) > 1 Then
Me.cboFilterAsType.SelStart = Len(Me.cboFilterAsType.Text)
Me.cboFilterAsType.RowSource = Replace(comboboxOriginal, ";", "") & " WHERE SOMEFIELD like ""*" & Me.cboFilterAsType.Text & "*"""
DoCmd.RunCommand acCmdSaveRecord
Me.cboFilterAsType.Requery
Me.cboFilterAsType.Dropdown
End If
End Sub
TO clear the filtering
Private Sub cboFilterAsType_DblClick(Cancel As Integer)
If Len(Nz(comboboxOriginal, "")) > 0 Then
Me.cboFilterAsType.RowSource = comboboxOriginal
End If
End Sub
Take a note that the RowSource should be something simple like SELECT SomeID From ATable

How to add list boxes and text boxes in Excel VBA Userforms dynamically as needed?

I do not know if this is appropriate to place in stackoverflow despite being VBA related--particularly in the UserForms area, however, I cannot visualize at all how i'm going to code this.
My Excel worksheet is shown below:
The UserForm I created to input the data is as shown below:
However, what I want to achieve is similar to how QuickBooks does it where the Amount Due is automatically distributed among the Expense Accounts without having to input them 1 by 1 as shown in the first image (My excel worksheet). Also, when there are more expense accounts than usual (e.g. 10 expense accounts, Quickbooks will automatically add new rows for that purpose). A sample is shown below:
My main issue is that I do not know how to let UserForms dynamically add more rows if I need to do so. It can be automatically add rows when all previous rows are filled or something as shown in the image below:
Let n be the number of expense accounts
So from having to input n*2 (or in my case 4 values):
Telephone/Insurance Expense: 40,000
Cash in Bank 40,000
Water Expense: 40,000
Cash in Bank: 40,000
I can to simplify it to n+1 inputs (or in my case 3 inputs):
Amount Due: 80,000
Telephone/Insurance Expense: 40,000
Water Expense 40,000
A lot of examples and tutorials how to add controls dynamically can be found, for example
how-to-create-controls-dynamically-at-runtime
adding-controls-to-a-frame-in-an-excel-userform-with-vba
vba-userform-basics-add-controls-dynamically-at-run-time
However, depending on the maximum number of lines, maybe it is a better solution to create all the controls at design time, set the Visible-property to false and change it to true when needed.
You can add controls based on the label click in the UserForm code.
You'll have to maintain a count of rows in order to utilize that to position them neatly and to move this label from your example down (otherwise it'll be hidden behind the textboxes you add).
Sample code for the UserForm:
Private rowCount As Integer 'To keep track of rows.
Private Sub UserForm_Initialize()
rowCount = 1
End Sub
Private Sub LabelAddRow_Click() 'Event handler: Add row on click of label.
Dim tb As Control
rowCount = rowCount + 1
Set tb = Me.Controls.Add("Forms.TextBox.1", "textBox" & rowCount & "left", True) 'Add left TextBox.
With tb 'Position and size it:
.Top = 25 + (rowCount * 25) + 10
.Left = 25
.Height = 25
.Width = 100
End With
Set tb = Me.Controls.Add("Forms.TextBox.1", "textBox" & rowCount & "right", True) 'Same for the right one:
With tb
.Top = 25 + (rowCount * 25) + 10
.Left = 150
.Height = 25
.Width = 100
End With
LabelAddRow.Top = LabelAddRow.Top + 25 'Move the label down.
End Sub
You might want to add something to the height of the UserForm too, to make it grow with the added controls. Also you might want to reposition other controls that are below the TextBoxes.
If you want to automatically add rows when the last box has been filled out, you're going to need to add some events to the newly added controls, however that's not the main issue listed in the question.
Edit: The above is obviously based on your last image, since that's the "quick win"; dealing with the events of dynamically added TextBoxes will add additional complexity. If you decide to take that route, I suggest to have a go at this first and post new questions as they come along.

Macro query spread over multiple-sheets

Wording my question is slightly tricky so I've included screen-shots to make this easier. I have 2 separate spreadsheets which are currently not linked together in anyway. What I've been asked to do is:
For the drop-downs which have a * next to them, have this * drop-down get converted into a acronym (I.e. If it's Home Visit *, then this will be converted to HV), and have it automatically entered into Cell Position X. Please refer to Image 1 then Image 2)
So the user would click on Sheet one, select the relevant drop-down field and then assign how much time that task took. The second sheet would then update itself with this information - it would insert the users name, program and activities. This is where it gets very tricky. Based off the drop-down selection, if it is asterisked (*), then based off the field-type it will convert it into a set acronym which would then be placed in one of the data fields based off the entry date that has been provided.
I designed both spread-sheets and they have macros in the background, but I can't seem to work out how to best perform this. Would you suggest a transpose function which checks firstly the date criteria and then an INDEX(MATCH) function to match the criteria against a pre-defined name-range which converts Home Visit etc. to HV automatically? I'm also unsure of how to insert delimiters for each new entry that is read. If anyone can provide help I would be very grateful.
I'm not 100% sure I understand your question, but here goes:
What about adding a Worksheet_Change event to look for changes in the drop-down's cell, and then converting it to an acronym?
Place the following code inside the sheet of interest:
Private Sub Worksheet_Change(ByVal Target As Range)
'If Cell A1 is changed, put the acronym into A2
If Target.Row = 1 And Target.Column = 1 Then
Cells(2, 1) = GetAcronym(Target.Value)
End If
End Sub
Function GetAcronym(TheText As String) As String
Dim result As String
Dim x As Long
'Always grab the first letter
result = Mid(TheText, 1, 1)
'Get the other letters
For x = 2 To Len(TheText) - 1
If Mid(TheText, x, 1) = " " Then result = result & Mid(TheText, x + 1, 1)
Next x
GetAcronym = UCase(result)
End Function