VBA code in Excel, Argument not optional, CountIf Error - vba

I created a code to find instances of the number 1 in column A in Sheet27 but it keeps giving the error 'argument not optional' and highlighting the CountIf part of the code. I want this information to be displayed as a msgbox.
Private Sub CommandButton1_Click()
Dim instances As Long
instances = WorksheetFunction.CountIf(Sheets("Sheet27")(Columns("A:A"), "1"))
MsgBox "We Found " & instances & " instances of ", vbInformation, "Alert"
End Sub

Try...
instances = WorksheetFunction.CountIf(Sheets("Sheet27").Columns("A:A"), "1")

Related

Problems with MS Word DocVariables defined in VBA

Background: a proprietary piece of veterinary software generates a document pre-populated with merge fields containing data for a particular patient.
The field I am interested in is weight but its a string (Top_Stat) that looks like this "24.5 kg".
I have created a script to read that field and convert it into an integer. However I now want to use this integer to male medication dose calculations based on the animal weight.
As create document variables for this but the variable (name and value) gets stored in the document. I want at least the value to be removed but can't seem to get the result with the following script.
Sub GetWeight()
ActiveDocument.Variables("WeightInKg").Delete
WeightInt = ActiveDocument.MailMerge.DataSource.DataFields("Top_Stat").Value
WeightInt = Replace(WeightInt, " kg", "") 'This removes the superfluous text
WeightInt = Val(WeightInt) 'This converts the weight into a number (integer)
ActiveDocument.Variables.Add Name:="WeightInKg", Value:=WeightInt 'Add the Word variable
ActiveDocument.Fields.Update
End Sub
What am I missing? Apologies, I am new to VBA.
Your code needs some error checking. This first time it is run the document variable "WeightInKg" does not exist and when you go to delete it, the routine errors out.
Document variables, not to be confused with VBA Subroutine variables are not Word document fields so unless you have another reason for updating all fields, that code line is unnecessary.
Finally, you should always declare your VBA Subroutine variables.
I have modified your code but could not fully test it because I don't have your mail merge data source ... but give it a try and see if it now works for you.
Sub AutoOpen()
Call GetWeight
End Sub
Sub GetWeight()
Dim WeightIn As Long
On Error Resume Next
ActiveDocument.Variables("WeightInKg").Delete
On Error GoTo ErrHandler
WeightInt = ActiveDocument.MailMerge.DataSource.DataFields("Top_Stat").Value
WeightInt = Replace(WeightInt, " kg", "") 'This removes the superfluous text
WeightInt = Val(WeightInt) 'This converts the weight into a number (integer)
ActiveDocument.Variables.Add Name:="WeightInKg", Value:=WeightInt 'Add the Word variable
' ActiveDocument.Fields.Update
ErrHandler:
If Err.Number > 0 Then
MsgBox Err.Number & vbCr & Err.Description, vbCritical
Err.Clear
End If
End Sub
This is the screenshot of the Word document I am trying to populate.
Screenshot

Excel (Office 365) restarts automatically while executing UDF

Thanks in advance for your help.
I am not sure where the problem in my UDF but the excel restarts automatically after executing the program and also shows MsxBox twice with the reference value.
Public queryString As String
Public Function SetIt(RefCell) As String
On Error GoTo CatchBlock
MsgBox RefCell.Value
queryString = RefCell.Value
RefCell.Parent.Evaluate "SetValue(" & RefCell.Address(False, False) & ")"
GoTo Finally
CatchBlock:
MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical, "Error in Function"
Finally:
SetIt = ""
End Function
// For now I am trying to set the cell reference value in some other cell.
Sub SetValue(RefCell As Range)
RefCell.Offset(1, 1).Value = queryString
End Sub
I am still beginner and need to accomplish another big task based on this program code execution.
Please help !!
Excel 64 bit & Office 365 is my environment

Call a VBA sub using a string value [duplicate]

This question already has an answer here:
Dynamic Function Calls in Excel VBA
(1 answer)
Closed 7 years ago.
This is my test code
Sub dotask()
Dim qusub As String
qusub = Worksheets("Task List").Range("C2").Value
MsgBox qusub
Application.Run qusub
End Sub
Sub msg1()
MsgBox "sub msg1"
End Sub
Sub msg2()
MsgBox "sub msg2"
End Sub
Sub msg3()
MsgBox "sub msg3"
End Sub
Sub msg4()
MsgBox "sub msg4"
End Sub
All of this is contained in a single standard module. I've read Trying to call a Sub with a String - VBA and wrote my code according to what I found there (i.e. using Application.Run). Cell C2 of Task List worksheet contains "msg3" at the moment. When I execute sub "dotask" I first get a message box saying "msg3" as I want but then I get the following error message:
Run-time error '1004':
Cannot run the macro 'msg3'. The macro may not be available in this workbook or all macros may be disabled.
I'm working on Excel 2010 and the file is .xlsm - what should I do to get my code to execute as I want it?
just ran it over here. msg1 seems to be a reserved word... change it to something else and it works fine =)
Using GetRef, you give the reference to the sub.
See my question here for example
EDIT: following the suggestions in the comments, here part of the solution to this question.
sub one(para)
WScript.Echo para & " from one"
end sub
sub two(para)
WScript.Echo para & " from two"
end sub
sub main(subname, para)
Dim f : Set f = GetRef(subname)
f para
end sub
main "one", "test" '=>test from one

VBA Error 1004 When Calling A Module with an Argument

This is my first post so bear with me.
I get a run-time error 1004 when I try calling a module from my user form and passing on an argument. I'm sure the answer is pretty obvious but I'm new to passing on arguments.
From User Form when clicking submit button:
Sub SubmitButton_Click()
Dim addRowValue As Integer
addRowValue = LineBox.Value
MsgBox "Add " & addRowValue & " rows."
Call Sheet1.ResizeTable(addRowValue)
End Sub
From Sheet1:
Sub ResizeTable(addRowValue As Integer)
Dim rng As Range
Dim tbl As ListObject
Set tbl = ActiveSheet.ListObjects("DATA_INPUT")
Set rng = Range("DATA_INPUT[#All]").Resize(tbl.Range.Rows.Count + _
addRowValue, tbl.Range.Columns.Count)
tbl.Resize rng
End Sub
Call Sheet1.ResizeTable works fine but when I add the argument is when I get the error. Also, the module ResizeTable() works fine when I change the variable addRowValue to a set number and run it.
Thanks for any help!
Problem is you are assigning a string to variable of type integer.
Change
addRowValue = LineBox.Value
To
addRowValue = CInt(LineBox.Value)
EDIT: You might also want to ensure the user enters a numeric value so have something like:
If IsNumeric(LineBox.Value) Then
addRowValue = CInt(LineBox.Value)
Else
MsgBox "Please enter numeric value", vbCritical
LineBox.Value = ""
End If

Error 9: Subscript out of range

I have a problem in excel Vba when I try to run this code, I have an error of subscript out of range:
Private Sub UserForm_Initialize()
n_users = Worksheets(Aux).Range("C1").Value
Debug.Print Worksheets(Aux).Range("B1:B" & n_users).Value
ListBox1.RowSource = Worksheets(Aux).Range("B1:B" & n_users).Value
ComboBox1.RowSource = Worksheets(Aux).Range("B1:B" & n_users).Value
ComboBox2.RowSource = Worksheets(Aux).Range("B1:B" & n_users).Value
End Sub
And Debug.Print works well, so the only problem is in Range("B1:B" & n_users).Value.
If the name of your sheet is "Aux", change each Worksheets(Aux) reference to Worksheets("Aux"). Unless you make Aux a string variable, for example:
Dim Aux As String
Aux = "YourWorksheetName"
n_users = Worksheets(Aux).Range(C1).Value
you must use quatations around sheet references.
Firstly, unless you have Aux defined somewhere in the actual code, this will not work. The sheet-name reference must be a string value, not an empty variable (which ARich explains in his answer).
Second, the way in which you are trying to populate the rowsource value is incorrect. The rowsource property of a combobox is set using a string value that references the target range. By this I mean the same string value you would use in an excel formula to reference a cell in another sheet. For instance, if your worksheet is named "Aux" then this would be your code:
ComboBox1.RowSource = "Aux!B1:B" & n_users
I think you can also use named ranges. This link explains it a little.
I can't see how you can get an Error 9 on that line. As others have pointed out repeatedly, the place you'll get it is if the variable Aux doesn't have a string value representing the name of a worksheet. That aside, I'm afraid that there is a LOT wrong with that code. See the comments in the below revision of it, which as near as I can figure is what you're trying to get to:
Private Sub UserForm_Initialize()
'See below re this.
aux = "Sheet2"
'You should always use error handling.
On Error GoTo ErrorHandler
'As others have pointed out, THIS is where you'll get a
'subscript out of range if you don't have "aux" defined previously.
'I'm also not a fan of NOT using Option Explicit, which
'would force you to declare exactly what n_users is.
'(And if you DO have it declared elsewhere, I'm not a fan of using
'public variables when module level ones will do, or module
'level ones when local will do.)
n_users = Worksheets(aux).Range("C1").Value
'Now, I would assume that C1 contains a value giving the number of
'rows in the range in column B. However this:
'*****Debug.Print Worksheets(aux).Range("B1:B" & n_users).Value
'will only work for the unique case where that value is 1.
'Why? Because CELLS have values. Multi-cell ranges, as a whole,
'do not have single values. So let's get rid of that.
'Have you consulted the online Help (woeful though
'it is in current versions) about what the RowSource property
'actually accepts? It is a STRING, which should be the address
'of the relevant range. So again, unless
'Range("B1:B" & n_users) is a SINGLE CELL that contains such a string
'(in which case there's no point having n_users as a variable)
'this will fail as well when you get to it. Let's get rid of it.
'****ListBox1.RowSource = Worksheets(aux).Range("B1:B" & n_users).Value
'I presume that this is just playing around so we'll
'ignore these for the moment.
'ComboBox1.RowSource = Worksheets(aux).Range("B1:B" & n_users).Value
'ComboBox2.RowSource = Worksheets(aux).Range("B1:B" & n_users).Value
'This should get you what you want. I'm assigning to
'variables just for clarity; you can skip that if you want.
Dim l_UsersValue As Long
Dim s_Address As String
l_UsersValue = 0
s_Address = ""
'Try to get the n_users value and test for validity
On Error Resume Next
l_UsersValue = Worksheets(aux).Range("C1").Value
On Error GoTo ErrorHandler
l_UsersValue = CLng(l_UsersValue)
If l_UsersValue < 1 Or l_UsersValue > Worksheets(aux).Rows.Count Then
Err.Raise vbObjectError + 20000, , "User number range is outside acceptable boundaries. " _
& "It must be from 1 to the number of rows on the sheet."
End If
'Returns the cell address
s_Address = Worksheets(aux).Range("B1:B" & n_users).Address
'Add the sheet name to qualify the range address
s_Address = aux & "!" & s_Address
'And now that we have a string representing the address, we can assign it.
ListBox1.RowSource = s_Address
ExitPoint:
Exit Sub
ErrorHandler:
MsgBox "Error: " & Err.Description
Resume ExitPoint
End Sub