How would I programmatically show items hidden on startup? - ms-access

I have an Access database that is set to just show my forms and hide the ribbon and table explorer.
This works fine, except for me.
I want to be able to open the database from a shortcut, just as if I held down the Shift Key to bypass the startup routines.
I detect the command line parameter. I close the login form.
What all do I need to turn on to get back to a fully functioning version of Access without bothering with a shift key?
Here are a couple of candidates that I found from someone who was disabling everything. I need to turn them back on. But, I can't see how this worked in the original, and doesn't work at all for me.
StartUpShowStatusBar = True // Done
AllowShortcutMenus = True
AllowFullMenus = True
AllowBuiltInToolbars = True
AllowToolbarChanges = True
AllowSpecialKeys = True
UseAppIconForFrmRpt = True

You have already seen my answer here to hide ribbon and navigation pane. I am posting here to show them again by clicking a button. Below is both code to hide and then show ribbon and navigation pane.
Codes to hide-
Private Sub Form_Load()
On Error GoTo HarunErrHandler
'******************* Hide Ribbon and Navigation Pane ***************************
DoCmd.ShowToolbar "Ribbon", acToolbarNo
Call DoCmd.NavigateTo("acNavigationCategoryObjectType")
Call DoCmd.RunCommand(acCmdWindowHide)
'*******************************************************************************
Exit Sub
HarunErrHandler:
MessageBox = MsgBox("Error Number: " & Err.Number & vbCrLf & Err.Description, vbInformation, "Error")
End Sub
To show ribbon and left pane-
Private Sub cmdShow_Click()
On Error GoTo HarunErrHandler
'******************* Show Ribbon and Navigation Pane ***************************
DoCmd.ShowToolbar "Ribbon", acToolbarYes
Call DoCmd.SelectObject(acTable, , True)
'*******************************************************************************
Exit Sub
HarunErrHandler:
MessageBox = MsgBox("Error Number: " & Err.Number & vbCrLf & Err.Description, vbInformation, "Error")
End Sub

Based on Harun's answer, I was able to build this, which seems to bring everything back.
Private Sub Form_Load()
On Error GoTo ErrHandler
If CheckKeyFiles = True Then
Me!txtUID = "workflow"
Me!txtSID = GetSID("workflow")
End If
Me!txtVersionDate = "Version " & GetVersionDate()
If Command = "develop" Then
DoCmd.Close acForm, "Dialog_Login"
DoCmd.SelectObject acTable, , True
Application.SetOption "Show Status Bar", True
CurrentDb.Properties("AllowFullMenus") = True
CurrentDb.Properties("AllowBuiltInToolbars") = True
CurrentDb.Properties("AllowToolbarChanges") = True
CurrentDb.Properties("AllowSpecialKeys") = True
DoCmd.ShowToolbar "Ribbon", acToolbarYes
End If
Exit Sub
ErrHandler:
Dim Response
Response = MsgBox("Error Number: " & Err.Number & vbCrLf & Err.Description, vbInformation, "Error")
End Sub

Related

DoEvent() Returns 0 BUT Run-time Error 2585 This action can't be carried out while processing a form or report event

This code was running without a hitch, but now getting Error 2585.
I have looked at Gustav's answer and Gord Thompson's answer but unless I am missing something (quite possible!) the first does not work and the second seems inapplicable. I saw on another site a suggestion that there might be a duplicate record ID, but I check for that possibility.
I put a call to DoEvent() in response to this error but it returns zero. I also wait for 10 seconds to let other processes run. Still receive the error.
Private Sub SaveData_Click()
Dim myForm As Form
Dim myTextBox As TextBox
Dim myDate As Date
Dim myResponse As Integer
If IsNull(Forms!Ecoli_Data!DateCollected.Value) Then
myReponse = myResponse = MsgBox("You have not entered all the required data. You may quit data entry by hitting 'Cancel'", vbOKOnly, "No Sample Date")
Forms!Ecoli_Data.SetFocus
Forms!Ecoli_Data!Collected_By.SetFocus
GoTo endOfSub
End If
If Me.Dirty Then Me.Dirty = False
myDate = Me.DateCollected.Value
Dim yearAsString As String, monthAsString As String, dayAsString As String, clientInitial As String
Dim reportNumberText As String
reportNumberText = Me!SampleNumber.Value
Debug.Print "reportNumberText = " & reportNumberText
Debug.Print "CollectedBy Index: " & Me!Collected_By & " Employee Name: " & DLookup("CollectedBy", "Data_Lookup", Me.Collected_By)
Dim whereString As String
whereString = "SampleNumber=" & "'" & reportNumberText & "'"
Debug.Print whereString
On Error GoTo errorHandling
DoCmd.OpenReport "ECOLI_Laboratory_Report", acViewPreview, , whereString
DoCmd.PrintOut
DoCmd.Close acReport, "ECOLI_Laboratory_Report", acSaveNo
Dim eventsOpen As Integer
eventsOpen = DoEvents()
Debug.Print "Number of Open Events = " & DoEvents()
Dim PauseTime, Start, Finish, TotalTime
PauseTime = 10 ' Set duration.
Start = Timer ' Set start time.
Do While Timer < Start + PauseTime
DoEvents ' Yield to other processes.
Loop
Finish = Timer ' Set end time.
TotalTime = Finish - Start ' Calculate total time.
myResponse = MsgBox("Processing Report Took " & TotalTime & " seconds.", vbOKOnly)
myResponse = MsgBox("Do you want to add more data?", vbYesNo, "What Next?")
If myResponse = vbYes Then
DoCmd.Close acForm, "ECOLI_Data", acSaveYes
Error Generated By Line Above and occurs whether response Y or N to MsgBox.
DoCmd.OpenForm "ECOLI_Data", acNormal, , , acFormAdd
DoCmd.GoToRecord , , acNewRec
Else
DoCmd.Close acForm, "ECOLI_Data", acSaveYes
End If
Exit Sub
errorHandling:
If Err.Number = 2501 Then
myResponse = MsgBox("Printing Job Cancelled", vbOkayOnly, "Report Not Printed")
ElseIf Err.Number = 0 Then
'Do nothing
Else
Debug.Print "Error Number: " & Err.Number & ": " & Err.Description
myResponse = MsgBox("An Error occurred: " & Err.Description, vbOKOnly, "Error #" & Err.Number)
End If
If Application.CurrentProject.AllForms("ECOLI_Data").IsLoaded Then DoCmd.Close acForm, "ECOLI_Data", acSaveNo
If Application.CurrentProject.AllReports("ECOLI_Laboratory_Report").IsLoaded Then DoCmd.Close acReport, "ECOLI_Laboratory_Report", acSaveNo
endOfSub:
End Sub
Any idea on what am I missing here? Thanks.
I can't replicate the problem, but the following might help:
I assume you run into troubles because you're closing and opening the form in the same operation. To avoid doing this, you can open up a second copy of the form, and close the form once the second copy is open. This avoids that issue.
To open a second copy of the form:
Public Myself As Form
Public Sub CopyMe()
Dim myCopy As New Form_CopyForm
myCopy.Visible = True
Set myCopy.Myself = myCopy
End Sub
(CopyForm is the form name)
To close a form that may or may not be a form created by this function
Public Sub CloseMe()
If Myself Is Nothing Then
DoCmd.Close acForm, Me.Name
Else
Set Myself = Nothing
End If
End Sub
More information on having multiple variants of the same form open can be found here, but my approach differs from the approach suggested here, and doesn't require a second object to hold references and manage copies.
This line of code
`DoCmd.Close acForm, "ECOLI_Data", acSaveYes`
doesn't save the record you are on, it just saves any changes to the form design.
You should probably use
If Me.Dirty Then Me.dirty = False
to force a save of the current record if any data has changed.

MS Access 2010 - MsgBox to Run Query & Delete Record Not Working

I have a button on a Continuous subform with the below VBA attached -
Private Sub del_Click()
On Error GoTo del_Click_Err
Dim LResponse As Integer
On Error Resume Next
DoCmd.GoToControl Screen.PreviousControl.Name
Err.Clear
If (Not Form.NewRecord) Then
LResponse = Eval("MsgBox('You are about to delete a record.'" & _
"'#If you click yes, you won't be able to undo this delete operation.' & Chr(13) & Chr(10) & " & _
"'Are you sure you want to delete this record?##', 276, 'Are you sure?')")
If LResponse = vbYes Then
DoCmd.SetWarnings False
DoCmd.OpenQuery "qry_DeleteSpecific"
DoCmd.RunCommand acCmdDeleteRecord
DoCmd.SetWarnings True
Else
End If
End If
If (Form.NewRecord And Not Form.Dirty) Then
Beep
End If
If (Form.NewRecord And Form.Dirty) Then
DoCmd.RunCommand acCmdUndo
End If
If (MacroError <> 0) Then
Beep
MsgBox MacroError.Description, vbOKOnly, ""
End If
del_Click_Exit:
DoCmd.SetWarnings True
Exit Sub
del_Click_Err:
MsgBox Error$
Resume del_Click_Exit
End Sub
The button was originally the auto-generated 'Delete Record' button and I have since modified it to include the query activation as well as my own msgBox.
The 'delete' button obviously worked fine before modification. The query also works as intended and I tested a button on a seperate form that just included the MsgBox code, which also worked.
But bringing it all together has failed somehow. When I click the button I don't get the MsgBox and it doesn't delete a record or run the query.
DoCmd.GoToControl Screen.PreviousControl.Name
This line appears to have fired correctly though.
Could anybody explain what may be going wrong with this?
---Edit---
Replaced
Error Clear
With
On Error GoTo del_Click_Err
I now get the error message -
The expression you entered contains invalid syntax
So it turns out it was all in the Quotes. The quotation issue is still a bit of a mystery to me, but I managed to get my code working.
Here's the change -
LResponse = Eval("MsgBox(""You are about to delete a record."" & " & _
"""#If you click yes, you won't be able to undo this delete operation."" & Chr(13) & Chr(10) & " & _
"""Are you sure you want to delete this record?##"", 276, ""Are you sure?"")")
Single quotes seemed to work when it was just the msgBox code by itself but not in the extended code. Anyway, I'll know to look out for this again.
#Andre your comment helped me debug this. I initially left 'Error Clear' as that was what the wizard put in for the delete button.

MSACCESS.EXE does not close when using POP-UP forms

Others have had issues with the MSACCESS.EXE process not closing (from Task Manager) when exiting their databases. Each of the posts I've read have had something to do with not properly closing recordset variables.
When I exit the database I'm working on, I notice the MSACCESS.EXE process moves from the "Apps" section to "Background Processes" in Win 10 Task Manager. This hung process continues to utilize RAM. I'm certain that I'm closing all recordset variables properly.
Through a lot of debugging, I figured out a simple way to replicate the problem:
Create two forms in a new Access database. Set the PopUp property to True for one of them and False for the other. Save the forms "PopUp" and "NoPopUp" and close the database.
Open Task Manager to view the processes running on your screen.
Open your Access database and open the NoPopUp form. Note the MSACCESS.EXE process under Apps.
Close your database. Note that MSACCESS.EXE is removed from your list of Processes (both under "Apps" and "Background Processes").
Now reopen your Access database and open form PopUp. Then close the database.
Note that the MSACCESS.EXE process moves from the "Apps" section to "Background Processes" and is still utilizing system memory.
Additional MSACCESS.EXE processes hang in Task Manager each time the database is closed after opening a form with its Pop-up property set to True.
My database uses a ton of Pop-up forms. How should I be closing my database so that these hung processes aren't stacking up? (I'm using Access 2013 in Windows 10.)
Thanks,
Sam
How are you closing your database now?
Can you change the command to call a function.
Then in that function call a routine that closes all open forms
You may have to add parameter to close without saving - depending on your results.
Function CloseAllOpenFrms()
On Error GoTo Error_Handler
Dim DbF As Access.Form
Dim DbO As Object
Set DbO = Application.Forms 'Collection of all the open forms
For Each DbF In DbO 'Loop all the forms
DoCmd.Close acForm, DbF.Name, acSaveNo
Next DbF
Error_Handler_Exit:
On Error Resume Next
Set DbF = Nothing
Set DbO = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occured." & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: CloseAllOpenFrms" & vbCrLf & _
"Error Description: " & Err.Description, _
vbCritical, "An Error has Occured!"
Resume Error_Handler_Exit
End Function
From http://www.devhut.net/2015/02/17/ms-access-vba-close-all-open-forms/
Try this very basic example in a new sample database.
EDIT: Add a Sleep and DoEvents after every close form in case of caching/fast cpu getting ahead of code? Last attempt to fix weird issue.
In Module 1
Option Compare Database
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Function CloseAllOpenFrms()
On Error GoTo Error_Handler
Dim DbF As Access.Form
Dim DbO As Object
Set DbO = Application.Forms 'Collection of all the open forms
' Close all popups first
For Each DbF In DbO 'Loop all the forms
If DbF.PopUp Then
DoCmd.Close acForm, DbF.Name, acSaveNo
DoEvents
Sleep 1000
End If
Next DbF
' Close remaining forms
For Each DbF In DbO 'Loop all the forms
DoCmd.Close acForm, DbF.Name, acSaveNo
DoEvents
Sleep 1000
Next DbF
Application.Quit acQuitSaveNone
Error_Handler_Exit:
On Error Resume Next
Set DbF = Nothing
Set DbO = Nothing
Exit Function
Error_Handler:
MsgBox "Error closing : " & DbF.Name & vbCrLf & _
"Error Description: " & Err.Description, _
vbCritical, "Error closing form"
Resume Error_Handler_Exit
End Function
Create basic Form1 with two command buttons:
Command button Command1 (Caption= Open Popup Form)
Command button Command0 (Caption = Exit DB)
In Form1's form module paste text
'------------------------------------------------------------
' Command1_Click
'
'------------------------------------------------------------
Private Sub Command1_Click()
On Error GoTo Command1_Click_Err
CloseAllOpenFrms
Command1_Click_Exit:
Exit Sub
Command1_Click_Err:
MsgBox Error$
Resume Command1_Click_Exit
End Sub
'------------------------------------------------------------
' Command0_Click
'
'------------------------------------------------------------
Private Sub Command0_Click()
On Error GoTo Command0_Click_Err
DoCmd.OpenForm "Form2-popup", acNormal, "", "", , acWindowNormal
Command0_Click_Exit:
Exit Sub
Command0_Click_Err:
MsgBox Error$
Resume Command0_Click_Exit
End Sub
Create another form Form2-popup and set Popup property to true
Add command button Command1 with caption "Exit Form"
'------------------------------------------------------------
' Command1_Click
'
'------------------------------------------------------------
Private Sub Command1_Click()
On Error GoTo Command1_Click_Err
DoCmd.Close , ""
Command1_Click_Exit:
Exit Sub
Command1_Click_Err:
MsgBox Error$
Resume Command1_Click_Exit
End Sub

How can I remove the pesky "The runCommand action was canceled" dialog box after a "cancel = true" statement

On the Form_beforeupdate() event of my form "Alias" I have this...
If IsNull(Me.txtFName) And IsNull(Me.txtLName) Then
MsgBox "You must enter a contact!", vbokayonly, "Contact"
Cancel = True
End If
Anytime this cancels a runCommand code such as...
DoCmd.RunCommand acCmdSaveRecord
a dialog appears telling me that it was canceled. Is there a way to suppress those dialogs?
You can add an error handler to trap and ignore error 2501, which is triggered when the form's Before Update event cancels DoCmd.RunCommand acCmdSaveRecord
The following example is from my form which has a command button to save the current record. It suppresses that "RunCommand action was canceled" message as I think you wish.
Since your form's code apparently calls DoCmd.RunCommand acCmdSaveRecord from multiple locations, replace each of those calls with SaveRecord as I did in cmdSave_Click().
Option Compare Database
Option Explicit ' <-- NEVER troubleshoot VBA code without this!!!
Private Sub cmdSave_Click()
'DoCmd.RunCommand acCmdSaveRecord
SaveRecord
End Sub
Private Sub SaveRecord()
Dim strMsg As String
On Error GoTo ErrorHandler
DoCmd.RunCommand acCmdSaveRecord
ExitHere:
Exit Sub
ErrorHandler:
Select Case Err.Number
Case 2501 ' The RunCommand action was canceled.
' do nothing --> just ignore the error
Case Else
' notify user about any other error
strMsg = "Error " & Err.Number & " (" & Err.Description _
& ") in procedure SaveRecord"
MsgBox strMsg
End Select
Resume ExitHere
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
If IsNull(Me.txtBlock_start.Value) Then
MsgBox "You must enter a start time!", vbOKOnly, "Start Time"
Cancel = True
End If
End Sub
I ended up doing this on a 'Save and Open the Receipts form' button.
Private Sub btnSaveOpenReceipts_Click()
'''''SaveRecord'''''
If (Me.Dirty) Then
SaveRecord
End If
'''''OpenReciepts'''''
If (Me.Dirty) Then 'unsure it saved
Exit Sub
Else
'blah blah blah
End If
End Sub

Programmatically Create a Button That Opens a Form In Access

When my database is opened, it shows a form with a "loading bar" that reports the progress of linking external tables and such, before showing a "Main Menu" form. The Main Menu has code that generates a form programmatically behind the scenes with buttons on it, and when that's done it saves and renames the form, and assigns it as the SourceObject to a subform.
This all works fine and dandy, that is, until I decide to make the buttons actually do something useful. In the loop that generates the buttons, it adds VBA code to the subform-to-be's module. For some reason, doing that makes VBA finish execution, then stop. This makes the (modal) loading form not disappear as there's an If statement that executes a DoCmd.Close to close the loading form when it's done loading. It also breaks functionality that depends on a global variable being set, since the global is cleared when execution halts.
Is there a better way to go about creating buttons that do stuff programmatically, short of ditching Access outright and writing real code? As much as I would love to, I'm forced to do it in Access in case I leave the company so the less tech-savvy employees can still work with it in my absence.
Below are bits and pieces of relevant code, if needed.
Form_USysSplash:
'Code that runs when the form is opened, before any processing.
Private Sub Form_Open(Cancel As Integer)
'Don't mess with things you shouldn't be.
If g_database_loaded Then
MsgBox "Please don't try to run the Splash form directly.", vbOKOnly, "No Touching"
Cancel = True
Exit Sub
End If
'Check if the user has the MySQL 5.1 ODBC driver installed.
Call CheckMysqlODBC 'Uses elfin majykks to find if Connector/ODBC is installed, puts the result into g_mysql_installed
If Not g_mysql_installed Then
Cancel = True
DoCmd.OpenForm "Main"
Exit Sub
End If
End Sub
'Code that runs when the form is ready to render.
Private Sub Form_Current()
'Prepare the form
boxProgressBar.width = 0
lblLoading.caption = ""
'Render the form
DoCmd.SelectObject acForm, Me.name
Me.Repaint
DoEvents
'Start the work
LinkOMTables
UpdateStatus "Done!"
DoCmd.OpenForm "Home"
f_done = True
End Sub
Private Sub Form_Timer() 'Timer property set to 100
If f_done Then DoCmd.Close acForm, Me.name
End Sub
Form_Home:
'Code run before the form is displayed.
Private Sub Form_Load()
'Check if the user has the MySQL 5.1 ODBC driver installed.
'Header contains an error message and a download link
If Not g_mysql_installed Then
FormHeader.Visible = True
Detail.Visible = False
Else
FormHeader.Visible = False
Detail.Visible = True
CreateButtonList Me, Me.subTasks
End If
End Sub
'Sub to create buttons on the form's Detail section, starting at a given height from the top.
Sub CreateButtonList(ByRef frm As Form, ByRef buttonPane As SubForm)
Dim rsButtons As Recordset
Dim newForm As Form
Dim newButton As CommandButton
Dim colCount As Integer, rowCount As Integer, curCol As Integer, curRow As Integer
Dim newFormWidth As Integer
Dim taskFormName As String, newFormName As String
Set rsButtons = CurrentDb.OpenRecordset("SELECT * FROM USysButtons WHERE form LIKE '" & frm.name & "'")
If Not rsButtons.EOF And Not rsButtons.BOF Then
taskFormName = "USys" & frm.name & "Tasks"
On Error Resume Next
If TypeOf CurrentProject.AllForms(taskFormName) Is AccessObject Then
buttonPane.SourceObject = ""
DoCmd.DeleteObject acForm, taskFormName
End If
Err.Clear
On Error GoTo 0
Set newForm = CreateForm
newFormName = newForm.name
With newForm
.Visible = False
.NavigationButtons = False
.RecordSelectors = False
.CloseButton = False
.ControlBox = False
.width = buttonPane.width
.HasModule = True
End With
rsButtons.MoveLast
rsButtons.MoveFirst
colCount = Int((buttonPane.width) / 1584) 'Twips: 1440 in an inch. 1584 twips = 1.1"
rowCount = Round(rsButtons.RecordCount / colCount, 0)
newForm.Detail.height = rowCount * 1584
curCol = 0
curRow = 0
Do While Not rsButtons.EOF
Set newButton = CreateControl(newForm.name, acCommandButton)
With newButton
.name = "gbtn_" & rsButtons!btn_name
.Visible = True
.Enabled = True
.caption = rsButtons!caption
.PictureType = 2
.Picture = rsButtons!img_name
.PictureCaptionArrangement = acBottom
.ControlTipText = rsButtons!tooltip
.OnClick = "[Event Procedure]"
'This If block is the source of my headache.
If Not IsNull(rsButtons!open_query) And rsButtons!open_query <> "" Then
newForm.Module.InsertLines newForm.Module.CountOfLines, _
"Private Sub gbtn_" & rsButtons!btn_name & "_Click()"
newForm.Module.InsertLines newForm.Module.CountOfLines, _
"DoCmd.OpenQuery """ & rsButtons!open_query & """"
newForm.Module.InsertLines newForm.Module.CountOfLines, _
"End Sub" & vbCrLf & vbCrLf
ElseIf Not IsNull(rsButtons!open_form) And rsButtons!open_form <> "" Then
newForm.Module.InsertLines newForm.Module.CountOfLines, _
"Private Sub gbtn_" & rsButtons!btn_name & "_Click()"
newForm.Module.InsertLines newForm.Module.CountOfLines, _
"DoCmd.OpenForm """ & rsButtons!open_form & """"
newForm.Module.InsertLines newForm.Module.CountOfLines, _
"End Sub" & vbCrLf & vbCrLf
End If
.height = 1584
.width = 1584
.Top = 12 + (curRow * 1584)
.Left = 12 + (curCol * 1584)
.BackThemeColorIndex = 1
.HoverThemeColorIndex = 4 'Accent 1
.HoverShade = 0
.HoverTint = 40 '60% Lighter
.PressedThemeColorIndex = 4 'Accent 1
.PressedShade = 0
.PressedTint = 20 '80% Lighter
End With
curCol = curCol + 1
If curCol = colCount Then
curCol = 0
curRow = curRow + 1
End If
rsButtons.MoveNext
Loop
DoCmd.Close acForm, newForm.name, acSaveYes
DoCmd.Rename taskFormName, acForm, newFormName
buttonPane.SourceObject = taskFormName
End If
End Sub
There is no need to write code while code is running, especially as you are writing essentially the same code over and over again. All you need do is call a function instead of an event procedure.
In your code above write the OnClick event like this:
If Not IsNull(rsButtons!open_query) And rsButtons!open_query <> "" Then
.OnClick = "=MyOpenForm(""" & rsButtons!open_form & """)"
ElseIf Not IsNull(rsButtons!open_form) And rsButtons!open_form <> "" Then
.OnClick = "=MyOpenQuery(""" & rsButtons!open_form & """)"
End If
Then create these two permanent (non-generated) functions somewhere the form can see them:
Public Function MyOpenForm(FormName as String)
DoCmd.OpenForm FormName
End Function
Public Function MyOpenQuery(QueryName as String)
DoCmd.OpenQuery QueryName
End Function
And ditch the code writing to the module.