I've been encountering the same problem over and over with some IF statements. One one form I've got this:
If KarlConvo = 4 Then
MsgBox("Karl: Wow man. I overheard everything. I don't like your methods but it did work. Have this man. I can't wait until she approaches my sexy self")
MsgBox("You have obtained the SANDWICH")
PlayerProfileMale.tpbSandwich.Visible = True
PlayerProfileMale.lblSandwich.Visible = True
Form2.lblFact3C2.Visible = True
KarlConvo = 5
TobyConvo = 4
PlayerProfileMale.EatButton = True
End If
The code above happens after a msgbox pops up. It should allow for a 'Eat' button to appear on another form. The IF statement on that form is:
If EatButton = True Then
btnEat.Visible = True
End If
Well the problem is that the button is not showing on my second form even though the only condition it has is for the EatButton variable (which is a Public Property) to be true. Any ideas on why this is happening?
Thanks in advance
Here are a couple of things to check:
Show, paint, or reload the PlayerProfileMale form after you assign PlayerProfileMale.EatButton = True. Trigger an event that causes the If EatButton statement to be executed.
Make sure you're addressing the proper instance of PlayerProfileMale when you assign PlayerProfileMale.EatButton = True. This shouldn't normally be a problem, but can be if you create an instance of the form and another instance is created (or already open) when you make the assignment.
Related
Using VBA (Excel 365 (16.0.12527.20880), German) I'm trying to set the strikethrough property of a checkbox (Checkbox1) caption to False in accordance to the Office VBA reference this should work.
The following code is placed in a Module1 (simplified) and changes the strikethrough-value of UserForm1.Checkbox1 (UserForm1 and Checkbox1 is static, created via the VBA-Editor, not via code during runtime).
Sub ChangeCheckBox()
UserForm1.CheckBox1.Caption = "Test" 'this triggers the Init-Procedure, which only sets the Height and Width of the UserForm. This shouldn't effect the problem, but I'm mentioning it here so it's clear that the form has been initialized. But if I leave it out, it's the same problem.
'Pre-Test - works fine
'Check initial value
Debug.Print UserForm1.CheckBox1.Font.Strikethrough 'returns false (as it should)
'Write value and check it
UserForm1.CheckBox1.Font.Strikethrough = False
Debug.Print UserForm1.CheckBox1.Font.Strikethrough 'returns false (as it should)
'Write value and check it again
UserForm1.CheckBox1.Font.Strikethrough = False
Debug.Print UserForm1.CheckBox1.Font.Strikethrough 'returns false (as it should)
'This next line seeems to cause the post-test failure
tmpString = ThisWorkbook.Worksheets("Sheet1").Cells(tmpIndex, tmpColumn).Value
Debug.Print tmpString 'returns the correct value
'Post-Test - fails!!!
'Check initial value
Debug.Print UserForm1.CheckBox1.Font.Strikethrough 'returns false (as it should)
'Write value and check it
UserForm1.CheckBox1.Font.Strikethrough = False
Debug.Print UserForm1.CheckBox1.Font.Strikethrough 'returns true (should still be false)
'Write value and check it again
UserForm1.CheckBox1.Font.Strikethrough = False
Debug.Print UserForm1.CheckBox1.Font.Strikethrough 'returns true (definitely should return false now)
End Sub
In my case, for some reason, the command sets the box to True instead of False. So far I pinpointed the problem to a specific line of code. The "Pre-Test" succeeds, the "Post-Test" fails (everything else works fine). Note, I'm using debug mode via step by step, no other code is executed "in-between".
The problem persists if I create a different Form and try the same thing there. The original procedures are several hundred lines of code, but I created the Testprocedure above and the problem persists. I can also reproduce it by creating a new Excel file from scratch with just one Sheet, one Userform/Checkbox, and one Module containing the test procedure.
So, why the hell does tmpString = ThisWorkbook.Worksheets("Sheetname").Cells(tmpIndex, tmpColumn).Value cause the "Post-Test" to fail?
Note: This error can not be reproduced on all machines, I tried it on a different machine. There, I can not reproduce the error.
I cannot reproduce the issue and I've tried on 3 different machines.
However, I remember seeing a similar issue about 7 years ago and I managed to work around it by first checking if I need to change the value of the font property.
Try replacing all occurences of this:
UserForm1.CheckBox1.Font.Strikethrough = False
with this:
If UserForm1.CheckBox1.Font.Strikethrough Then UserForm1.CheckBox1.Font.Strikethrough = False
This basically sets the .Font.Strikethrough property to False only if it is already True because otherwise it is False (obviously) and if there is any bug in the setter of that property then this skips the bug.
Unrelated to your question but it's not a good idea to use the default instance of a Userform like you're doing here with Userform1.Checkbox.... I recommend you read this article written by #MathieuGuindon back in 2017.
Try using index for your worksheet instead of the name.
Its a funny thing to happen in a programming language.
tmpString = ThisWorkbook.Worksheets(1).Cells(tmpIndex, tmpColumn).Value
Debug.Print tmpString
It worked for me and I think because the polymorphic functions in VBA made without debugging! because nothing else could cause this kind of behavior!
I've managed to reproduce the issue the same way it occured to you.
The root cause here is that you are not explicitly UNLOADING the form after you close it, which means that all modifications that you made to it while open get retained in memory.
For example using your code, shows the checkbox with strikethrough even when running it 2nd time. Which means it's retained in memory.
So to fix this, simply add Unload UserForm1 in your procedure after running the code.
While this approach works in resetting the checkbox (which I assume is your ultimate goal here), it still returns true for those last 2 checks for some reason. To workaround that as well (though it could be unnecessary if you achieve your goal), then simply use #Cristian Buse's if/then solution.
I am new at VBA and I am trying some code and I could not find a solution or where I am doing wrong.
What I want: The combination of two different text boxes make another text box visible(so it starts in useform not visible). With one condition I could do it using select case(LLL) but when I try it with another variant it does not work(XXX). There is no error message, the code runs but does not show the text box.
Sub Visible()
If userform.TextBox5.Value = "XXX" And userform.TextBox10.Value = "245" Then
userform.TextBox1.Visible = True
userform.T_1.Visible = True
Else
GoTo LLL
End If
LLL:
Select Case True
Case userform.TextBox5.Value = "LLL", userform.TextBox10.Value >= "145"
If userform.Option000.Value = True Then
userform.TextBox1.Visible = True
userform.T_1.Visible = True
Else
userform.TextBox1.Visible = False
userform.T_1.Visible = False
End If
End Select
I understand some of your questions I must say that my code is quite big one cause it is linked to SAP in order to get some values from there and due to its size the complete code is splitted in modules and I am only sharing the module where I am facing problems.
There is one case for select case statement cause it was the only way that it worked close for what I need. I have a lot of variables for the fields TextBox5 and TextBox10 the values of these textboxes come from SAP and when I combine them, other Text Boxes shall be visible depending on the variables given. The problem is that for just one combination (this one is the one that I applied the select case statement) I need another variable (option000) so that TextBox1 and T_1 become visible. When I tried to do it only with if statements it did not worked.
I have a form in MS Access that I'm trying to create for insurance claims. I have all the fields that I need to be filled in but what I'd like to be able to do is enable or disable those fields depending on certain actions of the users. So the flow of the form is like this: I have a Frame at the top with two radio buttons, one for a single-claim incident and one for a multi-claim incident. If the user clicks the single-claim button everything continues with no problem. If the user clicks the multi-claim incident button, a combo box appears to the side with a dropdown list of MultiClaim_Incident_ID numbers that they need to select from. What I'm trying to do is if the user selects the Multi-Claim Incident button AND does not select an Incident ID number from the dropdown down list (i.e. leaves it at default value) then the rest of the form is disabled until corrected as well as clear all the fields...
It seems like it should be pretty straightforward but I can't seem to get it to work, I'm not sure if my logic is flawed or what. Here's an abridged version of my VBA code:
Private Sub Form_Load()
Me.SM_Frame.Value = 1
Me.MultiClaim_Drpdwn.Value = Null
End Sub
Private Sub SM_Frame_AfterUpdate()
If SM_Frame.Value = 1 Then
Me.MultiClaim_Incident_ID_Label.Visible = False
Me.MultiClaim_Drpdwn.Visible = False
ElseIf SM_Frame.Value = 2 Then
Me.MultiClaim_Incident_ID_Label.Visible = True
Me.MultiClaim_Drpdwn.Visible = True
ElseIf SM_Frame.Value = 2 & MultiClaim_Drpdwn.Value = Null Then
Me.Incident_Date = Null
Me.Incident_Date.Enabled = False
Me.Claimant_Name.Value = ""
Me.Claimant_Name.Enabled = False
//PATTERN CONTINUES FOR REST OF FIELDS//
MsgBox ("CLEAR EVERYTHING!!")
ElseIf SM_Frame.Value = 1 Then
Me.Incident_Date.Value = ""
Me.Incident_Date.Enabled = True
Me.Claimant_Name.Value = ""
Me.Claimant_Name.Enabled = True
//PATTERN CONTINUES FOR REST OF FIELDS//
MsgBox ("Everything can continue as is")
End If
End Sub
Let me just say that getting sequences like these right is NOT straightforward AT ALL! So don't feel bad about not getting it right on the first try. I have to create things like that about once a month and still need a lot of tries until it works in all situations.
Try to seperate to concerns:
You already have SM_Frame_AfterUpdate(). Do in it what you must to handle changing from Value 1 to 2, namely making the Combobox visible, but STOP there. You dont know what will happen to the fields with information from SM_Frame alone, you need to wait for MultiClaim_Drpdwn. Also, do what is needed to go from 2 to 1, namely hide the Combobox.
Next, create an AfterUpdate-handler MultiClaim_Drpdwn_AfterUpdate(). Use THAT to deal with the fields (enable/disable, set empty) according to its value.
Once you have that in place, you only have some edge cases remaining. For example, you want the fields to behave like MultiClaim_Drpdwn_AfterUpdate() states right after you change the SM_Frame. Thats easy once you understand that you can just happily CALL MultiClaim_Drpdwn_AfterUpdate() from within SM_Frame_AfterUpdate(), best done at the very end. These eventhandlers are still just normal functions, already public and available for anyone. This will make things chain nicely when you come from the radiobutton or not when you come from the Combobox.
In an "elseif" series, once a condition is true, the rest is ignored.
So, your
ElseIf SM_Frame.Value = 2 & MultiClaim_Drpdwn.Value = Null Then
is never reached, because you've got
ElseIf SM_Frame.Value = 2 Then
before.
In the same idea, the "ElseIf SM_Frame.Value = 1 Then" after the MsgBox is totally useless, because it's hidden by "If SM_Frame.Value = 1 Then"
Try to use the step-by-step debug mode to see that.
In the following block of code, does VB.NET gracefully exit the With block if Var1 = 2?
With MyObject
.Property1 = "test"
If Var1 = 2 Then
Return True
End If
.Property2 = "Test2"
End With
Return False
I remember this being an issue in VB6 and causing headaches with unpredicable behaviour - is the same true of VB.NET?
According to MSDN, this still isn't possible:
If you need to exit before all the statements have been executed, put a label on the End With statement and use the GoTo Statement to branch to it. (...) You cannot transfer control either from outside a With block to inside it, or from inside it to the outside. You can call a procedure from inside the block, but control returns to the following statement.
Had to add another answer here, because I was mainly curious. Never used WITH much, and I can't recall ever exiting the block prematurely, but I just tested this under VB2010 and it appears to work just fine (ie as I would expect it to, in other words...
If Var1 =2, the function returns TRUE, and the value of MyObject.Property1 is "Test" but MyObject.Property2 has not be set.
It's possible that it worked this way in a test, but in a real app of significant size, with debugging turned off etc, etc, it could work differently, so, there's that to consider....
I am supporting an application which was running for the past 3 years. It was developed completely in MS Access and written in VBA.
Suddenly the application is facing the mentioned error at the following lines:
DoCmd.OpenForm FormName:="frmNewPeerGroup", View:=acNormal, windowmode:=acWindowNormal, OpenArgs:=5
FrmNewPeerGroup code
Private Sub Form_Open(Cancel As Integer)
Dim lDept As Long, lDiv As Long
lType = OpenArgs 'Supplied by caller
lAssmtVer = 1 'Current
sName = ""
sDescription = ""
dtCreatedDate = Format(Now(), "dd/mm/yyyy")
sCreatedBy = UCase(userPerms.NTLoginName)
lSupervisorID = userPerms.userID
lTeam = 0
With cmbBxType
.RowSourceType = "Value List"
.RowSource = GetValueListDict(pgType)
.Value = lType
.Enabled = (OpenArgs = 1)
End With
With cmbBxVersion
.RowSourceType = "Value List"
.RowSource = GetValueListDict(pgAssmtType)
.Value = lAssmtVer
End With
mgLogoDesc.Visible = False
txtBxCreatedDate.Value = dtCreatedDate
txtBxCreatedBy.Value = sCreatedBy
If OpenArgs = 5 Then
lTeam = oActiveAssmt.TeamID
lDept = GetParentID(aTeams(), CInt(lTeam))
lDiv = GetParentID(aDepts(), CInt(lDept))
With cmbBxDivision
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aDivs())
.Value = lDiv
.Enabled = False
End With
With cmbBxDepartment
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aDepts())
.Value = lDept
.Enabled = False
End With
With cmbBxTeam
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aTeams())
.Value = lTeam
.Enabled = False
End With
Else
With cmbBxDivision
.RowSourceType = "Value List"
.RowSource = GetValueListArray(aDivs())
.Enabled = False
End With
cmbBxDepartment.Enabled = False
cmbBxTeam.Enabled = False
End If
End Sub
Many instances of the DoCmd.OpenForm command are giving the error in a message box saying:
The expression On Click you entered as the event property setting
produced the following error: The OpenForm action was canceled.
- The expression may not result in the name of macro, the name of
a user-defined function, or [Event procedure].
- There may have been an error evaluating the function, event, or macro.
This is the error message I am receiving.
My problem is, the same code was running around 3 years, but suddenly some updates to Microsoft or Office might be giving trouble to this code.
Did anyone come across this error in the past weeks? Please let me know what else we can do to make this work again.
This thread is very old but I came across the same error and spent a few hours looking for an answer. I was able to find the cause after some time and thought of posting my answer as it may help someone in a similar situation. Creating a application using Access Forms is new to me, so the error message was not directly intuitive.
My forms were Master table data entry forms and configured to be Pop-up and Modal with Me.Form.Name sent as parameter in the DoCmd.OpenForm command using a button (OnClick event) placed next to the Combo controls on a transaction form to allow user to quickly add new records. This parameter value was picked up in the Form_Open(Cancel As Integer) event and used later to refresh the combo box (Forms!<formname>.Controls!<controlname>.Requery) once data was submitted to the master table using the pop-up form.
It appears that the Open event doesn't occur when you activate a form that's already open (ref: https://msdn.microsoft.com/en-us/library/office/aa211439(v=office.11).aspx). Each time I received the error, my data entry form was open in Design view in Access. So I closed the form in design mode, and repeated the steps. And Voila! no error!
Since I will have more than one forms open, I now need to test and try to use Form_Activate() as recommended in the above MSDN reference link.
I don't know if this qualifies as an answer, but the code in that OnOpen event is dependent on a lot of outside functions. Specifically, the code is assigning value lists for the RowSources of a bunch of combo boxes. The immediate red flag that occurs to me is that non-SQL Rowsources have a finite length, and in Access 97, that limit was 2048 characters (in Access 2003, it's 32,750 -- don't ask me why it's that number!).
So, the immediate thing I see is that perhaps what ever data drives the functions that create those value lists has begun to exceed 2048 characters in length.
If that's the actual answer, then you can write a callback function that will return the values in the arrays, and it won't have the limitation on the returned length. You'd set the RowsourceType to the name of your callback function and leave the Rowsource property blank.
An example of the callback function is found in the A97 help (though I can't find the same example in the A2K3 help). In A97 help, you get there by searching for RowsourceType, and then in the help window, click on the link in the sentence reading "You can also set the RowSourceType property with a ____user-defined function____."
To check this out, you just need to find out the length of the string returned from GetValueListArray() by each of the arrays referenced in the OnOpen event.
It also might be helpful to add an error handler to the OnOpen event, particularly given that there are so many outside dependencies in the code in that particular sub.
And last of all, let me say that it looks like horrible programming. Most of this ought to be settable with default properties, seems to me. I also question that kind of dependency on OpenArgs with such an undocumented input value. What does "5" mean? And what does "1" mean? Is that documented somewhere? It's just terrible, terrible code, in my opinion.
I'd likely do this with a standalone class module instead, because that will be self-documenting in terms of what does what. You'd set a particular named property to 5 and that would control what the form gets from the class module methods for populating the combo boxes. It would all be in one place, and you could use a meaningful property name to make it clear what the values 5 and 1 represent. It's particularly helpful to do this if you have the same kind of code in the OnOpen event of multiple forms. In that case, it's a no-brainer to move it out of the form modules, and the only question is whether you put it in a regular module or in a standalone class module (as I'm suggesting).
Anyway, perhaps none of this is on point, but it might give you some ideas.
Could it be the security settings is Access? All recent versions of Access has a security settings dialog where you can enable (or disable) macros in the application. I think you will get this error if macros are disabled.
Are you sure one of the required references (VBA IDE > Option > References) isn't missing?
If you're referencing Excel/Word or external objects, are you sure that the references to the type libraries are the right ones (if you're using specific versions instead of doing late binding)
Are you building the MDE on a 64 bit machine by any chance?
What is the code on the form frmNewPeerGroup? What version of Access are you using? If it is 2003, sp3 causes problems for which there is a hotfix. Have you tried decompile and / or compact and repair?
If you have an original mdb, check the references to make sure that none of them are marked MISSING. This is quite a likely reason for problem in that it has suddenly occurred.
To check the references, look at Tools->References on the menu for a code window.
If no references are missing, you could try stepping through the form code to get a more exact idea of where the error is occurring.