VBA Excel - Mantaining Public Variables With Button Press - excel

I'm trying to Create a document that has a bunch o constant strings.
I've declared then Public in a Module like this:
Public Abc As String
In "ThisWorkbook" I run the following code to initialize de variable
Private Sub Workbook_Open()
Abc = "C5"
End Sub
I have Buttons coded to change some values like:
If Range(Abc) = "" Then
Range(Abc) = 1
Else
Range(Abc) = Range(Abc) + 1
End If
When I run a button with this code:
Sub BotaoNovoDia()
i = 3
While i <= 33
If Cells(i, 11) = "" Then
Cells(i, 11) = Range(Apresentacao)
Cells(i, 12) = Range(Aceitacao)
Cells(i, 13) = Range(Aceitou)
Cells(i, 31) = Range("D41")
Cells(i, 11).Interior.Color = Range(Apresentacao).Interior.Color
Cells(i, 12).Interior.Color = Range(Aceitacao).Interior.Color
If Range("K34") < 0.65 Then
Range("K34").Interior.Color = vbRed
Else
Range("K34").Interior.Color = vbGreen
End If
If Range("L34") < 0.45 Then
Range("L34").Interior.Color = vbRed
Else
Range("L34").Interior.Color = vbGreen
End If
Range(Aceitou) = 0
Range(Rejeitou) = 0
Range(NaoApres) = 0
End
Else
i = i + 1
End If
Wend
End Sub
And i try to run the first button again I get and error saying: "Run-Time error '1004': Method 'Range' of object '_Global' failed"
the debug button takes me to the fisrt line that tries to access to the public variables value. What can i do to mantain the values in the Public variables?

When you call End (By itself, not as part of End If, etc) you clear your Globals.
Don't use End.

Using a named range is a great idea; but there's no reason why your public declaration shouldn't work - except for that pesky End statement. (I missed that first read through...)
However, your scope isn't clear in each of your functions, e.g. which worksheet is the Range referring to, so if one function works on another worksheet, pushing the button that fires "Change" could refer to a different place that doesn't like that reference.
e.g. your ranges should be something like SomeWorkbook.TheWorksheet.Range(<range>) and when you're changing the cell value, you should use .Value to ensure there's no ambiguity - you'll know from searching through here that error 1004 is the least descriptive error code...

Related

VBA Excel Run-time error '438' Object doesn't support this property or method when using with msforms.TextBox

I'm trying to make a more functional search application to use on Excel. The idea is to be able to perform a search of a user-specified set of key words in cells that contain target text that can have up to 600 words. The application would locate all cells with at least one match and displays the entire content of the cell in a textbox (in this case textbox7 in UserForm1) and would highlight the matching words in orange colored text for quick identification of the context of the key words within the target text.
For some reason I get an error message reading "Run-time error '438': Object doesn't support this property or method" and it highlights the line in my code reading: "With sh.TextBox".
Below I've included a copy of the code with the section where this error is occurring. From what I can see it looks like the error is the result of the way I've dimensioned variable "sh" (i.e as msforms.TextBox)
Ultimately what I need to achieve is something that will allow the use of "Characters" object which is a crucial part of this application because it locates the key words that have been found in the target text so that the font color can be changed to orange (and bold text).
I would be very grateful if someone can point out what the issue is and how I can go about resolving it. Thanks in advance.
Private Sub CommandButton2_Click()
'code below displays all email items found with at least one word match
Dim Position As Long
Dim EmlCharacterLength As Long
Dim KeyWordCharacterLength As Long
Dim sh As msforms.TextBox
Set sh = UserForm1.TextBox7
SlotCount2 = 0
If RA1Counter < NmbrItemsFound Then
Do While ResultsArray1(1, RA1Counter) = ResultsArray1(1, RA1Counter + 1)
RA1Counter = RA1Counter + 1
Loop
EmailCntr = EmailCntr + 1
TextBox2.Value = EmailCntr & " of " & NmbrEmails
TextBox3.Value = CorroArray(5, ResultsArray1(1, RA1Counter))
TextBox4.Value = CorroArray(2, ResultsArray1(1, RA1Counter))
TextBox5.Value = CorroArray(3, ResultsArray1(1, RA1Counter))
TextBox6.Value = CorroArray(0, ResultsArray1(1, RA1Counter))
TextBox7.Value = CorroArray(4, ResultsArray1(1, RA1Counter))
EmlCharacterLength = Len(CorroArray(4, ResultsArray1(1, RA1Counter)))
Do While SlotCount2 < NbrKeyWords + 1
Position = 1
KeyWordCharacterLength = Len(SplitKeyWords(SlotCount2))
Do While Position < EmlCharacterLength
Position = InStr(Position, CorroArray(4, ResultsArray1(1, RA1Counter)), SplitKeyWords(SlotCount2), 1)
With sh.TextBox
.Characters(Start:=Position, Length:=KeyWordCharacterLength).Font.Bold = True
.Characters(Start:=Position, Length:=KeyWordCharacterLength).Font.Color = RGB(255, 102, 0)
End With
Position = Position + KeyWordCharacterLength
Loop
SlotCount2 = SlotCount2 + 1
Loop
RA1Counter = RA1Counter + 1
Else
RA1Counter = 1
EmailCntr = 0
End If
End Sub

Change label's caption with loop in a VBA userForm

I want my code to loop through a range of cells and every time show the content of the cell (that is a question) in a label's caption of a userForm and allow the user to choose the button of "Yes" (for knowing the answer) or "NO" (for not knowing the answer) and then the code use the user's response to perform some actions and then continue the loop for other cells.
For each iteration in for loop i need user be allowed to choose "Yes" or "No" or "Cancel" and then the userForms code continue running.
Here is some of the code:
Private Sub UserForm_Activate()
For i = 2 To n
Cells(i, 3) = Cells(i, 3) + 1
If Cells(i, 3) = 1 Then
UserForm1.Controls("question").Caption = Cells(i, 1).Value 'lable 1
UserForm1.Controls("answer").Caption = "" 'lable 2
'some codes...
elseIf Cells(i, 3) = 3 Then
UserForm1.Controls("question").Caption = Cells(i, 1).Value 'lable 1
UserForm1.Controls("answer").Caption = "" 'lable 2
next
end sub
and i need to run these codes whenever user clicks on a button on the form . then the rest of the above code be executed .
Private Sub ansYes_Click() 'If user clicks Yes show the answer and continue
UserForm1.Controls("answer").Caption = Cells(i, 2)
UserForm1.Controls("answer").Visible = True
End Sub
Private Sub ansNo_Click() 'If user clicks No show the answer and continue
UserForm1.Controls("answer").Caption = Cells(i, 2)
UserForm1.Controls("answer").Visible = True
Cells(i, 3) = 0
Cells(i, 4) = 1
End Sub
Private Sub ansCancel_Click() 'If user clicks cancel unload userform and exit the for loop
Unload UserForm1
End Sub
You haven't shown us where you show the UserForm or how it is defined within your project and you haven't given a good description of the problem. This forces assumptions that may not be accurate.
Do not name your UserForm "UserForm1", give it a useful name. Henceforth, I will refer to this as "UserResponseForm"
Do not use default instance of a UserForm, use a variable and learn the difference between Dim As and Dim As New. The difference is significant and important.
Dim myForm As UserResponseForm
Dim myForm As New UserResponseForm
Using UserResponseForm's property window, find and rename your labels "Question" and "Answer"
In UserResponseForm's code use Ctrl + H to replace:
UserForm1.Controls("answer") with Me.Answer
and
Unload UserForm1 with Me.Hide
Move all of your code from Private Sub UserForm_Activate to a normal module. Give the module and the sub a useful name. I will refer to module as "QuestionaireCodeModule" and the sub as "RunTheQuestionnaire"
The QuestionaireCodeModule should look similar to this
Option Explicit
Private Const n As Long = 20 'you didn't show how n was populated or scoped so I put it here
Sub RunTheQuestionaire()
Dim i As Long
Dim myForm As New UserResponseForm
For i = 2 To n
Cells(i, 3) = Cells(i, 3) + 1
If Cells(i, 3) = 1 Or Cells(i, 3) = 3 Then 'added or condition for clarity
myForm.Question.Caption = Cells(i, 1).Value 'lable 1
myForm.Answer.Caption = vbNullString 'lable 2
'some codes...
'next three lines removed because they are redundant
'elseIf Cells(i, 3) = 3 Then
'UserForm1.Controls("question").Caption = Cells(i, 1).Value 'lable 1
'UserForm1.Controls("answer").Caption = "" 'lable 2
End If
myForm.Show
If Not myForm.Visible Then Exit For
Next i
End Sub
That should be it but I can't say if this will work for you or not because you did not provide enough to work with and the code you provided in your example won't compile.

Pass Arguments through Onaction with CheckBoxes

So i have been at this for a while now and I have searched through many websites and forums but alas I can not find a solution to my issue.
I am trying to add arguments to an .OnAction event for a Checkbox
So.. For example
Dim chk as Checkbox
With chk
.name = "chk" & .TopLeftCell.Offset(0, -7).Text
.Caption = ""
.Left = cel.Left + (cel.Width / 2 - chk.Width / 2) + 7
.Top = cel.Top + (cel.Height / 2 - chk.Height / 2)
.OnAction = "CheckboxHandle(chk)"
End With
So if I was trying to call this sub -> Public Sub CheckboxHandle(obj As CheckBox)
It requries a CheckBox Object to be able to run (this can change to a shape/Object if necessary)
THINGS I HAVE TRIED
Changing the data type to object and shape however i couldn't find a way to pass it through
Variations of the below statements
"""CheckboxHandle(chk)"""
"'CheckboxHandle" ""chk"" '"
Application.caller then looping through objects to find the object whit that name (this takes way too long as I have over 300 Checkboxes)
CONTEXT
In case the context helps I am trying to add a checkbox to every cell in a range and then have each one call the same method when they are clicked. I need the OnAction to send an Object as i look for the TopleftCell of the Object to change the colour of the adjacent cells
IN CASE IT IS HELPFUL
here is the method i would like to call from the OnAction Event
Public Sub CheckboxHandle(obj As CheckBox)
Dim rng As Range
'Sneaky sneaky changes
Application.ScreenUpdating = False
'For Loop to go through each of the cells to the left of the check box
For Each rng In Range(obj.TopLeftCell, obj.TopLeftCell.Offset(0, -7))
With rng
'if the checkbox is checked
If obj.Value = -1 Then
.Interior.Color = RGB(202, 226, 188)
'Adds the date and the person so you know who did the edit
obj.TopLeftCell.Offset(0, 1).Value = Now & " by " & Application.username
Else
'if it isn't checked
.Interior.Pattern = xlNone
'removes the edit name and date
obj.TopLeftCell.Offset(0, 1).Value = ""
End If
End With
Next rng
'Shows all the changes at the same time
Application.ScreenUpdating = True
'Changes the value of the progress bar to represent the project completion
If obj.Value = -1 Then
ActiveSheet.Range("E1").Value = ActiveSheet.Range("E1").Value + 1 / 207
Else
ActiveSheet.Range("E1").Value = ActiveSheet.Range("E1").Value - 1 / 207
End If
End Sub
Any help on this issue would be much appreciated
-Sebic0
I don't think that you can pass an object via the OnAction. The OnAction-property is a string holding the name of a Sub (plus parameter).
You could try to pass the name of the checkBox instead. Note that you have to enclose the name of the checkbox in double quotes, so that you would get something like. CheckboxHandle "chk123":
.OnAction = "'CheckboxHandle """ & .Name & """'"
And change your Action-routine
Public Sub CheckboxHandle(chbBoxName as string)
dim chk as CheckBox
Set chk = ActiveSheet.CheckBoxes(chkBoxName)
(...)

VBA-Object Required Error

I was writing a function with ws declared already. It works well under the private sub of the command button but when i extract it as a function it shows the object required error. The file is too large and I must make it as a function and call it but the error stopped my program running.
Could anyone please help me thanks a lot.
If Month(ws.Cells(j, 11)) = "a" And Year(ws.Cells(j, 11)) = ComboBox1.Text Then 'this sentence error
If ws.Cells(j, 5) <> "-" Then 'this sentence also error if I deleted the above one
n = 2
Else: n = 1
End If
p = 1

Dealing with Dropdowns in Excel

I want my worksheet to interact with the user input through the dropdown. Basically I need to copy and paste columns of data according to the input via the dropdown button.
This is my code
Sub DropDown84_Change()
If ActiveSheet.DropDowns("Drop Down 84").Value = 1 Then
Sheets("data").Range("N28:N30").Value = Sheets("data").Range("E48:B50").Value
ElseIf ActiveSheet.DropDowns("Drop Down 84").Value = 2 Then
Sheets("data").Range("N28:N30").Value = Sheets("data").Range("F48:F50").Value
ElseIf ActiveSheet.DropDowns("Drop Down 84").Value = 3 Then
Sheets("data").Range("N28:N30").Value = Sheets("data").Range("G48:G50").Value
ElseIf ActiveSheet.DropDowns("Drop Down 84").Value = 4 Then
Sheets("data").Range("N28:N30").Value = Sheets("data").Range("H48:H50").Value
Else: Sheets("data").Range("N28:N30").Value = Sheets("data").Range("J48:J50").Value
End If
End Sub
I receive a message
"Runtime error 1004, Unable to get the DropDowns property of the worksheet class"
Please help,
I hope you use ActiveX for this:
Sub ComboBox84_Change()
Select Case ActiveSheet.ComboBox84.Value
Case 1
Sheets("data").Range("N28:N30").Value = Sheets("data").Range("E48:B50").Value
Case 2
Sheets("data").Range("N28:N30").Value = Sheets("data").Range("F48:F50").Value
Case 3
'-- do for all of your cases--
End Select
End Sub

Resources