I'm using Access 2016 in Win 10, everything updated and current. I have a form with a standard Access TextBox with a vertical scrollbar. All is fine unless I scroll down then click off the field to read info from another source or whatever because the scrolled text rolls right back to the top and I have to scroll back down to where I was before I can resume work. It wastes time and derails my train of thought.
I see no property or method to lock the 'caret' or otherwise disable this annoying behavior. I have also researched everywhere I can think of and no one seems to know what to do about it.
I've even built my own scroll buttons which worked great except it got complicated trying to keep track of the text position if I added or deleted text. So, if someone has a good custom scrollbar in VBA/VB6 I'd love to see it, please.
Thanks for your time and advice. I appreciate it.
Kent in KC.
Set and restore the selected position:
Option Compare Database
Option Explicit
Private LastPosition As Long
Private Sub YourTextbox_LostFocus()
LastPosition = Me!YourTextbox.SelStart
End Sub
Private Sub YourTextbox_GotFocus()
Me!YourTextbox.SelStart = LastPosition
Me!YourTextbox.SelLength = 0
End Sub
Private Sub Form_Current()
' Reset last position.
LastPosition = 0
End Sub
It will scroll the textbox to make the line when left to the top line visible.
In Access 2010, I have a continuous form, and I'd like to change certain properties of a 'cell', like border colour, based on values in another cell. I haven't found a way to do this in VBA, because it's a continuous form and changing the properties directly in VBA changes it for all records, not just the one I'm on. I assume I have to use some form of conditional formatting, but the conditional formatting GUI only allows me to set background colour, basic text formatting, and the Enabled property.
How can I set other properties on a control on a continuous form, for specific records only?
Feeding back how I got around this problem in the end. txtFixMax is the control I wanted to give a funky border to (dependent on a value in field [ChangedToday]). It already has conditional formatting to change the background colour.
I created a second control, txtFixMaxOverlay, made it into a small square and placed it on top of the control txtFixMax. I set the properties of txtFixMaxOverlay to remove borders, and gave it the same conditional formatting as txtFixMax, so that it was invisible to the eye (but the Visible property = true). Then I gave it additional condition, the first one on the list, based on [ChangedToday], to change its background colour.
The effect isn't a border (although with a lot of tedious positioning of 4 controls I could have done this to give a border effect), but it does give me an extra element to visually change. The effect is:
You can't. Use background or text color.
See also https://msdn.microsoft.com/en-us/library/office/ff821010.aspx - there is only BackColor and ForeColor.
Yes, you can... just not with the built-in conditional formatting functionality. Use the Paint event of the Form's Detail section. There are still various limitations, but at the least you can set more properties than just the background and foreground colors.
Example:
Private Sub Detail_Paint()
If Me.IndicatorColumn.Value = "Critical" Then
Detail.BackColor = RGB(255,0,0)
Detail.AlternateBackColor = Detail.BackColor
Me.AnotherColumn.BorderStyle = 7 'Dash Dot Dot
Me.AnotherColumn.BorderColor = vbMagenta
Else
Detail.BackColor = vbWhite
Detail.AlternateBackColor = RGB(150, 150, 150)
Me.AnotherColumn.BorderStyle = 0 'Transparent
Me.AnotherColumn.BorderColor = vbWhite
End If
End Sub
See TextBox.BorderStyle.
I have a simple button in MS Access form that I require to have the background color changed and remain once the button is pressed and the mouse is no longer hovering. So, Blue static, Green on Hover, Red once pressed and remains red. I have the hover and press controls set and all work fine. But I get a mismatch error when trying to change the backcolor during the procedure.
Private Sub OpenBtn_Click()
OpenBtn.BackColor = "#ED1C24"
DoCmd.OpenForm "Customer"
End Sub
I Know I'm not using the write ' or " or & somewhere... any help is greatly appreciated.
Color is not string, you need to provide Long for BackColor. Use RGB function:
OpenBtn.BackColor = RGB(255, 0, 0) 'red color
In VBA programming, is it possible to hide the ToolTipText for a Slider Bar?
The picture below shows a Slider Bar on a form in a Microsoft Access database. I would like to hide the ToolTipText in the red circle.
The reason I want to do this is because the Slider Bar cannot show decimal values (example: 0,1), so I want to display the values in a box next to the slider after they are scaled to decimal values. I know how to do this, but not how to hide the ToolTipText for the Slider that shows only integer values.
There is no easy way to remove that indicator as it's not exposed through the control itself.
However, there are a couple of solutions:
Subclassing the control and intercepting Windows messages
Not for the faint of heart, complex and overkill, but you theoretically could intercept windows messages and drop those that correspond to the tooltip.
This is not easy in VBA at all, and I wouldn't even try it.
If you feel like delving into this, have a look at an example in KB278379
Just display something else.
More interesting is the ability to change the displayed text to something else:
To change the text, handle the Scroll event and update the slider's Text property:
Private Sub MySlider_Scroll()
MySlider.Text = "Awesomeness: " & (MySlider.Value * 7.89)
End Sub
The event is not visible from the control's properties themselves, but if you open the IDE and select the Slider from the list of controls, you will be able to create the code for handling the Scroll event:
I'm trying to force an MS-Access form to take a certain position relative to the right edge of the main window (actually I want to center it, but I can see also wanting to dock it to one side or another). I can reposition the form this with Me.Move, e.g.,
Me.Move newWindowLeft, newWindowTop, newWidth, newHeight
However, how can I find out how wide the parent window is?
You can use a windows API:
(UPDATED to return twips)
Type Rect
x1 As Long
y1 As Long
x2 As Long
y2 As Long
End Type
Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As Rect) As Long
Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Const LOGPIXELSX = 88
Const LOGPIXELSY = 90
Const DIRECTION_VERTICAL = 1
Const DIRECTION_HORIZONTAL = 0
Public Function GetMainWindowSize()
Dim MDIRect As Rect
Dim lWidthPixels As Long
Dim lWidthTwips As Long
' Get the screen coordinates and window size of the MDIClient area'
GetClientRect Application.hWndAccessApp, MDIRect
lWidthPixels = MDIRect.x2 - MDIRect.x1
lWidthTwips = PixelsToTwips(lWidthPixels, DIRECTION_HORIZONTAL)
MsgBox "Width (Pixels) = " & lWidthPixels & " Width (Twips) = " & lWidthTwips
End Function
Function PixelsToTwips(lPixels As Long, lDirection As Long) As Long
Dim lDeviceHandle As Long
Dim lPixelsPerInch As Long
lDeviceHandle = GetDC(0)
If lDirection = DIRECTION_HORIZONTAL Then
lPixelsPerInch = GetDeviceCaps(lDeviceHandle, LOGPIXELSX)
Else
lPixelsPerInch = GetDeviceCaps(lDeviceHandle, LOGPIXELSY)
End If
lDeviceHandle = ReleaseDC(0, lDeviceHandle)
PixelsToTwips = lPixels * 1440 / lPixelsPerInch
End Function
Not sure what version of Access you are using, but in Access 2003, there does not appear to be a way to directly get this information.
Here's a hack:
DoCmd.Maximize
w = Forms("yourForm").WindowWidth
h = Forms("yourForm").WindowHeight
This will maximize the current window, let's assume that it's your form. You can then measure the form to get the size of the parent window's display area, then un-maximize, and move the form based on the size of the parent window that you now know.
If there is a way to turn off ScreenUpdating in Access, you can do this before the maximize and measure code, then turn it back on, and it won't take any noticeable amount of time as far as the user is concerned.
EDIT: Even without hiding the maximize command from the user, the whole maximize and move operation happens more quickly than the user can see.
It's an ugly hack, but it does work.
I realise this is a very old question, but I want to share some code I've created to handle the desired end result of the original purpose of this question - repositioning windows so they are aligned with another existing entity.
This module exposes 3 functions:
TwipsToPixels ( _
Twips As Long, _
Optional Dimension As Dimension = DIMENSION_X _
) As Long
PixelsToTwips ( _
Pixels As Long, _
Optional Dimension As Dimension = DIMENSION_X _
) As Long
These simply convert between one unit of measurement and the other. Both accept a long integer argument input and a value from the Dimension enum, either X or Y, which can be used to specify whether the conversion should be done according the to horizontal or vertical display settings. It's worth noting that 99.99999% of the time, the value will be the same in both dimensions, so you can usually omit the second argument. Both return a long integer.
The module uses pixels for everything internally, so these conversion functions are only provided as a convenience for applications that prefer to work in twips.
PositionWindow ( _
hWnd As Long, _
Mode As PositionMode, _
Optional OffsetX As Long = 0, _
Optional OffsetY As Long = 0 _
)
hWnd is the handle of the window to be positioned (for example, to position a form window this can be obtained using objForm.hWnd).
Mode is a bit mask constructed from the options in the PositionMode enum (see below).
OffsetX is the number of pixels to adjust the position by in the horizontal dimension, after Mode has been evaluated.
OffsetY is the number of pixels to adjust the position by in the vertical dimension, after Mode has been evaluated.
Modes
Every positioning call requires an X component and a Y component. These components consist of two sub-components, a base and a position.
The base is an entity to use as a reference for calculating the new position, and can be one of DISPLAY (the active physical display on the machine), WINDOW (the main Access window) or CURSOR (the mouse pointer). For convenience, these are combined in the values from the PositionMode enum.
The active display is determined using the center pixel of the main Access window. If this falls outside the bounds of the area show on the physical displays attached to the machine, the value is adjusted to compensate, and the display with the largest visible part of the application on it will be used.
The position of the X component can be one of LEFT, RIGHT or X_CENTER. The Y component has TOP, BOTTOM and Y_CENTER.
Using LEFT causes the left-most pixel of the target window to be aligned with the left-most pixel of the base entity, and this pattern follows for RIGHT, TOP and BOTTOM. The CENTER positions cause the center-line of the target window to be aligned with the center-line of the base entity.
The values from the PositionMode enum are combined with the bitwise Or operator to achieve the desired expression.
Handling display overflow
Sometimes when WINDOW or CURSOR are used as a base for one of the components, the target window may be positioned so that some or all of it is not on a visible display. To avoid this, you can use the PREVENT_OVERFLOW_X and PREVENT_OVERFLOW_Y flags. These can simply be included in the bit mask passed to the Mode argument using the bitwise Or operator.
These flags cause the position to be adjusted, if necessary, to ensure that the entire of the target window is within the edges of the active monitor.
For convenience, a PREVENT_OVERFLOW item is also included in the enum, this is the same as specifying both PREVENT_OVERFLOW_X and PREVENT_OVERFLOW_Y.
Oveflow prevention is not applied to DISPLAY-based positions.
Offsets
The OffsetX and OffsetY arguments can be used to adjust the position of the window after it has been aligned in the manner specified by Mode. Both can be a positive or negative number, indicating a number of pixels to alter the position by in the relevant dimension.
Display overflow prevention will override offsets - the offsets will still be applied, but if the resulting position results in a portion or all of the target window being outside the active display, the position will be adjusted to bring it back inside the boundaries.
Limitations
The handling code for multiple displays makes 2 assumptions:
That the virtual display area (the combination of all displays treated as a single display) is uniform - so it won't play nice with L shaped setups or other such ridiculous configurations.
That all active displays use the same resolution.
In my experience, in the real world, these are fairly safe assumptions.
No support for simultaneously re-positioning and re-sizing is provided (as it is with objForm.Move). You will need to treat these as separate tasks.
Examples
' Get the window handle for frm_MyForm
Dim hWnd As Long
hWnd = Forms("frm_MyForm").hWnd
' Align the form to the top left corner of the active display
PositionWindow hWnd, DISPLAY_LEFT Or DISPLAY_TOP
' Align the form to the center of the Access main window
PositionWindow hWnd, WINDOW_X_CENTER Or WINDOW_Y_CENTER
' Align the form to the bottom right of the mouse pointer position, prevent the
' window from disappearing off the screen
' This effectively sets the top left corner of the window to the pointer location
PositionWindow hWnd, CURSOR_RIGHT Or CURSOR_BOTTOM Or PREVENT_OVERFLOW
' Horizontally center the form on the display, vertically center on the mouse
PositionWindow hWnd, DISPLAY_X_CENTER Or CURSOR_Y_CENTER
' Center the window on the mouse pointer then move it 200px right and 30px up
PositionWindow hWnd, CURSOR_X_CENTER Or CURSOR_Y_CENTER, 200, -30
Here's the actual code I used
Application.Echo False 'turn off screen updates
DoCmd.Maximize
w = Me.WindowWidth
h = Me.WindowHeight
DoCmd.Restore 'restore the window to it's old size
Application.Echo True 'turn on screen updates
DoCmd.MoveSize w / 2 - myWidth / 2, _
h / 2 - myHeigth / 2, _
myWidth, _
myHeigth
This may be of interest: http://www.mvps.org/access/downloads/clFormWindow.bas
It says it:
'' Moves and resizes a window in the coordinate system *
'' of its parent window. *
'' N.B.: This class was developed for use on Access forms *
'' and has not been tested for use with other window *
'' types. *