How to make the process run while the button is pressed? - ms-access

I use:
  - Win 7x64;
  - Access - 2016;
I try to solve my problem with the following code.
Form1
Option Compare Database
Option Explicit
Public statusBool As Boolean
Public numProc As Integer
' `Button pressed`.
Private Sub btnStart_Click()
numProc = 0
statusBool = True
Call Process(statusBool, numProc)
End Sub
' Process
Public Sub Process(statusBool As Boolean, numProc As Integer)
If statusBool = True Then
Me.txtProcessFrm = "ProcessNum - " & numProc + 1
Call SleepFor(1000) '1 seconds delay
Call Process(statusBool, numProc)
End If
End Sub
'
Private Sub btnStart_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
statusBool = False
numProc = 0
Call Process(statusBool, numProc)
End Sub
Public Sub SleepFor(ByVal MilliSeconds As Long)
Sleep MilliSeconds
End Sub
Module1
Option Compare Database
Option Explicit
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Question
Will my solution be correct for this task or are there simpler ways to solve this problem?
Update_1
The code does not start.
I get an error Sub or Function not defined.
Update_2
Module Module1.
Replaced Private to Public.
It was
 Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
It became
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Problem.
When I click the button btnStart_Click the file hangs
Update_3
Modified Process (statusBool As Boolean, numProc As Integer)
It became.
' Process
Public Sub Process(statusBool As Boolean, numProc As Integer)
If statusBool = True Then
Do
Sleep 1000
DoEvents
Loop Until Me.txtProcessFrm = "ProcessNum - " & numProc + 1
Call Process(statusBool, numProc)
End If
End Sub
Problem.
It seems the pause works, but the logic itself does not work.
In other words, the text field is not filled with text.
If you release the button, the cycle continues to work.

The chain of event for clicking a button follows as this.
MouseDown → MouseUp → Click → DblClick → Click
In your code, the loop will never stop because your statusBool will always be true causing infinite loop and that's probably why it's hanging even if you release the mosue.
you can however try this mouse down => mouse up:
Private Sub btnStart_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
statusBool = True
Call Process(0)
End Sub
Private Sub btnStart_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
statusBool = False
End Sub
Public Sub Process(numProc As Integer)
If statusBool Then
numProc = numProc + 1
Me.txtProcessFrm = "ProcessNum - " & numProc
Sleep 1000
DoEvents
Call Process(numProc)
End If
End Sub
more here:
https://learn.microsoft.com/en-us/office/vba/api/access.commandbutton.click

Related

Ms Access fade in form with Windows API

I've managed to make my form fade out correctly, but for some reason my fade in isn't working correctly. The form "hitches" during the load. It loads normally, and then fades in. Rather than just fading in the begin with.
It's done by creating a module, and then code within the form.
The form code:
Option Compare Database
Dim gintC
Private Sub Form_Load()
Me.TimerInterval = 2
FadeForm Me, Fadezero, 1, 5
End Sub
Private Sub Form_Timer()
If IsEmpty(gintC) Then
FadeForm Me, Fadein, 1, 15
End If
gintC = 1
Me.TimerInterval = 0
End Sub
Private Sub Form_Close()
FadeForm Me, Fadeout, 1, 255
End Sub
The module:
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function SetLayeredWindowAttributes Lib "user32" _
(ByVal hWnd As Long, ByVal crey As Byte, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Const GWL_EXSTYLE = (-20)
Public Const WS_EX_LAYERED = &H80000
Public Const WS_EX_TRANSPARENT = &H20&
Public Const LWA_ALPHA = &H2&
'Enum for determining the direction of the fade.
Public Enum FadeDirection
Fadein = -1
Fadeout = 0
Fadezero = 1
SetOpacity = 1
End Enum
Public Sub FadeForm(frm As Form, Optional Direction As FadeDirection = FadeDirection.Fadein, _
Optional iDelay As Integer = 0, Optional StartOpacity As Long = 5)
Dim lOriginalStyle As Long
Dim iCtr As Integer
'You can only set a form's opacity if it's Popup property = True.
If (frm.PopUp = True) Then
'Get the form window’s handle, and remember its original style.
lOriginalStyle = GetWindowLong(frm.hWnd, GWL_EXSTYLE)
SetWindowLong frm.hWnd, GWL_EXSTYLE, lOriginalStyle Or WS_EX_LAYERED
'If the form’s original style = 0, it hasn’t been faded since it was opened.
'To get fading to work, we have to set its style to something other than zero.
If (lOriginalStyle = 0) And (Direction <> FadeDirection.SetOpacity) Then
'Recursively call this same procedure to set the value.
FadeForm frm, SetOpacity, , StartOpacity
End If
'Depending on the direction of the fade...
Select Case Direction
Case FadeDirection.Fadezero
iCtr = StartOpacity
SetLayeredWindowAttributes frm.hWnd, 0, CByte(iCtr), LWA_ALPHA
Case FadeDirection.Fadein
'Just in case.
If StartOpacity < 1 Then StartOpacity = 1
'Fade the form in by varying its opacity
'from the value supplied in 'StartOpacity'
'to 255 (completely opaque).
For iCtr = StartOpacity To 255 Step 1
SetLayeredWindowAttributes frm.hWnd, 0, CByte(iCtr), LWA_ALPHA
'Process any outstanding events.
DoEvents
'Wait a while, so the user can see the effect.
Sleep iDelay
Next
Case FadeDirection.Fadeout
'Just in case.
If StartOpacity < 6 Then StartOpacity = 255
'Fade the form out by varying its opacity
'from 255 to 1 (almost transparent).
For iCtr = StartOpacity To 1 Step -1
SetLayeredWindowAttributes frm.hWnd, 0, CByte(iCtr), LWA_ALPHA
'Process any outstanding events.
DoEvents
'Wait a while, so the user can see the effect.
Sleep iDelay
Next
Case Else 'FadeDirection.SetOpacity.
'Just in case.
Select Case StartOpacity
Case Is < 1: StartOpacity = 1
Case Is > 255: StartOpacity = 255
End Select
'Set the form's opacity to a specific value.
SetLayeredWindowAttributes frm.hWnd, 0, CByte(StartOpacity), LWA_ALPHA
'Process any outstanding events.
DoEvents
'Wait a while, so the user can see the effect.
Sleep iDelay
End Select
Else
'The form’s Popup property MUST = True
DoCmd.Beep
MsgBox "The form's Popup property must be set to True.", vbOKOnly & vbInformation, "Cannot fade form"
End If
End Sub
Any Advice? Any idea why the closing fade works, but the loading fade doesn't?
Thanks.
You should
move code from Load to Open event
call OpenForm with WindowMode = acHidden
set Me.Visible = True in Timer

VBA editor events

I have some controls in MS Access form that change the system language to Turkish, Arabic and English and I want to change the system language to English when I go to VBA to write some code.
I have a code that change system language and want to know
How to run this code automatically when I activate VBA editor?
If you put the following code on start of your application, it would run automatically Test2, whenever you press Alt+F11.
Private Sub Workbook_Open()
Application.OnKey "%{F11}", "Test2"
End Sub
Public Sub Test2()
Debug.Print "tested"
End Sub
I am not sure whether this is exactly what you want, but it is a work around to achieve it.
Edit:
Actually, here you may find plenty of useful stuff:
http://www.mrexcel.com/forum/excel-questions/468063-determine-language-user.html
E.g. With the Sub ShowLanguages you may built a function telling you which language are you using and if it is not English, you may switch to it, the way you do it in your answer. I would probably built something similar later.
Private Const LOCALE_ILANGUAGE As Long = &H1
Private Const LOCALE_SCOUNTRY As Long = &H6
Private Declare Function GetKeyboardLayout Lib "user32" _
(ByVal dwLayout As Long) As Long
Private Declare Function GetLocaleInfo Lib "kernel32" _
Alias "GetLocaleInfoA" _
(ByVal Locale As Long, _
ByVal LCType As Long, _
ByVal lpLCData As String, _
ByVal cchData As Long) As Long
Public Sub ShowLangauges()
Dim hKeyboardID As Long
Dim LCID As Long
hKeyboardID = GetKeyboardLayout(0&)
If hKeyboardID > 0 Then
LCID = LoWord(hKeyboardID)
Debug.Print GetUserLocaleInfo(LCID, LOCALE_ILANGUAGE)
Debug.Print GetUserLocaleInfo(LCID, LOCALE_SCOUNTRY)
End If
End Sub
Private Function LoWord(wParam As Long) As Integer
If wParam And &H8000& Then
LoWord = &H8000& Or (wParam And &H7FFF&)
Else
LoWord = wParam And &HFFFF&
End If
End Function
Public Function GetUserLocaleInfo(ByVal dwLocaleID As Long, _
ByVal dwLCType As Long) As String
Dim sReturn As String
Dim nSize As Long
nSize = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, Len(sReturn))
If nSize > 0 Then
sReturn = Space$(nSize)
nSize = GetLocaleInfo(dwLocaleID, dwLCType, sReturn, Len(sReturn))
If nSize > 0 Then
GetUserLocaleInfo = Left$(sReturn, nSize - 1)
End If
End If
End Function
I use Timer to check if VBA editor window is the active window every 0.5 Sec and if true I run my function that change the language to English and stop Timer:
Private Sub Form_Timer()
Dim st As String
On Error Resume Next
st = VBE.ActiveWindow.Caption
If Err = 0 Then
ChLng 1033
Me.TimerInterval = 0
End If
On Error GoTo 0
End Sub
And I run Timer again when any control on my form change the language to non English language:
Private Sub cmbAR_GotFocus()
ChLng 1025
Me.TimerInterval = 500
End Sub
Private Sub cmbTR_GotFocus()
ChLng 1055
Me.TimerInterval = 500
End Sub
In Form design I manually add all needed events including Form Load event that run the Timer:
Private Sub Form_Load()
Me.TimerInterval = 500
End Sub
NOTE: ChLng xxxx is the function that change the language:
(Find your desired language at BCP 47 Code)
Private Declare Function ActivateKeyboardLayout Lib _
"user32.dll" (ByVal myLanguage As Long, Flag As Boolean) As Long
'define your desired keyboardlanguage
Sub ChLng(lng As Long)
ActivateKeyboardLayout lng, 0
End Sub

How can I bring my current Access DB to foreground via VBA?

I'm trying to get my access db to come to the foreground based on the couple of lines, below. I'm not sure why it isn't working though, or if there are better methods to do this.
From what I've read, this should work:
Access.Visible = False
Access.Visible = True
But doesn't actually bring the database to the front.
Edit for more info:
Private Sub Form_Open(Cancel As Integer)
getStrUserName = Environ("username")
dbName = "myDB.accdb" ' database name
versionChckDB = "versionCheckDB.accdb" ' version check db name
strServer = "C:\My\Path\to\Server" ' server location string
strDesktop = "C:\My\Path\to\Local" ' desktop location string
strVersionCheck = "C:\My\Path\to\Version" ' version check location
Static acc As Access.Application
Dim db As DAO.Database
Dim strDbName As String
If FileLocked(strDesktop & "\" & versionChckDB) Then
Dim objAccess As Access.Application
Set objAccess = GetObject(strDesktop & "\" & versionChckDB)
objAccess.Application.Quit acQuitSaveAll
Set objAccess = Nothing
DoCmd.OpenForm "frmMainMenu"
DoCmd.RunCommand acCmdAppMaximize
Access.Visible = False
Access.Visible = True
GoTo exitSub
Else
strDbName = strDesktop & "\" & versionChckDB
Set acc = New Access.Application
acc.Visible = True
Set db = acc.DBEngine.OpenDatabase(strDbName, False, False)
acc.OpenCurrentDatabase strDbName
End If
'db.Close
exitSub:
Call SetForegroundWindow(Application.hWndAccessApp) ' bringing access DB to foreground
End Sub
Usually one uses an API function for that.
From http://www.access-programmers.co.uk/forums/showthread.php?t=132129 :
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
and then
Call SetForegroundWindow(Application.hWndAccessApp)
Edit
If you want to get the newly opened Access application window to the front, you need its hWnd:
Call SetForegroundWindow(acc.hWndAccessApp)
Edit 2
This works for me. Notepad is briefly in the foreground, then the Access window.
Module:
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Sub TestAccessToForeground()
Sleep 300
Shell "notepad.exe", vbNormalFocus
Sleep 300
Call SetForegroundWindow(Application.hWndAccessApp)
End Sub
Form:
Private Sub Form_Open(Cancel As Integer)
Call TestAccessToForeground
End Sub

Forms GotFocus event does not seem to fire

I'm trying to call an event when the user returns focus to the Access application when a specific form is open. The following event doesn't seem to fire up at all.
Private Sub Form_GotFocus()
Call crtListDirectory
End Sub
Does any body have any ideas as to how I could trigger this event to happen, and when/how does the Form_GotFocus event actually get triggered.
thanks in advance for any help
Noel
Access help:
A form can get the focus only if all
visible controls on a form are
disabled, or there are no controls on
the form.
You might like to try Activate.
EDIT re Comments
The only way I can see of doing what you seem to want is with APIs, which is somewhat messy. To demonstrate this you will need a form with two controls Text0 and Text2 (these are the default names). Set the Timer Interval to something suitable, say 2000, and the Timer Event to:
Private Sub Form_Timer()
Dim lngWin As Long
Dim s As String
'This is just a counter to show that the code is running
Me.Text2 = Nz(Me.Text2, 0) + 1
'API
lngWin = GetActiveWindow()
s = GetWinName(lngWin)
If s = "Microsoft Access" Then
If Me.Text0 = "Lost Focus" Then
Me.Text0 = "Focus returned"
End If
Else
Me.Text0 = "Lost Focus"
End If
End Sub
You will now need a module for:
Option Compare Database
Declare Function GetActiveWindow Lib "user32" () As Integer
Declare Function GetWindowText Lib "user32.dll" Alias _
"GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As _
String, ByVal cch As Long) As Long
Declare Function GetWindowTextLength Lib "user32" Alias _
"GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Function GetWinName(hw As Long)
Dim lngText As Long ' receives length of text of title bar
Dim strWinName As String ' receives the text of the title bar
Dim lngWinText As Long ' receives the length of the returned string
lngText = GetWindowTextLength(hw)
strWinName = Space(lngText + 1)
lngWinText = GetWindowText(hw, strWinName, lngText + 1)
strWinName = Left(strWinName, lngWinText)
GetWinName = strWinName
End Function
This is all very, very rough, but it gives you something to mess about with.

MS Access : Form Timer control...can I use it for setting a time gap in a routine?

Just wondering, if I have some graphical events/animation happening on a splash screen, can I use the timer event some how to simply break up the routine for a small amount of time.
basically like:
-some action events
DoEvents
'some timer interval
-more action code
Use the Windows API to include a pause between code sections. See the sSleep() procedure at this page: Make code go to Sleep
Const clngMilliSeconds As Long = 10000 '(10 seconds) '
'some action events '
DoEvents
'some timer interval '
Call sSleep(clngMilliSeconds)
'more action code '
You could combine a form level variable Dim iStep as integer which will automatically be Static, and in your On Timer proc, something like:
Select Case iStep
Case 1
'do something'
Case 2
'do something else'
Case 3
'etc...'
End Select
iStep = iStep + 1
In this case, I think it would be better to create your own timer by storing Now() to a variable at the start, and checking for the intervals you want with DateDiff, or even straight subtraction, given that dates are stored as numbers.
Form Fade
Dug out of a very old library and not tested recently.
Form:
Option Compare Database
Dim gintC
Private Sub Form_Load()
Me.TimerInterval = 2
FadeForm Me, Fadezero, 1, 5
End Sub
Private Sub Form_Timer()
If IsEmpty(gintC) Then
FadeForm Me, Fadein, 1, 15
End If
gintC = 1
Me.TimerInterval = 0
End Sub
Module:
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function SetLayeredWindowAttributes Lib "user32" _
(ByVal hWnd As Long, ByVal crey As Byte, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Const GWL_EXSTYLE = (-20)
Public Const WS_EX_LAYERED = &H80000
Public Const WS_EX_TRANSPARENT = &H20&
Public Const LWA_ALPHA = &H2&
'Enum for determining the direction of the fade.
Public Enum FadeDirection
Fadein = -1
Fadeout = 0
Fadezero = 1
SetOpacity = 1
End Enum
Public Sub FadeForm(frm As Form, Optional Direction As FadeDirection = FadeDirection.Fadein, _
Optional iDelay As Integer = 0, Optional StartOpacity As Long = 5)
Dim lOriginalStyle As Long
Dim iCtr As Integer
'You can only set a form's opacity if it's Popup property = True.
If (frm.PopUp = True) Then
'Get the form window’s handle, and remember its original style.
lOriginalStyle = GetWindowLong(frm.hWnd, GWL_EXSTYLE)
SetWindowLong frm.hWnd, GWL_EXSTYLE, lOriginalStyle Or WS_EX_LAYERED
'If the form’s original style = 0, it hasn’t been faded since it was opened.
'To get fading to work, we have to set its style to something other than zero.
If (lOriginalStyle = 0) And (Direction <> FadeDirection.SetOpacity) Then
'Recursively call this same procedure to set the value.
FadeForm frm, SetOpacity, , StartOpacity
End If
'Depending on the direction of the fade...
Select Case Direction
Case FadeDirection.Fadezero
iCtr = StartOpacity
SetLayeredWindowAttributes frm.hWnd, 0, CByte(iCtr), LWA_ALPHA
Case FadeDirection.Fadein
'Just in case.
If StartOpacity < 1 Then StartOpacity = 1
'Fade the form in by varying its opacity
'from the value supplied in 'StartOpacity'
'to 255 (completely opaque).
For iCtr = StartOpacity To 255 Step 1
SetLayeredWindowAttributes frm.hWnd, 0, CByte(iCtr), LWA_ALPHA
'Process any outstanding events.
DoEvents
'Wait a while, so the user can see the effect.
Sleep iDelay
Next
Case FadeDirection.Fadeout
'Just in case.
If StartOpacity < 6 Then StartOpacity = 255
'Fade the form out by varying its opacity
'from 255 to 1 (almost transparent).
For iCtr = StartOpacity To 1 Step -1
SetLayeredWindowAttributes frm.hWnd, 0, CByte(iCtr), LWA_ALPHA
'Process any outstanding events.
DoEvents
'Wait a while, so the user can see the effect.
Sleep iDelay
Next
Case Else 'FadeDirection.SetOpacity.
'Just in case.
Select Case StartOpacity
Case Is < 1: StartOpacity = 1
Case Is > 255: StartOpacity = 255
End Select
'Set the form's opacity to a specific value.
SetLayeredWindowAttributes frm.hWnd, 0, CByte(StartOpacity), LWA_ALPHA
'Process any outstanding events.
DoEvents
'Wait a while, so the user can see the effect.
Sleep iDelay
End Select
Else
'The form’s Popup property MUST = True
DoCmd.Beep
MsgBox "The form's Popup property must be set to True.", vbOKOnly & vbInformation, "Cannot fade form"
End If
End Sub