DLL "'-t" gives Run-time error 424: Object Required - vba

I am using a simple timer which tells me the time elapsed between performing the same calculation with different data types. When I run this I get the error:
Run-time error '424':
Object required
The troublesome line:
target_sheet.Range("A2").Value = -t
Here is all of my code:
Public Declare Function GetTickCount Lib "kernel32.dll" () As Long
Sub Function1_Var_RandNumCounter()
Dim Var_RandNum_X, Var_RandNum_Y, Count As Variant
For Count = 1 To Count = 1000000
Var_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Var_RandNum_Y = Rnd(Now)
Next Count
target_sheet.Range("A2").Value = -t
' MsgBox GetTickCount - t, , "Milliseconds"
Call Function1_Dec_RandNumCounter
End Sub
Sub Function1_Dec_RandNumCounter()
Dim Count, Var_RandNum_X, dec_RandNum_X, Var_RandNum_Y, dec_RandNum_Y
dec_RandNum_X = CDec(Var_RandNum_X)
dec_RandNum_Y = CDec(Var_RandNum_Y) ' convert these vals to decimals
For Count = 1 To Count = 1000000
dec_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
dec_RandNum_Y = Rnd(Now)
Next Count
target_sheet.Range("B2").Value = -t
' MsgBox GetTickCount - t, , "Milliseconds"
Call Function1_Int_RandNumCounter
End Sub
Sub Function1_Int_RandNumCounter()
Dim Count, Int_RandNum_X, Int_RandNum_Y
For Count = 1 To Count = 1000000
Int_RandNum_X = Rnd(Now)
Int_RandNum_Y = Rnd(Now)
Next Count
target_sheet.Range("C2").Value = -t
' MsgBox GetTickCount - t, , "Milliseconds"
Call Function1_Double_RandNumCounter
End Sub
Sub Function1_Double_RandNumCounter()
Dim Count, Dbl_RandNum_X, Dbl_RandNum_Y
For Count = 1 To Count = 1000000
Dbl_RandNum_X = Rnd(Now)
Int_RandNum_Y = Rnd(Now)
Next Count
target_sheet.Range("D2").Value = -t
' MsgBox GetTickCount - t, , "Milliseconds"
End Sub
Sub Function2_BarGraph()
' Put all of these vals in a 2D bar graph
End Sub

The probably reason is that you haven't assigned anything to variable target_sheet, so it is empty and when it is empty you cannot call its methods (i.e. Range) since it causes 'Run-time error 424 - Object required'.
You need to assign some worksheet to variable target_sheet before you use it for the first time, i.e.:
Set target_sheet = ActiveSheet
target_sheet.Range("A2").Value = -t

Related

How to stop numbers being repeated in this VBA script

I have found this VBA script (running in powerpoint) and I just wanted to know how to stop numbers from being repeated. I did some google searches and I think the solution would be to create an array, and have the selected number go into the array. The script would then generate a new number as long as it skips all numbers in the array.
I'm just not sure how to implement this as I do not know VBA.
here is the script:
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Dim chosenNum As Integer
Dim I As Integer
Dim k As Integer
Sub randomNumber()
lowRand = 1
maxRand = 10
Randomize
For k = 1 To 10
chosenNum = Int((maxRand - lowRand) * Rnd) + lowRand
With ActivePresentation.SlideShowWindow.View.Slide.Shapes(2).TextFrame.TextRange
.Text = chosenNum
End With
For I = 1 To 1
Sleep (50)
DoEvents
Next
Next
End Sub
Any thoughts? Thanks.
This will collect 10 unique single digit numbers (0 to 9) into a string and then split them into an array. As each is returned to the slide, 1 is added so the resut is 1 to 10.
Sub randomNumber()
Dim lowRand As Long, maxRand As Long, strNum As String, chosenNum As String
Dim k As Long, vNUMs As Variant
lowRand = 0: maxRand = 10: strNum = vbNullString
Randomize
For k = 1 To 10
chosenNum = Format(Int((maxRand - lowRand) * Rnd) + lowRand, "0")
Do While CBool(InStr(strNum, chosenNum))
chosenNum = Format(Int((maxRand - lowRand) * Rnd) + lowRand, "0")
Loop
strNum = strNum & chosenNum
Next k
vNUMs = Split(StrConv(strNum, vbUnicode), Chr(0))
For k = LBound(vNUMs) To UBound(vNUMs)
With ActivePresentation.SlideShowWindow.View.Slide.Shapes(2).TextFrame.TextRange
.Text = vNUMs(k) + 1
End With
For I = 1 To 1
Sleep (50)
DoEvents
Next
Next k
End Sub
I just wrote this to help you. The function is designed to return random integer numbers in the range you specify until all numbers in the range have been returned when it will then return -1. There is a test sub included to show how to use the function to get all numbers from 5 to 10.
'----------------------------------------------------------------------------------
' Copyright (c) 2015 YOUpresent Ltd.
' Source code is provide under Creative Commons Attribution License
' This means you must give credit for our original creation in the following form:
' "Includes code created by YOUpresent Ltd. (YOUpresent.co.uk)"
' Commons Deed # http://creativecommons.org/licenses/by/3.0/
' License Legal # http://creativecommons.org/licenses/by/3.0/legalcode
'----------------------------------------------------------------------------------
Option Explicit
Option Base 0 ' Explicitly set the lower bound of arrays to 0
Private iUsed As Integer ' count of all used numebrs
Public arrTracking() As String
'----------------------------------------------------------------------------------
' Purpose: Returns a random number in a specified range without repeats
' Inputs: iLow - integer representing the low end of the range
' iHigh - integer representing the high end of the range
' bReset - boolean flag to optionally reset the array
' Outputs: returns an integer number or -1 if all numbers have been used
' Example first call: myNum = GetRandomNumber(10, 5, true)
' Example subsequent call: myNum = GetRandomNumber(10, 5)
'----------------------------------------------------------------------------------
Function GetRandomNumber(iLow As Integer, iHigh As Integer, Optional bReset As Boolean) As Integer
Dim iNum As Integer ' random number to be generated
Dim InArray As Boolean ' flag to test if number already used
Randomize
' Reset the tracking array as required
If bReset Then ReDim arrTracking(iHigh - iLow)
' If we've used all of the numbers, return -1 and quit
If iUsed = iHigh - iLow + 1 Then
GetRandomNumber = -1
Exit Function
End If
' Repeat the random function until we find an unused number and then
' update the tracking array, uncrease the counter and return the number
Do While Not InArray
iNum = Fix(((iHigh - iLow + 1) * Rnd + iLow))
If arrTracking(iNum - iLow) = "" Then
arrTracking(iNum - iLow) = "used"
iUsed = iUsed + 1
InArray = True
GetRandomNumber = iNum
Else
'Debug.Print iNum & " used"
End If
Loop
End Function
'----------------------------------------------------------------------------------
' Purpose: Test sub to get all random numbers in the range 5 to 10
' Inputs: None
' Outputs: Debug output of 6 numbers in the range 5 to 10 in then immediate window
'----------------------------------------------------------------------------------
Sub GetAllRand()
Dim iRndNum As Integer
' Get the initial number, restting the tracking array in the process
iRndNum = GetRandomNumber(5, 10, True)
Debug.Print iRndNum
Do While Not iRndNum = -1
iRndNum = GetRandomNumber(5, 10)
Debug.Print iRndNum
Loop
End Sub
Here's a UDF that you can use to populate an array with unique random numbers:
Function GetRandomDigits(amount As Integer, maxNumber As Integer) As Variant
With CreateObject("System.Collections.ArrayList")
Do
j = WorksheetFunction.RandBetween(1, maxNumber)
If Not .Contains(j) Then .Add j
Loop Until .Count = amount
GetRandomDigits = .ToArray()
End With
End Function
And here's an example of how to use it:
Sub MM()
Dim nums As Variant
nums = GetRandomDigits(10, 100)
For Each num In nums
Debug.Print num
Next
End Sub

Getting 424 Runtime error, object required

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

VBA QueryPerformanceCounter Not Working

I am trying to test the execution time differences between data types after looping through 1 million random numbers per data type (integer, double, decimal, and variant). I took this code from the Microsoft Developer website. I am using Excel 2010.
Here is the code:
Option Explicit
Sub Function1()
Module Module1
Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef X As Long) As Short
Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef X As Long) As Short
Dim Ctr1, Ctr2, Freq As Long
Dim Acc, I As Integer
' Times 100 increment operations by using QueryPerformanceCounter.
If QueryPerformanceCounter(Ctr1) Then ' Begin timing.
For I = 1 To 100 ' Code is being timed.
Acc += 1
Next
QueryPerformanceCounter (Ctr2) ' Finish timing.
Console.WriteLine ("Start Value: " & Ctr1)
Console.WriteLine ("End Value: " & Ctr2)
QueryPerformanceFrequency (Freq)
Console.WriteLine ("QueryPerformanceCounter minimum resolution: 1/" & Freq & " seconds.")
Console.WriteLine ("100 Increment time: " & (Ctr2 - Ctr1) / Freq & " seconds.")
Else
Console.WriteLine ("High-resolution counter not supported.")
End If
'
' Keep console window open.
'
Console.WriteLine()
Console.Write ("Press ENTER to finish ... ")
Console.Read()
End Module
End Sub
Sub Function1_Int_RandNumCounter()
Dim Int_RandNum_X As Integer
Dim Int_RandNum_Y As Integer
Dim Count As Integer
For Count = 1 To Count = 1000000
Int_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Int_RandNum_Y = Rnd(Now)
Next Count
' Call Function1_Dbl_RandNumCounter
End Sub
Sub Function1_Dbl_RandNumCounter()
Dim Dbl_RandNum_X As Double, Dbl_RandNum_Y As Double, Count As Double
For Count = 1 To Count = 1000000
Dbl_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Dbl_RandNum_Y = Rnd(Now)
Next Count
Call Function1_Var_RandNumCounter
End Sub
Sub Function1_Var_RandNumCounter()
Dim Var_RandNum_X, Var_RandNum_Y, Count As Variant
For Count = 1 To Count = 1000000
Var_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Var_RandNum_Y = Rnd(Now)
Next Count
Call Function1_Dec_RandNumCounter
End Sub
Sub Function1_Dec_RandNumCounter()
Dim Count, Var_RandNum_X, dec_RandNum_X, Var_RandNum_Y, dec_RandNum_Y
dec_RandNum_X = CDec(Var_RandNum_X)
dec_RandNum_Y = CDec(Var_RandNum_Y) ' convert these vals to decimals
For Count = 1 To Count = 1000000
dec_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
dec_RandNum_Y = Rnd(Now)
Next Count
Call Function2_BarGraph
End Sub
Sub Function2_BarGraph()
' Put all of these vals in a 2D bar graph
End Sub
This code gives me errors such as:
Compile error:
Only comments may appear after End Sub, End Function, or End Property
EDIT: Here is the improved version of the code, which has no compile errors, but I'm not sure how to integrate the timer into my functions.
Option Explicit
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
Private m_CounterStart As LARGE_INTEGER
Private m_CounterEnd As LARGE_INTEGER
Private m_crFrequency As Double
Private Const TWO_32 = 4294967296# ' = 256# * 256# * 256# * 256#
Private Function LI2Double(LI As LARGE_INTEGER) As Double
Dim Low As Double
Low = LI.lowpart
If Low < 0 Then
Low = Low + TWO_32
End If
LI2Double = LI.highpart * TWO_32 + Low
End Function
Private Sub Class_Initialize()
Dim PerfFrequency As LARGE_INTEGER
QueryPerformanceFrequency PerfFrequency
m_crFrequency = LI2Double(PerfFrequency)
End Sub
Public Sub StartCounter()
QueryPerformanceCounter m_CounterStart
End Sub
Property Get TimeElapsed() As Double
Dim crStart As Double
Dim crStop As Double
QueryPerformanceCounter m_CounterEnd
crStart = LI2Double(m_CounterStart)
crStop = LI2Double(m_CounterEnd)
TimeElapsed = 1000# * (crStop - crStart) / m_crFrequency
End Property
Sub Function1_Int_RandNumCounter()
Dim Int_RandNum_X As Integer
Dim Int_RandNum_Y As Integer
Dim Count As Integer
For Count = 1 To Count = 1000000
Int_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Int_RandNum_Y = Rnd(Now)
Next Count
' Call Function1_Dbl_RandNumCounter
End Sub
Sub Function1_Dbl_RandNumCounter()
Dim Dbl_RandNum_X As Double, Dbl_RandNum_Y As Double, Count As Double
For Count = 1 To Count = 1000000
Dbl_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Dbl_RandNum_Y = Rnd(Now)
Next Count
Call Function1_Var_RandNumCounter
End Sub
Sub Function1_Var_RandNumCounter()
Dim Var_RandNum_X, Var_RandNum_Y, Count As Variant
For Count = 1 To Count = 1000000
Var_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Var_RandNum_Y = Rnd(Now)
Next Count
Call Function1_Dec_RandNumCounter
End Sub
Sub Function1_Dec_RandNumCounter()
Dim Count, Var_RandNum_X, dec_RandNum_X, Var_RandNum_Y, dec_RandNum_Y
dec_RandNum_X = CDec(Var_RandNum_X)
dec_RandNum_Y = CDec(Var_RandNum_Y) ' convert these vals to decimals
For Count = 1 To Count = 1000000
dec_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
dec_RandNum_Y = Rnd(Now)
Next Count
Call Function2_BarGraph
End Sub
Sub Function2_BarGraph()
' Put all of these vals in a 2D bar graph
End Sub
EDIT: New VBA code (did I set up this function properly?)
Sub Function1_Int_RandNumCounter()
Dim Int_RandNum_X As Integer
Dim Int_RandNum_Y As Integer
Dim Count As Integer
Dim oPM As PerformanceMonitor
Dim Time_Int As Variant
Time_Int = CDec(Time_Int)
Set oPM = New PerformanceMonitor
oPM.StartCounter
For Count = 1 To Count = 1000000
Int_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property
Int_RandNum_Y = Rnd(Now)
Next
Time_Int = oPM.TimeElapsed
' Call Function1_Dbl_RandNumCounter
End Sub
Add a new class module to your project, call it PerformanceMonitor and paste this code from the thread I linked to in my comment into the class:
Option Explicit
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
Private m_CounterStart As LARGE_INTEGER
Private m_CounterEnd As LARGE_INTEGER
Private m_crFrequency As Double
Private Const TWO_32 = 4294967296# ' = 256# * 256# * 256# * 256#
Private Function LI2Double(LI As LARGE_INTEGER) As Double
Dim Low As Double
Low = LI.lowpart
If Low < 0 Then
Low = Low + TWO_32
End If
LI2Double = LI.highpart * TWO_32 + Low
End Function
Private Sub Class_Initialize()
Dim PerfFrequency As LARGE_INTEGER
QueryPerformanceFrequency PerfFrequency
m_crFrequency = LI2Double(PerfFrequency)
End Sub
Public Sub StartCounter()
QueryPerformanceCounter m_CounterStart
End Sub
Property Get TimeElapsed() As Double
Dim crStart As Double
Dim crStop As Double
QueryPerformanceCounter m_CounterEnd
crStart = LI2Double(m_CounterStart)
crStop = LI2Double(m_CounterEnd)
TimeElapsed = 1000# * (crStop - crStart) / m_crFrequency
End Property
Now as an example of how to use it, you need to declare and create an instance of the PerformanceMonitor class, then call its StartCounter method at the start of the code you want to time, then at the end call its TimeElapsed property to see how long it took (in milliseconds). For example:
Sub foo()
Dim n As Long
Dim oPM As PerformanceMonitor
Set oPM = New PerformanceMonitor
oPM.StartCounter
For n = 1 To 100000
Debug.Print n
Next
MsgBox oPM.TimeElapsed
Set oPM = Nothing
End Sub

VBA: Initialize object on first use in Module

I kept receiving Object Variable Not Set (Error 91) with the following code in PowerPoint 2013.
I did a step through with this, and it flagged it on the Set SlideCounter = New Counter line which is quite confusing.
Module - Module1:
Dim SlideCounter As Counter
Sub showNext()
If SlideCounter Is Nothing Then
Set SlideCounter = New Counter
End If
ActivePresentation.SlideShowWindow.View.GotoSlide (SlideCounter.GetSlideNumber)
End Sub
Class Module - Counter:
'You should config the following constants
Const kBeginSlide As Integer = 2
Const kEndSlide As Integer = 4
Const kEnddingSlide As Integer = 5
'You should NOT modify anything below
Dim slides As Collection
Private Sub Class_Initialize()
Dim x As Integer
For x = kBeginSlide To kEndSlide
slides.Add (x)
Next x
End Sub
Public Function GetSlideNumber()
If slides.Count = 0 Then
GetSlideNumber = kEnddingSlide
Else
Dim slideIndex As Integer
slideIndex = GetRandomInteger(1, slides.Count)
GetSlideNumber = slides.Item(slideIndex)
slides.Remove (slideIndex)
End If
End Function
Private Function GetRandomInteger(lowerBound As Integer, upperBound As Integer)
Randomize
GetRandomInteger = Int((upperBound - lowerBound + 1) * Rnd + lowerBound)
End Function

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