I have an Access form users sometimes forget to save. I put in a BeforeUpdate trigger to pop up message reminding users to save or cancel before taking any action.
I found this code on the net and it works for everything except my "New Record" button.
As far as I know Me.Dirty should do the trick.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim ctl As Control
On Error GoTo Err_BeforeUpdate
' The Dirty property is True if the record has been changed.
If Me.Dirty Then
' Prompt to confirm the save operation.
If MsgBox("Do you want to save?", vbYesNo + vbQuestion, _
"Save Record") = vbNo Then
Me.Undo
End If
End If
Exit_BeforeUpdate:
Exit Sub
Err_BeforeUpdate:
MsgBox Err.Number & " " & Err.Description
Resume Exit_BeforeUpdate
End Sub
The code for the new record
Private Sub new_Click()
njno = NewJobNbr()
Job.Value = njno
RnK.Value = ""
Date_Requested.Value = ""
Est_Time.Value = ""
Originator.Value = ""
Date_Required.Value = ""
Description.Value = ""
Reason_for_Request.Value = ""
Comments.Value = ""
Priority_Tasks.Value = ""
TName.Value = ""
Required.Value = ""
Costing.Value = ""
Completed.Value = ""
Date_Completed.Value = ""
End Sub
I don't really understand what njno is. If the textboxes are bound to the form's RecordSource then.
On form Current event use:
Private Sub Form_Current ()
If Me.NewRecord Then
Job.Value = njno
End if
End Sub
Then on the button Click event use:
Private Sub new_Click()
DoCmd.GoToRecod,,acNewRec
End sub
Related
My sub Workbook_BeforeClose runs twice, because in my Sub CloseWBFromSharePointFolder, I either check in my file, discard it or cancel and do nothing (see code below). Both the check in and the discarding of the file trigger Workbook_BeforeClose to run again.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
CloseWBFromSharePointFolder
End Sub
Both snippets from CloseWBFromSharePointFolder which trigger Workbook_BeforeClose
Check in
ActiveWorkbook.CheckIn SaveChanges:=True, Comments:="Checked-In by " & Application.Username
Discard
Application.ActiveWorkbook.CheckIn False
Any help would be appreciated.
P.s. I also tried to use a public variable to track if it runs again. This does not work because the public variable got reset. The explanation I found is because Workbook_BeforeClose calls CloseWBFromSharePointFolder, which then triggers Workbook_BeforeClose. This resets everything and the public variable becomes empty
P.s.2 for more details.
CloseWBFromSharePointFolder Code
Sub CloseWBFromSharePointFolder()
Dim myForm1 As UserForm1
Set myForm1 = UserForm1
myForm1.Caption = "Choose before closing:"
myForm1.Show
End Sub
UserForm1 Code
Dim Buttons() As New BtnClass
Private Sub UserForm_Initialize()
Dim ButtonCount As Integer
Dim ctl As Control
' Create the Button objects
ButtonCount = 0
For Each ctl In UserForm1.Controls
If TypeName(ctl) = "CommandButton" Then
'Skip the OKButton
If ctl.Name <> "OKButton" Then
ButtonCount = ButtonCount + 1
ReDim Preserve Buttons(1 To ButtonCount)
Set Buttons(ButtonCount).ButtonGroup = ctl
End If
End If
Next ctl
Me.CommandButton1.Caption = "Check in"
Me.CommandButton2.Caption = "Discard check-out"
Me.CommandButton3.Caption = "Keep checked-out"
Me.CommandButton4.Caption = "Cancel"
End Sub
BtnClass Code
Public WithEvents ButtonGroup As MsForms.CommandButton
Private Sub ButtonGroup_Click()
If UserForm1.Visible = True Then
Select Case ButtonGroup.Name
Case "CommandButton1" 'check in
CheckIn
Case "CommandButton2" 'Discard check-out
Discard
Case "CommandButton3" 'Keep checked-out
KeepCheckedOut
Case Else ' Cancel
'Do Nothing
End Select
Unload UserForm1
ElseIf UserForm2.Visible = True Then
Select Case ButtonGroup.Name
Case "CommandButton1" 'check out
CheckOut
Case "CommandButton2" 'Read only
'Do Nothing
Case Else ' Cancel
'Do Nothing
End Select
Unload UserForm2
End If
End Sub
Sub CheckIn()
If ActiveWorkbook.CanCheckIn = True Then
'Check In, Save and Close
ActiveWorkbook.CheckIn SaveChanges:=True, Comments:="Checked-In by " & Application.Username
MsgBox ("File sucessfully checked in")
Else
MsgBox ("File could not be checked in!")
End If
End Sub
My content in sheet2 was hidden and only after user form popped up and enter the password before the content can unhide. However with the warning message, even after I select "yes to terminate" my sheet content still unhides.
Expected outcome:
After the user selects "yes to terminate" on the warning message, it is suppose to drop the user form. Can anyone help me solve it?
Under worksheet(sheet2):
Private Sub Worksheet_Activate()
If Sheets("Reference").Columns("A:K").EntireColumn.Hidden = True Then
Password.Show
Call unhide
Else
Sheets("Reference").Columns("A:K").EntireColumn.Hidden = False
End If
End Sub
Under userform (Password):
Private Sub Submit_Click()
If Me.Pword.Value = "123" Then
Unload Me
Call unhide
Else
Me.Hide
Retry = MsgBox("The password is incorrect. Do you wish to try again?", _
vbYesNo, "Retry?")
Select Case Retry
Case Is = vbYes
Me.Pword.Value = ""
Me.Pword.SetFocus
Me.Show
Case Is = vbNo
Unload Me
End Select
End If
End Sub
Private Sub cmdExit_Click()
If ExitAsk = vbYes Then Unload Password
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
If Not ExitAsk = vbYes Then Cancel = True
End If
End Sub
Private Function ExitAsk() As VbMsgBoxResult
Dim Smsg As String
Smsg = "Do you really want to exit? Click Yes to Quit or No to Continue."
ExitAsk = MsgBox(Smsg, vbYesNo + vbDefaultButton2 + vbQuestion, "Exit!")
End Function
I have a form that opens and takes data from a table; and puts it in text boxes. There is button on this form, named "CustomerInfoBackBtn".
The code I have inside of it that doesn't work (well, it might... just Access automatically saves the data anyways when I edit the text boxes) is this:
Private Sub CustomerInfoBackBtn_Click()
Dim LResponse As Integer
LResponse = MsgBox("Would you like to save?", vbYesNo, "Save?")
If LResponse = vbYes Then
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Close
DoCmd.OpenForm "CustomerListF"
Else
DoCmd.Close
DoCmd.OpenForm "CustomerListF"
End If
End Sub
How do I make it pop up the msgbox asking them if they would like to save, and if they push yes it saves, then refreshes the subform and THEN opens the previous form (CustomerListF) and if they push no, it doesn't save, reverts information to what it was before, and opens up the previous form? I think all I really need is a way to stop access from automatically saving the data changes, but I am not sure.
Edit for answer:
Code in button that pulls up that error:
Dim TempSaveRecord As Boolean
Private Sub CustomerNotesBackBtn_Click()
If MsgBox("Do you want to save your changes?", vbInformation + vbYesNo, [Warning! Some data may be lost.]) = vbNo Then
TempSaveRecord = False
Else
TempSaveRecord = True
End If
DoCmd.Close
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
If (TempSaveRecord) Then
DoCmd.Save
Else
DoCmd.RunCommand acCmdUndo
End If
End Sub
Here is what I do to control whether a record is saved or not.
Make sure that the Close Button property of the form is set to No so that the user will have to click on the Back button, Then use the following code:
Dim TempSaveRecord as Boolean
Private Sub cmdBack_Click()
If MsgBox("Do you want to save your changes?", vbInformation + vbYesNo) = vbNo Then
TempSaveRecord = False
Else
TempSaveRecord = True
End If
DoCmd.Close
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
If (TempSaveRecord) Then
DoCmd.Save
Else
DoCmd.RunCommand acCmdUndo
End If
End Sub
Then when the Form closes you can force any other form to Refresh using the following:
Private Sub Form_Close()
[Forms]![MyFormName].Refresh
End Sub
Form bounded DAO.Recordset are saved automatically by DAO Engine without any user action. In your case Modifications can be saved any time without warning, or before clicking on [Back] or [Close] button.
You can work around like this with transaction here or ADO:
Option Compare Database
Option Explicit
Private boolFrmDirty As Boolean
Private boolFrmSaved As Boolean
Private Sub Form_AfterDelConfirm(Status As Integer)
If Me.Saved = False Then Me.Saved = (Status = acDeleteOK)
End Sub
Private Sub Form_AfterUpdate()
Me.Saved = True
End Sub
Private Sub Form_Delete(Cancel As Integer)
If Me.Dirtied = False Then DBEngine.BeginTrans
Me.Dirtied = True
End Sub
Private Sub Form_Dirty(Cancel As Integer)
If Me.Dirtied = False Then DBEngine.BeginTrans
Me.Dirtied = True
End Sub
Private Sub Form_Open(Cancel As Integer)
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT * FROM Customers", dbOpenDynaset)
Set Me.Recordset = rs
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim msg As Integer
If Me.Saved Then
msg = MsgBox("Do you want to commit all changes?", vbYesNoCancel)
Select Case msg
Case vbYes
DBEngine.CommitTrans
Case vbNo
DBEngine.Rollback
Case vbCancel
Cancel = True
End Select
Else
If Me.Dirtied Then DBEngine.Rollback
End If
End Sub
Public Property Get Dirtied() As Boolean
Dirtied = boolFrmDirty
End Property
Public Property Let Dirtied(boolFrmDirtyIn As Boolean)
boolFrmDirty = boolFrmDirtyIn
End Property
Public Property Get Saved() As Boolean
Saved = boolFrmSaved
End Property
Public Property Let Saved(boolFrmSavedIn As Boolean)
boolFrmSaved = boolFrmSavedIn
End Property
If you use ADODB.Recordset as form.Recordset,
Dim rst As ADODB.Recordset
'
'... Create it by querying a remote db.
'
Set Me.Recordset = rst
You thus can control saving or abandon of user modifications, As ADO driver can not save to the Database itself... It's more complicated.
Code from Reference
I know this is probably a stupid question, but you know what they say. I have VBA in an Access Database with commands for On Click. Essentially it is a form with a combo box and timestamp for user login. Once the button is clicked a data entry form will load dependent upon which name is selected from the Combo Box. I would like for the Login Form to close once the data entry form has opened. The problem is that no matter where I put the DoCmd.Close the stupid form won't CLOSE!
In case it matters this form is set to open automatically when a user opens the database.
Below is the VBA for the Event Procedure associated with the button.
Option Compare Database
Private Sub TimeInButton_Click()
Dim strLoginForm As String
If Me.AgentCombo = "Amber" Then
strForm = "frmCustomersAmber"
ElseIf Me.AgentCombo = "Amanda" Then
strForm = "frmCustomersAmanda"
ElseIf Me.AgentCombo = "Brett" Then
strForm = "frmCustomersBrett"
ElseIf Me.AgentCombo = "Marcus" Then
strForm = "frmCustomersMarcus"
ElseIf Me.AgentCombo = "Terrah" Then
strForm = "frmCustomersTerrah"
End If
'------------------------------------------------------------
' TimeInButton_Click
'
'------------------------------------------------------------
On Error GoTo TimeInButton_Click_Err
On Error Resume Next
DoCmd.GoToRecord , "", acNewRec
If (MacroError <> 0) Then
Beep
MsgBox MacroError.Description, vbOKOnly, ""
End If
DoCmd.OpenForm strForm
TimeInButton_Click_Exit:
Exit Sub
TimeInButton_Click_Err:
MsgBox Error$
Resume TimeInButton_Click_Exit
End Sub
DoCmd.Close takes optional arguments that will make it much more reliable. For example,
DoCmd.Close acForm, "MyFormName"
We have a userform with multiple textboxes and we would like to build something similar to the link image below, in terms of showing what the user should input in each text box:
http://d2o0t5hpnwv4c1.cloudfront.net/426_formsBestPractices/comments.png
The "default" text would disappear once the user starts typing (as opposed than once the user "lands" cursor within the textbox.
Also, if nothing gets entered within the textbox the default text would not be submitted and a blank would be used.
Can this be done?
Any suggestions will be greatly appreciated.
Can I ask why you want the default text to dissapear once a user changes the text and not once they enter the textbox?
This is not what most users will expect, I think it will be slightly confusing for some and wouldn't recommend it. The user will most likely try and delete the old text before typing their new text creating extra work.
I would use something like this:
Const sNameDefault As String = "Your Name Here"
Const sEmailDefault As String = "Your Email Here"
Private Sub UserForm_Initialize()
Me.TextBox1.Text = sNameDefault
Me.TextBox2.Text = sEmailDefault
CommandButton1.SetFocus
End Sub
'// TextBox1 - Name
Private Sub TextBox1_Enter()
With Me.TextBox1
If .Text = sNameDefault Then .Text = vbNullString
End With
End Sub
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
With Me.TextBox1
If .Text = vbNullString Then .Text = sNameDefault
End With
End Sub
'// TextBox2 - Email
Private Sub TextBox2_Enter()
With Me.TextBox2
If .Text = sEmailDefault Then .Text = vbNullString
End With
End Sub
Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
With Me.TextBox2
If .Text = vbNullString Then .Text = sEmailDefault
End With
End Sub
Private Sub CommandButton1_Click()
Dim sName As String, sEmail As String
'// Get Name
If Me.TextBox1.Text = sNameDefault Then
sName = vbNullString
Else
sName = Me.TextBox1.Text
End If
'// Get Email
If Me.TextBox2.Text = sEmailDefault Then
sEmail = vbNullString
Else
sEmail = Me.TextBox2.Text
End If
MsgBox ("Your Name: " & sName & vbNewLine & " Your Email:" & sEmail)
Unload Me
End Sub
The above example is simply a userform with two textbox's and a commandbutton. Clicking inside the textbox will clear the default text. If the user enters nothing clicking another textbox or control will cause the default text to be added back. Once the command button is clicked the code will return blank if the default text remains.
Yes it is possible :)
I have created a sample for you. You can download it from here.
http://wikisend.com/download/143478/Sample.xlsm
The trick is to create 2 similar TextBoxes and hide the 'original' one behind the dummy TextBox ("Which has the default text")
When you start typing in the dummy, the text will actually be typed in the textbox which is hidden.
And when you are pulling values, simply pull the values from the 2nd text box so the default data is not considered :)
Hope this helps.
Code Used
Private Sub UserForm_Initialize()
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1.Text)
End Sub
Private Sub CommandButton1_Click()
MsgBox TextBox2.Text
End Sub
Private Sub TextBox1_Change()
TextBox1.Visible = False
With TextBox2
.Text = Replace(TextBox1.Text, "Please enter your name", "")
.Visible = True
.SetFocus
.SelStart = Len(TextBox2.Text)
End With
End Sub