Getting 424 Runtime error, object required - vba

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

Related

Passing Values in VBA

In the code I am posting, I am using a check box called "ACDS Test" and whenever it is checked it creates a sheet, then when it becomes unchecked it calls the upper function and deletes the sheet.
I am trying to add a message box that essentially works like a fail safe to ensure they want to delete the page. If they say they do not want to delete the page then I want the checkbox to stay checked.
For some reason I am getting this error message when I try to pass the value to make sure the checkbox stays checked and I cannot figure out why.
The error comes up on the line:
Sub ACDSTest_Click(CorrectValue As Integer)
And the specific error is: "Compile error: Procedure Declaration does not match description of event or procedure having the same name".
Any help is much appreciated! IF any more clarification is needed please feel free to ask!
Sub DeleteWorksheet(NameSheet As String)
Dim Ans As Long
Dim t As String
Dim CorrectValue As Integer
Dim i As Long, k As Long
k = Sheets.Count
Ans = MsgBox("Would you like to take this test off of the form?", vbYesNo)
Select Case Ans
Case vbYes
'Code reads through each page and finds one with corresponding name to string t
'Once it finds the correct page, it deletes it
For i = k To 1 Step -1
t = Sheets(i).Name
If t = NameSheet Then
Sheets(i).Delete
End If
Next i
CorrectValue = 0
Case vbNo
CorrectValue = 1
End Select
End Sub
Sub ACDSTest_Click(CorrectValue As Integer)
Dim NameSheet As String
Dim NameValue As String
NameSheet = "ACDS"
NameValue = "ACDS Test"
If ACDSTest.Value = True Then
CreateWorksheet (NameSheet), (NameValue)
Worksheets("Sheet1").Activate
Else
DeleteWorksheet (NameSheet)
If CorrectValue = 1 Then
ActiveSheet.Shapes("ACDS Test").ControlFormat.Value = 1
End If
End If
End Sub
The issue here is that the CorrectValue variable as you define it in DeleteWorksheet does not exist in the context of the
variable does not exist in context of the ACDSTest_Click subroutine. This is because variables defined within subroutines or functions are local to those functions. To correct this I would convert DeleteWorksheet to a function such as the below.
Further, the event that fires Private Sub ACDSTest_Click() cannot handle passing a value to that function, so changing it to Sub ACDSTest_Click(CorrectValue As Integer) causes an error.
Function DeleteWorksheet(ByVal SheetName As String) As Boolean
On Error GoTo SheetDNE
SheetName = Sheets(SheetName).Name 'Check if sheet exists w/o other objects
On Error GoTo 0
Select Case MsgBox("Would you like to take this test off of the form?", vbYesNo)
Case vbYes
Application.DisplayAlerts = False
Sheets(SheetName).Delete
Application.DisplayAlerts = True
DeleteWorksheet = True
Case Else: DeleteWorksheet = False
End Select
Exit Function 'Exit The Function w/o error
SheetDNE: 'Sheet Does Not Exist
MsgBox "The indicated sheet, " & SheetName & ", does not exist", vbOKOnly
End Function
And
Private Sub ACDSTest_Click()
Dim NameSheet As String
Dim NameValue As String
NameSheet = "ACDS"
NameValue = "ACDS Test"
If ACDSTest.Value = True Then
CreateWorksheet (NameSheet), (NameValue)
Worksheets("Sheet1").Activate
Else
If Not DeleteWorksheet(NameSheet) Then _
ActiveSheet.Shapes("ACDS Test").ControlFormat.Value = 1
End If
End Sub

how to call a function within an if statement (vba)

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.

catvba, false positive if statement

Unfortunately, sometimes when the if statements are more complex, behavior is quite strange, here is a copy of the line which doesnt work as expected when used like this
If someFunction(arg1, arg2, CreatedFromClass(arg3, arg4, arg5)) Then GoTo err1
someFunction(...) itself has return type long, but in this case is absolutely always evaluated as positive, even though someFunction before return contains 0 as a return value.
so, it can be wrapped as any of the following and result will be always true
If someFunction() = True Then
If someFunction() = False Then
If someFunction() = 0 Then
If someFunction() = 1 Then
If someFunction() <> 0 Then
If someFunction() <> 1 Then
If Not someFunction() = 0 Then
If Not someFunction() = 1 Then
If (someFunction() = 0) = False Then
If (someFunction() = 0) = True Then
If CBool(someFunction() = 0) = True Then
If CBool(someFunction() = 1) = True Then
but when is split into segments, and manually assigned to the variable, then works as expected
Dim rVal As Long
rVal = someFunction(arg1, arg2, CreatedFromClass(arg3, arg4, arg5))
If rVal Then GoTo err1
question is of course why the behavior is not the same? did someone experienced similar?
Additionally, after couple hours, i been able to isolate problematic piece of code!
Class: cls.cls
Option Explicit
Private mCol As Collection
Private Sub Class_Initialize()
Set mCol = New Collection
End Sub
Private Sub Class_Terminate()
Set mCol = Nothing
End Sub
Public Sub Add(iItem)
mCol.Add iItem
End Sub
Public Function DoCopy() As cls
Set DoCopy = New cls
Dim i As Long
For i = 1 To mCol.Count
DoCopy.Add mCol(i)
Next
End Function
and testing module
Option Explicit
Public Function CreateCls(ParamArray params()) As cls
Set CreateCls = New cls
If UBound(params) < 0 Then Exit Function
Dim i As Long
For i = LBound(params) To UBound(params)
CreateCls.Add params(i)
Next
End Function
Private Function doTest(iCls As cls) As Long
doTest = 0
End Function
Private Sub CATStart()
Dim x As cls
Set x = CreateCls("param1", "param2", "param3", "param4")
If doTest(x.DoCopy) = 0 Then Debug.Print "long_0"
If doTest(x.DoCopy) = 1 Then Debug.Print "long_1"
If CBool(doTest(x.DoCopy)) = True Then Debug.Print "bool_True"
If CBool(doTest(x.DoCopy)) = False Then Debug.Print "bool_False"
Set x = Nothing
End Sub
And of course all of them will be evaluated as True valid and result printed!
And yes, i found an answer on my question, in Catia, i have VBA version 7.1.1033, which doesn't work as expected, while the the same piece of code works in Excel, which uses newer VBA version, 7.1.1049...
So answer is, VBA has bug in that release..

Public variable value reset when called in another module, Excel VBA

In Excel, I have two modules, let's say module1 and module2.
In module1, I have declared a public variable:
Public offsetNumber As Integer
Within the sub, I assign a number to the 'offsetNumber' variable.
offsetNumber = 2
Msgbox offsetNumber
This successfully displays the number 2.
Now, in module2, I try to call the variable offsetNumber.
Msgbox offsetNumber
However, the value displayed is 0, not 2.
How can I carry over the variable value from module1 to module2?
UPDTATE:
I've tried the module1.offsetNumber and checking "require variable declarations". I've also checked to make sure that the value is not being overwritten (at least in module1).
To be more in depth, this is how my module1 is currently structured:
Public offsetNumber as Integer
Sub **********
Dim .... (declare variables)
Activecell.EntireRow.Select
currentRow = ActiveCell.Row
offsetNumber = currentRow - 48
Msgbox offsetNumber (returns correct value)
........... (misc code)
Msgbox offsetNumber (returns correct value)
End Sub
This is how my module2 is structured:
Sub *********
Dim ..... (declare variables)
.............. (misc code)
Msgbox offsetNumber (returns 0)
For rowCounter = 2 to lastRow
If Sheets("****").Cells(rowCounter, 3) = ****** Then
Sheets("****").Activate
Rows(rowCounter + offsetNumber).Select
End If
Next rowCounter
End Sub
In "Immediate" window after executing module1, the following line
? offsetNumber
returns a value of 0.
SOLUTION:
This is what worked for me:
Module1:
Public globalOffsetNumber as Integer
Sub **********
Dim .... (declare variables)
Activecell.EntireRow.Select
currentRow = ActiveCell.Row
offsetNumber = currentRow - 48
globalOffsetNumber = offsetNumber (new line)
Msgbox offsetNumber (returns correct value)
........... (misc code)
Msgbox offsetNumber (returns correct value)
End Sub
Module2:
Sub *********
Dim ..... (declare variables)
.............. (misc code)
Msgbox globalOffsetNumber (now returns correct value)
For rowCounter = 2 to lastRow
If Sheets("****").Cells(rowCounter, 3) = ****** Then
Sheets("****").Activate
Rows(rowCounter + globalOffsetNumber).Select
End If
Next rowCounter
End Sub
You don't have to do anything for a public variable which is declared in one module to be accessible in another. Try this experiment:
In module 1 have:
Option Explicit
Public s As String
Sub setvar()
s = "Hi"
End Sub
In module 2 have:
Sub readvar()
Debug.Print s
End Sub
If you first run setvar and then immediately run readvar you should see "Hi" displayed in the immediate window.
My guess is that you are somehow or other resetting the project after running your first sub but before running the second.
I add the same issue,
do not put "Public s As String" in module 2.
Definition resets variable.

FILTER Function for integers - VBA

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