I am trying to call a function within my if statement. The function is called classyear and is just after the if. I am trying to run through a timetable and see what classes belong to each year. so if it ends in a 1 it will be counted. Does anyone know how I would go about calling the function? Any help is appreciated
Public Sub time()
Dim rgTimeTable As Range, rgClass As Range, counter As Integer
Set rgTimeTable = Range("B3, N11")
For Each rgClass In rgTimeTable
If rgClass.Value = classyear Then counter = counter + 1 ' classyear is the function
Next rgClass
MsgBox test ' also a function
End Sub
EDIT
Code for the function i am trying to call
Public Function classyear(class As String) As Integer
Dim yr As String
yr = Right(class, 1)
If IsNumeric(yr) Then classyear = yr Else classyear = 0
End Function
Your classyear function takes a string input, so you need to give it one. Something like:
If CInt(rgClass.Value) = classyear("Year1") Then counter = counter + 1
Also you can neaten up your classyear function:
Public Function classyear(class As String) As Integer
On Error Resume Next 'if error classyear will return 0
classyear = CInt(Right(class, 1))
End Function
You can call a Sub inside if block like:
(Use function if you want to return some value else use Sub)
if (...)
classyear() '<--Calling the Sub defined below
End if
Private Sub classyear()
.
.
End Sub
Hope this is what you are looking for.
Related
I am trying to return a value from a function but is not happening.
Public sub test()
x = 2
msgbox number(x)
Exit Sub
Public Function number(num)
if len(num) = 1 then
num = "0" + num
End if
End Function
The function is returning a null value.
You need to assign the result to the name of the function, and concatenate the 0, like this:
Public Function number(num) As String
if len(num) = 1 then
number = "0" & num
Else
number = num
End if
End Function
though it would seem easier to just use Format(num, "00")
Public function number(num as string) as string
If len(num) = 1 then
Number ="0" & num
Else
Number = num
End if
End function
You need to have code in the function that sets a value to the name of the function - the return value.
Pretty simple, but I couldn't find anything by Googling. An example of what I want to happen:
Function myFunc()
Dim a As Integer
Dim b As Integer
Dim c As Integer
a = 20000
b = 15000
c = a + b
myFunc = c
End Function
I want myFunc() to return -30536 instead of throwing an overflow exception. I know I could write a function that does that, but I've written a bunch of code for a project with the assumption that overflow was allowed, so I'm hoping there's a quick fix.
EDIT: I don't need help coming up with a function that solves the overflow issue with type conversions. I have one already; I just want to avoid changing hundreds of addition and subtraction operations. I'm also bit frustrated that VBA seems to go out of its way to disable overflow functionality--it should let the user decide if they want to use it or not.
I would suggest writing MyFunc to do the math as Long, and test for integer "overflow" and adjust
Function MyFunc(a As Integer, b As Integer) As Integer
Dim sum As Long
Const Mask As Integer = -1
sum = CLng(a) + CLng(b)
If sum > 32767 Then
sum = sum - 65536
ElseIf sum < -32768 Then
sum = sum + 65536
End If
MyFunc = sum
End Function
Test with
Sub zx()
Debug.Print MyFunc(20000, 15000)
End Sub
In order to prevent Integer overflow in your Excel VBA code, you may use the custom Function to perform the Integer to Long type casting like shown below:
Sub TestIntegerConversion()
Debug.Print myFuncLong(20000, 15000)
End Sub
Function myFuncLong(a As Integer, b As Integer) As Long
myFuncLong = CLng(a) + CLng(b)
End Function
or without using custom Function in a simple form like this:
Sub PreventOverflow()
Dim a As Integer
Dim b As Integer
a = 20000
b = 15000
Debug.Print CLng(a) + CLng(b)
End Sub
Alternatively, you may write your own custom function, which should implement that "overflow math" (you have somehow to specify using plain math notation how to get the number -30536 from 35000) and return the result either as Long, or String. Possible implementation is shown below (note: Overflow exception number is 6)
Sub OverflowCustomMath()
Dim a As Integer
Dim b As Integer
Dim c As Long
a = 20000
b = 15000
On Error GoTo Err:
Debug.Print a + b
Err:
If (Err.Number = 6) Then
'apply your custom overflow math, as for e.g.
Debug.Print CLng(a) + CLng(b)
End If
End Sub
Hope this may help.
Use typical VBA error handler but tests for your case.
Option Explicit
Sub test()
MsgBox myFunc
End Sub
Function myFunc()
On Error GoTo Local_err
Dim a As Integer
Dim b As Integer
Dim c As Integer
a = 20000
b = 15000
c = a + b
myFunc = c
Local_exit:
Exit Function
Local_err:
If Err = 6 Then
myFunc = -30536
Else
MsgBox Err & " " & Err.Description
' myFunc = whatever error value to return
End If
Resume Local_exit
End Function
Please help with the code error 424 below
Public counter As String
Private Sub Workbook_WindowActivate(ByVal Wn As Window)
If ActiveSheet1.Name = Sheet2.Name Then
If counter = 0 Or counter = Null Then
Call LLP_Hide
End If
End If
End Sub
Remove 1 from ActiveSheet1.
If counter is meant to count it should be declared as Integer type instead of String.
Anyway, this part of code will also cause error: counter = 0. Replace it with counter = "0" or change the type of counter.
Public counter As Integer
Private Sub Workbook_WindowActivate(ByVal Wn As Window)
If ActiveSheet.Name = Sheet2.Name Then
If counter = 0 Then
Call LLP_Hide
End If
End If
End Sub
I am attempting to do a VLOOKUP on a different worksheet based on given parameters in the function. I've played around with it for several hours and can not figure out why it is not working. I cut down the code as much as I could to test, but am unable to effectively find a solution. I think it might be an issue of how I am calling the range from the other worksheet for the VLOOKUP. Code is below. Please advice. If I'm unclear about what I'm asking just ask and I will provide feedback. Thank you
Function GraphDataA(cR As String, time As String, aClient As String, tps As String, dat As String)
Dim client As Boolean
Dim day As Boolean
Dim tot As Boolean
Dim dayTotData As Range
Dim dayTotDatas As Worksheet
Set dayTotDatas = ActiveWorkbook.Sheets("DayTot")
Set dayTotData = dayTotDatas.Range("A3:AI168")
client = False
day = False
tot = False
If date = "" Then
GraphDataA = ""
End If
If aClient = "" Then
GraphDataA = ""
End If
If cR = "Client" Then
client = True
End If
If time = "Day" Then
day = True
End If
If tps = "Total" Then
tot = True
End If
If client = True Then
If day = True Then
If tot = True Then
GraphDataA = WorksheetFunction.VLookup(aClient, dayTotData, WorksheetFunction.Match(dat, dayDate, 0) + 8, _
False)
End If
End If
End If
End Function
VLOOKUP() will throw an error if nothing matches. So you need to add error catching code to your function.
You need to modify the function as
Function MyFunction() as Something
On Error Goto ErrorHandler
' Your existing code goes here
Exit Function
ErrorHandler:
MyFunction = -1 ' Or something which indicates that the value isn't found
End Function
You don't appear to be returning any value from your function. Try adding As Variant to the end of the first line like so:
Function GraphDataA(cR As String, time As String, aClient As String, tps As String, dat As String) As Variant
I searched the website but was not succesfful and tried doing some research on this but facing with " Type Mismatch" error.
I declared an array as integer type but the FILTER function seems to work only with STRING's. Can you please let me know how I can use the FILTER function for integers?
If UBound(Filter(CntArr(), count)) > 0 Then
msgbox "found"
End If
as i understand you need to know if specified count present in array. You can use for loop for it:
Dim found as Boolean
found = False
For i = 0 To UBound (CntArr())
If CntArr(i) = count Then
found = True
Exit For
End If
Next i
If found Then msgbox "found" End If
Below I have created IsIntegerInArray() function that returns boolean. Follow the two Subs for an example of integer array declaration. Declaring array as Integer should also prevent some unnecessary bugs caused by implicit data conversion.
Sub test_int_array()
Dim a() As Integer
ReDim a(3)
a(0) = 2
a(1) = 15
a(2) = 16
a(3) = 8
''' expected result: 1 row for each integer in the array
Call test_printing_array(a)
End Sub
Sub test_printing_array(arr() As Integer)
Dim i As Integer
For i = 1 To 20
If IsIntegerInArray(i, arr) Then
Debug.Print i & " is in array."
End If
Next i
End Sub
Function IsIntegerInArray(integerToBeFound As Integer, arr() As Integer) As Boolean
Dim i As Integer
''' incorrect approach:
''' IsIntegerInArray = (UBound(Filter(arr, integerToBeFound)) > -1) ' this approach searches for string, e.g. it matches "1" in "12"
''' correct approach:
IsIntegerInArray = False
For i = LBound(arr) To UBound(arr)
If arr(i) = integerToBeFound Then
IsIntegerInArray = True
Exit Function
End If
Next i
End Function