Error 91 on Frame Control upon Start Up - excel

I have a Microsoft Form 2.0 Frame Control with three option buttons. The name of the Frame Control is Side, three option button captions are X, O, and Random with names xOption, oOption, and randomSide respectively.
The code runs fine, except upon startup, if I open Excel and run the program immediately, it will give me an Error 91, note that one of the options (X, O, or Random) is already selected. In order to get rid of this error, I need to explicitly select another option, then the error goes away. I don't know why this happens. Here is the sub for the Frame Control
Public Sub Side_Click()
sideLetter = Side.ActiveControl.Caption
If StrComp(sideLetter, "Random") = 0 Then
Randomize
tempRand = Int((Rnd() * 2 + 1))
If tempRand = 1 Then
sideLetter = "X"
Else
sideLetter = "O"
End If
End If
End Sub
The Line sideLetter = Side.ActiveControl.Caption Is the one causing the issue. I have not explicitly declared Side as a frame control in case that's some helpful information because I'm thinking that the object is already declared just by making the Frame Control. Thanks in advance!

You need to check that Side.ActiveControl is actually an object, before you read it's Caption:
Public Sub Side_Click()
If Not Side.ActiveControl Is Nothing Then
sideLetter = Side.ActiveControl.Caption
If StrComp(sideLetter, "Random") = 0 Then
Randomize
tempRand = Int((Rnd() * 2 + 1))
If tempRand = 1 Then
sideLetter = "X"
Else
sideLetter = "O"
End If
End If
End If
End Sub

Related

Inputbox selection causing: "Text is not valid." Error [duplicate]

The current function I use to collect text InputBox can't accept more than 255 characters apparently, and I need to be able to collect more than that? Is there a parameter or different function I can use to increase this limit?
To be pedantic, the Inputbox will let you type up to 255 characters, but it will only return 254 characters.
Beyond that, yes, you'll need to create a simple form with a textbox. Then just make a little "helper function" something like:
Function getBigInput(prompt As String) As String
frmBigInputBox.Caption = prompt
frmBigInputBox.Show
getBigInput = frmBigInputBox.txtStuff.Text
End Function
or something like that...
Thanks BradC for the info that. My final code was roughly as follows, I have a button that calls the form that I created and positions it a bit as I was having some issues with the form being in the wrong spot the everytime after the first time I used.
Sub InsertNotesAttempt()
NoteEntryForm.Show
With NoteEntryForm
.Top = 125
.Left = 125
End With
End Sub
The userform was a TextBox and two CommandButtons(Cancel and Ok). The code for the buttons was as follows:
Private Sub CancelButton_Click()
Unload NoteEntryForm
End Sub
Private Sub OkButton_Click()
Dim UserNotes As String
UserNotes = NotesInput.Text
Application.ScreenUpdating = False
If UserNotes = "" Then
NoteEntryForm.Hide
Exit Sub
End If
Worksheets("Notes").ListObjects("Notes").ListRows.Add (1)
Worksheets("Notes").Range("Notes").Cells(1, 1) = Date
Worksheets("Notes").Range("Notes").Cells(1, 2) = UserNotes
Worksheets("Notes").Range("Notes").Cells(1, 2).WrapText = True
' Crap fix to get the wrap to work. I noticed that after I inserted another row the previous rows
' word wrap property would kick in. So I just add in and delete a row to force that behaviour.
Worksheets("Notes").ListObjects("Notes").ListRows.Add (1)
Worksheets("Notes").Range("Notes").Item(1).Delete
NotesInput.Text = vbNullString
NotesInput.SetFocus ' Retains focus on text entry box instead of command button.
NoteEntryForm.Hide
Application.ScreenUpdating = True
End Sub
I don't have enough rep to comment, but in the sub form_load for the helper you can add:
me.AutoCenter = True
Outside of that form, you can do it like this:
NoteEntryForm.Show
Forms("NoteEntryForm").AutoCenter = True
My Access forms get all confused when I go from my two extra monitors at work to my one extra monitor at home, and are sometimes lost in the corner. This AutoCenter has made it into the form properties of every one of my forms.

Unable to operate simple mathematical operation using user form with excel 2013

I am trying to create a user form do doing some mathematical operation like multiply and divide. Where I want to divide input value (obtained through user form) into halves. But I made a mistake don't know where because as soon as I clicked on radio button (rdio_cgst) vba shws an compile error with error 'Object required'. Please help me to find out the mistake.
Help is highly appreciable.
Private Sub RDIO_CGST_Click()
If LIST_GST <> "" And RDIO_CGST.Value = True Then
Sheets("BILLING").Range("W19").Value = LIST_GST
Sheets("BILLING").Range("I19").Value = LIST_GST/ 2
Sheets("BILLING").Range("J19").Value = LIST_GST/ 2
Sheets("BILLING").Range("K19").Value = 0
Else
Sheets("BILLING").Range("I19").Value = 0
Sheets("BILLING").Range("J19").Value = 0
End If
End Sub

Replacing userform name with variable

I have the following function put in "Module1" determine the maximum value of a text box in user form, named "frmAddRecord2", that can be input.
txtLV and txtMaxLV are textboxes under "frmAddRecord2".
And txtMaxLV_Pass is a boolean variable put under frmAddRecord2 as well. At this stage, this function works fine.
Public Function txtLV_Max() As Long
With frmAddRecord2
If .txtLV.Value >= 99 Or Not .txtMaxLV_Pass Then
txtLV_Max = 109
Else
txtLV_Max = .txtMaxLV.Value - 1
End If
End With
End Function
As I will have "frmAddRecord1", "frmAddRecord2", "frmAddRecord3" ... etc, so I would like to call the following sub when frmAddRecord1 or frmAddRecord2
is activated.
Public Sub SetActiveUserForm(Optional UserFormName As String)
If UserFormName = "frmAddRecord1" Then
Set ActiveUserForm = frmAddRecord1
UserFormShown = True
ElseIf UserFormName = "frmAddRecord2" Then
Set ActiveUserForm = frmAddRecord2
UserFormShown = True
Else
Set ActiveUserForm = Nothing
UserFormShown = False
End If
End Sub
And I would like to restructure the function as:
Public Function txtLV_Max() As Long
With activeuserform
If .txtLV.Value >= 99 Or Not .txtMaxLV_Pass Then
txtLV_Max = 109
Else
txtLV_Max = .txtMaxLV.Value - 1
End If
End With
End Function
However, error occur at the Line "If .txtLV.Value >= 99 Or Not .txtMaxLV_Pass Then" . After testing, the txtMaxLV_Pass is found failed to be call after I restructured the function. And it work fine again if I moved txtMaxLV_Pass to be public under Module1.
But I would like to ask, if I want to keep the txtMaxLV_Pass under the userform, what should I changed in declare the userform variable. Please advice, I have studied this in web site and books, but still not able to tackle. Thank you for all your help.
The Global variable ActiveUserForm was given the type of Userform. However, to access UserForm properties from a Userform variable, it actually needs to be of type Object or Variant.

I am getting a thread error when attempting to open a form based on a timer tick event

I have a program that runs a scoretable front screen. I want to have a running ad loop of videos that pop up based on a timer. I created a separate form to play the video and am using a timer to open the form and play one video, then I am incrementing a global variable, closing the form, then waiting for the timer to reopen the form. When the timer tries to reopen the form, it is giving me a thread error. I am somewhat new to this level of coding and am confused about why this error is occuring and how to fix it. I read up on the topic and think I generally understand the problem, but can't seem to find the proper code to get it to work. Here is the code (global variable of VAds) I have used the invoke procedure to fix this problem with a picture box, but cant figure out the same thing for the video. Thanks in advance.
Private Sub PlayAdVideos(sender As Object, e As EventArgs) Handles VideoAds.Click
On Error Resume Next
If Application.OpenForms().OfType(Of frmAds).Any Then
frmVideoAds.Close()
Play_Ads.Text = "Start Video Advertisement Loop"
Exit Sub
Else
Play_Ads.Text = "Close Video Advertisement Loop"
Dim Sz As Integer
If ScreenNo.Text = "" Then
Sz = 1
Else
Sz = ScreenNo.Text
End If
Dim screen As Screen
screen = Screen.AllScreens(Sz)
frmVideoAds.StartPosition = FormStartPosition.Manual
frmVideoAds.Location = screen.Bounds.Location + New Point(0, 0)
frmVideoAds.WindowState = FormWindowState.Maximized
frmVideoAds.FormBorderStyle = FormBorderStyle.None
frmVideoAds.TopMost = True
frmVideoAds.BackColor = Color.Black
frmVideoAds.Show()
End If
For Each foundFile As String In My.Computer.FileSystem.GetFiles("C:\CCHS\VideoAds\")
VideoAdList.Items.Add(foundFile)
Next
If VideoAdList.Items.Count = 0 Then
Exit Sub
End If
Dim TMR2 As New System.Timers.Timer()
VideoAdNum = VideoAdList.Items.Count - 1
TMR2.Interval = 10000 'miliseconds
TMR2.Enabled = True
TMR2.Start()
AddHandler TMR2.Elapsed, AddressOf OnTimedEvent
End Sub
Public Sub OnTimedEvent(ByVal sender As Object, ByVal e As ElapsedEventArgs)
If frmVideoAds.InvokeRequired Then
If VAds = VideoAdNum Then
VAds = 0
Else
VAds = VAds + 1
End If
frmVideoAds.Invoke(Sub() frmVideoAds.Show())
Else
If VAds = VideoAdNum Then
VAds = 0
Else
VAds = VAds + 1
End If
frmVideoAds.Show()
End If
End Sub
System.Timers.Timer elapsed events will generally always be fired on a thread other than the UI thread.
Which means you'll have to call the frmVideoAds.Invoke every time you call frmVideoAds.Show() in that method.
Your else statement should just need to have the invoke added, which would make both execution paths the same so you could update the whole thing.
Public Sub OnTimedEvent(ByVal sender As Object, ByVal e As ElapsedEventArgs)
If VAds = VideoAdNum Then
VAds = 0
Else
VAds = VAds + 1
End If
frmVideoAds.Invoke(Sub() frmVideoAds.Show())
End Sub
This will generally work, but in some cases , ActiveX in particular, the System.Timers is required to be in a Single Threaded Apartment (STA). It defaults to a Multi threaded apartment (MTA). To force it into a STA mode simply add
TMR2.SynchronizingObject = Me
just before your TM2.Start().

Excel VBA script: Crash on End If

Details:
In this segment, I am filling the cell referenced by 'z' with modified date values from cell referenced by 'a', depending on the conditions met. The code crashes at the inner End If line.
Code snippet:
If Range(x).Value =1 Then
If Day(Range(a)) > Day(Range(b)) Then
Range(z).Value = DateSerial(Year(Range(a)), Month(Range(a)), Day(Range(a)-1)) + TimeSerial(20,0,0)
Else
Range(z).Value = DateSerial(Year(Range(a)), Month(Range(a)), Day(Range(a))) + TimeSerial(20,0,0)
End If
ElseIf Range(y).Value =1 Then
Range(z).Value = DateSerial(Year(Range(a)), Month(Range(a)), Day(Range(a)-1)) + TimeSerial(8,0,0)
Else
Range(z).Value = Range(a).Value
End If
Your code is good. Either you have a problem where one of your ranges is pointing to invalid data, or you have corruption in your module.
You can handle corruption by exporting your moodules to a text file (right click module in VBA editor->export) and then import into a clean workbook.
It seems to test fine for me.
I know default properties have been created in order to make code more concise, and I realize objects should not need to be fully qualified with their parent objects but I don't always trust the VBA compiler so my version is a little longer than yours (I've used the cells C1 to C5 to test):
Option Explicit
Sub FullyQualified()
With Excel.ThisWorkbook.Sheets("Sheet1")
If .Range("C1").Value = 1 Then
If Day(.Range("C3").Value) > Day(.Range("C4").Value) Then
.Range("C5").Value = DateSerial(Year(.Range("C3").Value), Month(.Range("C3").Value), Day(.Range("C3").Value - 1)) + TimeSerial(20, 0, 0)
Else
.Range("C5").Value = DateSerial(Year(.Range("C3").Value), Month(.Range("C3").Value), Day(.Range("C3").Value)) + TimeSerial(20, 0, 0)
End If
ElseIf .Range("C2").Value = 1 Then
.Range("C5").Value = DateSerial(Year(.Range("C3").Value), Month(.Range("C3").Value), Day(.Range("C3").Value - 1)) + TimeSerial(8, 0, 0)
Else
.Range("C5").Value = .Range("C3").Value
End If
End With
End Sub

Resources