Runtime error 438 on remove dynamically added userform control - vba

I've got the following code:
Private Sub cboA_change()
'Something to determine number of controls there should be, variable gC
'Something to determine number of controls there are, variable nC
'The first time the code runs, the following code runs:
For i = nC to gC
frmA.Frame1.Controls.Add("txtGroup" & i)
Next
'The second time the code runs, the following is executed:
For i = 7 To nC
Me.Frame1.Controls("txtGroup" & i).Remove 'ERROR HERE
Next
For i = nC to gC
frmA.Frame1.Controls.Add("txtGroup" & i)
Next
End Sub
Something like this, the code is way bigger and I tried to clear it up so if the structure doesn't seem right, that doesn't matter really.
I debugged the Add statement and I know there is a control added to the userform, called txtGroup7. However, when I later try to remove this control, I get Run-time Error 438: Object Doesn't Support This Property or Method. I tried changing the code to:
Me.Frame1.Controls.Remove ("txtGroup" & i)
But this didn't work either.
Can anybody point me in the right direction?
Edit:
I know the help says the following:
"This method deletes any control that was added at run time. However,
attempting to delete a control that was added at design time will
result in an error."
But since the control is added in run-time (dynamically, with VBA code) this shouldn't be a problem, right?
Edit 2:
I don't get why this works, but it seems to work:
q=0
While q < Me.Frame1.Controls.Count
If Me.Frame1.Controls(q).Name = "txtGroup7" Then
Me.Frame1.Controls.Remove q
Else
q = q + 1
End If
Wend

You must have something else wrong in your code, because Removeshould be working. Tried :
Private Sub ToggleButton1_Click()
If ToggleButton1.Value = True Then
Me.Frame1.Controls.Add "Forms.TextBox.1", "Text1", True
Else
Me.Frame1.Controls.Remove "Text1"
End If
End Sub
on a UserForm with a ToggleButton and a Frame and it correctly add and remove the TextBox when pressed.

Related

How do I change the text of multiple bookmarks by stepping through an array?

Sub initialize()
For boxNum = 1 To 10
vaultValuesForm.Controls("h" & boxNum).Value = ""
vaultValuesForm.Controls("d" & boxNum).Value = ""
Next boxNum
vaultValuesForm.Show
End Sub
Sub button_Populate_Click()
Dim array_h(9) As String, array_d(9) As String
For boxNum = 0 To 9
array_h(boxNum) = vaultValuesForm.Controls("h" & (boxNum + 1)).Value
array_d(boxNum) = vaultValuesForm.Controls("d" & (boxNum + 1)).Value
Next boxNum
Call populateTable(array_h(), array_d())
End Sub
Sub populateTable(array_0() As String, array_1() As String)
For x = 1 To 4
ThisDocument.Bookmarks("bd" & x).Range.Text = array_0(0)
Next x
End Sub
I have tested the functionality of this code at various points, and it works flawlessly right up until this line:
ThisDocument.Bookmarks("bd" & x).Range.Text = array_0(0)
Specifically, until it reaches = array_0(0). In its current state, reaching this point in the Sub results in "Run-time error '5941': The requested member of the collection does not exist." Same deal when I originally tried using = array_0(x) (which is ultimately what I'm trying to accomplish). However, if replaced with something direct such as = "AA", it works. How do I phrase this bit properly to set the bookmark values to those within the array?
Note: In case you're wondering, the arrays are being referenced and passed properly; I tested this by changing the loop to comments and using MsgBox() with various array elements.
The answer from comments. The issue I wasn't aware of was that the bookmarks were being deleted after running the module, so it wouldn't work again unless the bookmarks were created again.
Are you sure the bookmarks bd1...bd4 are still there in the document? Because a bookmark's range.text deletes the bookmark, so if you want to be able to repeat the bookmark text assignments you have to recreate the bookmarks after assigning the texts. FWIW I ran your code and it was fine when bd1..bd2 etc. existed but threw 5941 the next time. (This is quite a common problem!) – slightly snarky Sep 3 at 8:37
So, for the official answer to my question, the way I had done it initially is how; it just couldn't be repeated.

Form causes Run-time error -2147352571 (80020005)

I have a form which is partially filled in automatically from tables. There is a combo, where the number of transaction is chosen and then there is a textbox, where I want to fill in the partner name (searched in sheets).
I have spend some long time to figure out what am I having wrong in my code. In the end I managed the code work, but it looks very mysterious for me and it's not clean.
The original code:
Private Sub ComboTransaction_Change()
Dim ws_su As Worksheet
Set ws_su = Worksheets("Sale Unsettled")
TextPartner = ws_su.Range("SaleUnsettled_Start").Offset(Application.WorksheetFunction.Match(Val(ComboTransaction), ws_su.Range("SaleUnsettled_Transactions"), 0), 1)
End Sub
The "solution":
Private Sub ComboTransaction_Change()
Dim ws_su As Worksheet
Set ws_su = Worksheets("Sale Unsettled")
PartnerValue = ws_su.Range("SaleUnsettled_Start").Offset(Application.WorksheetFunction.Match(Val(ComboTransaction), ws_su.Range("SaleUnsettled_Transactions"), 0), 1)
TextPartner = PartnerValue
End Sub
Why I have to do it via the PartnerValue, that's a mystery for me. Not only it bothers me because it's messing up the code (there are more values which I have to fill in the same way), but I also have another forms (Purchase etc), where it works without this strange patch.
I would like to get rid of if so if you have any idea what's wrong, I will appreciate your message.
The only difference between TextPartner and PartnerValue is that TextPartner is a TextBox in the form and PartnerValue isn't.
The Run-time error means that it is a Type mismatch.
Try to use
TextPartner.Text = ws_su.Range("SaleUnsettled_Start").Offset( _
Application.WorksheetFunction.Match(Val(ComboTransaction), _
ws_su.Range("SaleUnsettled_Transactions"), 0), 1)

VB - Calling Sub doesn't work from all classes

I have a sub (Named "StartStop") that is called from a couple different buttons as well as from another form. All of the forms are their default instance and the sub is called the same way each time:
The Buttons on the "Main" Form:
Call StartStop(Start.Text, "Server")
Call StartStop(Weekend.Text, "Server")
From the problem Form:
Select Case MessageParse(2)
Case "Start"
Call Main.StartStop("Start", MessageParse(1))
Case "Stop"
Call Main.StartStop("Pause", MessageParse(1))
Case "Weekend"
Call Main.StartStop("Weekend", MessageParse(1))
Case "Weekday"
Call Main.StartStop("Weekday", MessageParse(1))
My issue is that from my problem form, (named "CommServer"), it calls the sub and runs through the code but does not execute any of it. I can step through it and watch it run line by line without any apparent change.
If I call it the same way from a third unrelated form, for the sake of testing, everything works the same way it does from the buttons which is leading me to believe it's something with my CommServer form. Here's a snippet from the called Sub:
Public Sub StartStop(ByVal Action As String, ByVal User As String)
Select Case Action
Case "Start"
Countdown.Interval = 500
TargetDT = DateTime.Now.Add(TimeLimit)
Countdown.Start()
GameUpdateTimer.Interval = GameSpeed * 1000
GameUpdateTimer.Start()
Start.Text = "Pause"
Weekend.Enabled = True
GameOn = True
CommServer.xUpdate("StartStop" & "`" & "Start", True)
CommServer.xUpdate("ChatMessage" & "`" & User & " Started The Game", True)
I can step through the sub, and even watch it loop back to the CommServer form and run through the xUpdate Sub over there, except nothing happens. However if I dropped the line MsgBox("Test") in that code it would produce a message box but ignore everything else.
So my question is, what should I be looking for in my CommServer form that would pass by the code without executing it? I've scoured my code and can't find any evidence that these forms are not the default instance.
Thanks in Advance, I hope it's easy!

SetFocus inside a GotFocus procedure initiated by another SetFocus

Objective: Redirect focus from one command button to another using the first's GotFocus procedure.
Context: I have a form-independent procedure in a generic module that, on most forms, sets focus to the NewRecord button after saving the previous record. But on one form, I would like to redirect (based on certain conditions) focus back to the SignRecord button so the user can "sign" a second part of the same record (I may need this for other uses in the future). The target control is enabled and visible and can otherwise be focused and the original control can be focused when the redirect doesn't occur. Reference [2] below implies that this should be possible, though I'm not changing visibility of my controls.
Issue: When the conditions are met to redirect focus in the GotFocus procedure, it redirects as desired but the original (test) SetFocus call throws a "Run-time error '2110', Can't move focus to the control CommandNew".
What I've tried:
Exit Sub after my downstream SetFocus calls.
Call CommandSign.SetFocus in the hopes that it would make it happen outside the previous SetFocus process.
In a module,
Public Sub test()
Forms("TargetForm").CommandNew.SetFocus 'This gets the error '2110'
End Sub
In the 'TargetForm',
Private Sub CommandNew_GotFocus()
If IsNull(textDateTime) Then Exit Sub 'Works as expected
'I can see these two parts work. The framSign value changes
'and CommandSign gets focus
If checPPC And IsNull(textSigID_PPC) And framSign = 2 Then
framSign = 1
CommandSign.SetFocus
ElseIf checDAS And IsNull(textSigID_DAS) And framSign = 1 Then
framSign = 2
CommandSign.SetFocus
End If
End Sub
References:
[1]: SelectNextControl() a bad idea in a GotFocus event?
[2]: http://www.access-programmers.co.uk/forums/showthread.php?t=100071
I think your problem is that the call to Forms("TargetForm").CommandNew.SetFocus doesn't quite seem to, in fact, finish setting the focus to CommandNew until after Private Sub CommandNew_GotFocus() has finished executing. Because you've called another SetFocus before the first SetFocus could finish, there is a conflict that Access seems to be unable to cope with.
Whether or not that is the case, one thing is clear: the way you have your execution plan set up right now is unfortunately not going to work. You might try adding either a global variable or a public variable to each form that determines whether or not you should set your focus to CommandSign after you set the focus to CommandNew.
Ex. TargetForm:
Public boolSetCommandSignFocusInstead As Boolean
Private Sub CommandNew_GotFocus()
If IsNull(textDateTime) Then Exit Sub 'Works as expected
'I can see these two parts work. The framSign value changes
'and CommandSign gets focus
If checPPC And IsNull(textSigID_PPC) And framSign = 2 Then
framSign = 1
boolSetCommandSignFocusInstead = True
ElseIf checDAS And IsNull(textSigID_DAS) And framSign = 1 Then
framSign = 2
boolSetCommandSignFocusInstead = True
Else
boolSetCommandSignFocusInstead = False
End If
End Sub
Module:
Public Sub test()
Forms("TargetForm").CommandNew.SetFocus
If Forms("TargetForm").boolSetCommandSignFocusInstead Then
Forms("TargetForm").CommandSign.SetFocus
End If
End Sub

VBA Excel "Variables are required"

Got a trouble in a VBA excel program.
Sub code(s)
...
code = t
End Sub
And then :
Sub CommandButton1_Click()
...
For i = 0 To size
current_y = code(string_array(i))
...
End Sub
When i run the program, i got this error "Variables are required" (not sure, i'm working on a japanese version of excel). Sub CommandButton1_Click is highlighted and code is selected inside CommandButton1_Click. Can't figure out why, though it must be simple...
You're trying to return a result from a Sub. Try declaring it as a function instead, as this is able to return values to the caller:
Function code(s)
...
code = t
End Function
If it makes it any clearer, on my English version the error message is:
Expected Function or variable
Does the code include Option Explicit? Perhaps the error translates to "Variable declaration required"? Try removing option explicit - if that fixes it remove that line, then go through checking all variables are declare (e.g. dim current_y as string).