Vertical scroll bars in a text box. (1 Viewer)

sja13

Professional Idiot
Local time
Today, 04:45
Joined
May 3, 2017
Messages
63
Back in 2004 the User anb001 had a problem with forcing a text box to show a vertical scroll bar.

The argument in 2004 seemed to focus on "Why" rather than "How".

I have the same problem, and as it happens the same reasons as anb001.
I want the User to be aware at a glance that there is more text than is currently visible in a "Notes" Textbox.

Other than a rather heated discussion about WHY anb001 wanted this facility, there was very little in the way of help.

Such options as were offered seemed to boil down to "Set the textbox to have no scrollbars in the Properties, then at run time count the characters to be displayed, and if you think there's too many to fit in the box, turn the vertical scrollbar on".

This is not a million miles away from "just set the textbox's scroll property to 'None', and at Form Load, set it to 'Vertical'".

I've tried this (and other variants), and they have absolutely no effect until the textbox has focus.

I've even tried switching focus to the textbox on Form_Current, which shows the scrollbar (even when the textbox is empty), but the bar just vanishes when any other control takes focus (and the text is highlighted, which looks ugly).

In the intervening 13 years, has anyone found a solution which causes a textbox to retain scrollbars regardless of which control has focus?

Any help would be welcome....
 

CJ_London

Super Moderator
Staff member
Local time
Today, 04:45
Joined
Feb 19, 2013
Messages
16,612
In the intervening 13 years, has anyone found a solution which causes a textbox to retain scrollbars regardless of which control has focus?
Access provides preconfigured forms, controls etc which users can reconfigure within limits. If you use something like .net then controls come are at a much more basic level and you have to do all the configuring yourself. Benefit for access is rapid development at a cost of say 5% of not being able to do something.

So the answer is no, you need to find another way.

Perhaps you should look at Stephen Lebans website. http://www.lebans.com/

In particular his grow/shrink solution for forms. If you don't want to grow/shrink, then you could adapt it to show/hide a label with a down arrow or text saying 'there is more than you can see' placed next to the control in question - or used to apply conditional formatting to the control itself.

Another one to investigate is his Hscroller example - you can use this to get to the scrollbar window (every form, every control, every feature - scrollbar, navigation bar etc is a window) and perhaps you can force it to be visible at all times.
 

static

Registered User.
Local time
Today, 04:45
Joined
Nov 2, 2015
Messages
823
Won't work in continuous forms.

Code:
'If field1 > 10 chars display first 10 + ellipsis
'if field1 has focus display full text with scroll

Private Sub field1_Enter()
    If field1.ControlSource = "" Then field1.ControlSource = "field1"
End Sub

Private Sub field1_Exit(Cancel As Integer)
    Form_Current
End Sub

Private Sub Form_Current()
    If Len(field1) > 10 Then
        field1.ControlSource = ""
        field1 = Left(Recordset!field1, 10) & "..."
    Else
        field1.ControlSource = "field1"
    End If
End Sub

Private Sub Form_Open(Cancel As Integer)
    field1.ScrollBars = 2
End Sub
 

isladogs

MVP / VIP
Local time
Today, 04:45
Joined
Jan 14, 2017
Messages
18,221
Static's idea is simple & effective - it works

It does work in continuous forms (but see note below)but of course not in datasheet view

I think its slightly more obvious if you modify the Form_Current code on these lines:

Code:
Private Sub Form_Current()
    If Len(field1) > 10 Then
        field1.ControlSource = ""
        field1 = Left(Recordset!field1, 10) & ". . ." & _
           vbNewLine & vbNewLine & "Click to view the full record"
    Else
        field1.ControlSource = "field1"
    End If
End Sub

However, even better would be to have the extra line in a different colour e.g. RED as in the examples below



I did this with a hidden label (lbl1) with RED text over the lower part of the control

Code:
'If field1 > 20 chars display first 20 + ellipsis + show label with RED text
'if field1 has focus, display full text with scroll + hide label with RED text

Private Sub field1_Enter()
    If Me.field1.ControlSource = "" Then 
	Me.field1.ControlSource = "field1"
	Me.lbl1.visible=False	
End Sub

Private Sub field1_Exit(Cancel As Integer)
    Form_Current
End Sub

Private Sub Form_Current()
    If Len(field1) > 20 Then
        Me.field1.ControlSource = ""
        Me.field1 = Left(Recordset!field1, 20) & ". . ."
        Me.Lbl1.visible = True
    Else
        Me.field1.ControlSource = "field1"
        Me.lbl1.visible=False	
    End If
End Sub

Private Sub Form_Open(Cancel As Integer)
    Me.field1.ScrollBars = 2
End Sub

NOTE:
Changes to one record in a continuous form affect all records.
So if the red text is clicked it disappears for all records and all records shows the full field text

Of course, the question remains - is it really worth the effort of doing either of these solutions....?
 

Attachments

  • ScrollBarTextbox.PNG
    ScrollBarTextbox.PNG
    56.3 KB · Views: 6,921
Last edited:

sja13

Professional Idiot
Local time
Today, 04:45
Joined
May 3, 2017
Messages
63
After a fair bit of reading, at my skill level the only real option is to take up the suggestions from Static and ridders of having a Label saying something like
“Click for more ==>” next to the box, or possibly some code to change the colour and width of the Textbox’s border.

In either case I need to know if the textbox will “overflow”.

With thanks to all who’ve contributed various code snippets, ideas, suggested reading etc., and after lots of frustrating journeys up blind alleys, I’ve created the following code to try to create a generic solution which will identify if supplied text will fit within a given textbox.

The main routine is “funWillTextFit”.
This uses “funGetTextDims” to get the useable size of the text box.

Note:- It took ages before I discovered the significance of the “padding” properties in a text box!

However, there is still an issue with the perception of the text on screen. Often, a line of text may be visible even though technically it doesn’t completely fit height-wise.

I don’t know why this happens (my inexperience? screen rendering? formatting code deep in the bowels of Access?)

To try to deal with that, I have introduced a “Fuzzy” percentage value. If the “needed” size exceeds the available size by less than the “fuzzy” percentage, the function returns a True condition (i.e. the whole of the text is readable). In the example it’s set to 7.73, which works for me in the application I’m developing.

I’ve also included a test harness to show how the function may be invoked.
There is code in the test harness to allow you to adjust the size of the textbox, and the font of the text.
There are also MsgBoxs to identify what’s going on – remove or enhance these as you wish.

To run the test, create a new database. In it, create a Form called “frmTest”. Add a textbox control to “frmTest”, naming the control “tbxTest” .
Use “Alt+F11” (or the Visual Basic button in the Create/Macros and Code section of the ribbon) to get to the Visual Basic editor.
Paste the following code.
Hopefully the comments will explain what’s happening….

Code:
Option Compare Database
Option Explicit
Public Sub TestTextFit()
Dim booRes                      As Boolean
Dim ctlOnForm                   As Control
Dim frm                         As Form
Dim intFont                     As Integer
Dim sngH                        As Single
Dim sngW                        As Single
Dim strFont                     As String
Dim strTestTxt                  As String
'*
'** Set the details to be used.
'*
  strTestTxt = "Writing lots of text to see if the vertical scroll bar on the control actually appears, or is it just one of those things which are supposed to work but in reality don't!"
  strFont = "Calibri"
  intFont = 11
  sngH = funCmToTwip(2)
  sngW = funCmToTwip(7)
'*
'** Show the Form, so the text can be seen.
'** The form needs to be in Form view.
'** (We close the Form if it was already open.)
'*
  On Error Resume Next
  DoCmd.Close acForm, "frmTest", acSaveNo
  On Error GoTo 0
  
  DoCmd.OpenForm "frmTest", acNormal
  Set frm = Form_frmTest
'*
'** Resize the textbox.
'*
  Set ctlOnForm = frm!tbxTest
  With frm!tbxTest
    .Properties("Width") = sngW
    .Properties("Height") = sngH
    .Properties("FontName") = strFont
    .Properties("FontSize") = intFont
  End With
  
  frm!tbxTest.Value = strTestTxt
'*
'** Get the result.
'*
  booRes = funWillTextFit(ctlOnForm, _
                          strTestTxt)
'*
'** Tell User the result.
'*
  Call MsgBox(strTestTxt & vbCrLf & _
              vbCrLf & _
              booRes)
'*
'** Dismiss the Form.
'*
'  DoCmd.Close acForm, "frmTest", acSaveNo
End Sub 'TestTextFit
Public Function funWillTextFit(ctl As Control, _
                            ByVal str As String) As Boolean
Const csngFuzzy                 As Single = 7.73
Dim intLinesAvail               As Integer
Dim intLinesInteger             As Integer
Dim intLinesRequired            As Integer
Dim sngCtlHeight                As Single
Dim sngCtlWidth                 As Single
Dim sngDiff                     As Single
Dim sngLinesAvail               As Single
Dim sngLinesRequired            As Single
Dim sngPcnt                     As Single
Dim sngTextHeight               As Single
Dim sngTextWidth                As Single
'*
'** Get Control's dimensions
'** (in Twips).
'*
  sngCtlHeight = ctl.Height - (ctl.TopPadding + ctl.BottomPadding)
  sngCtlWidth = ctl.Width - (ctl.LeftPadding + ctl.RightPadding)
'*
'** Get the supplied text's dimensions
'** as it would be if placed in the
'** control using the control's
'** current dimensions and font (in Twips).
'** 1 cm = approx 567 twips.
'*
  sngTextWidth = funGetTextDims(ctl, str)
  sngTextHeight = funGetTextDims(ctl, str, True)
'*
'** Number of lines required is
'** text width / ctl width, rounded up.
'*
  
  sngLinesRequired = sngTextWidth / sngCtlWidth
  intLinesRequired = Round(sngLinesRequired + 0.5, 0)
  sngLinesAvail = sngCtlHeight / sngTextHeight
  intLinesAvail = Round(sngLinesAvail - 0.5, 0)
  MsgBox "we need to fit " & _
         Round(sngLinesRequired, 5) & _
         " (" & intLinesRequired & ")" & _
         vbCrLf & _
         "lines of text into a " & _
         Round(sngLinesAvail, 5) & _
         " (" & intLinesAvail & ")" & _
         " line box"
  sngDiff = sngLinesRequired - sngLinesAvail
  sngPcnt = (sngDiff / sngLinesAvail) * 100

'*
'** Number of lines available is
'** text height / ctl height, rounded down.
'*
  Call MsgBox("Lines Req'd: " & _
              sngLinesRequired & _
              vbCrLf & _
              "Lines Avail: " & _
              sngLinesAvail & _
              vbCrLf & _
              "Diff pcnt: " & _
              Round(sngPcnt, 2), _
               vbInformation, _
               "DIAGNOSTIC")
  If sngLinesRequired > sngLinesAvail Then
    If sngPcnt < csngFuzzy Then
      funWillTextFit = True
     Else
      funWillTextFit = False
    End If
   Else
    funWillTextFit = True
  End If
End Function 'funWillTextFit
Public Function funGetTextDims(ctl As Control, _
                         ByVal strTest As String, _
                Optional ByVal booHeight As Boolean = False) As Long
Dim lngH                        As Long
Dim lngW                        As Long
'*
'** Initialize WizHook
'*
  WizHook.Key = 51488399
'*
'** Get the width (lngW) and height
'** (lngH) of the string in twips, based
'** on the font settings of the control
'** using the largely undocumented
'** WizHook function TwipsFromFont.
'*
  With ctl
    WizHook.TwipsFromFont .FontName, _
                          .FontSize, _
                          .FontWeight, _
                          .FontItalic, _
                          .FontUnderline, _
                          0, _
                          strTest, _
                          0, _
                          lngW, _
                          lngH
  End With
  If booHeight Then
    funGetTextDims = lngH
   Else
    funGetTextDims = lngW
  End If
End Function 'funGetTextDims
Public Function funTwipToCm(sngT As Single) As Single
  funTwipToCm = sngT / 567
End Function 'funTwipToCm
Public Function funCmToTwip(sngC As Single) As Single
  funCmToTwip = sngC * 567
End Function 'funCmToTwip
 

isladogs

MVP / VIP
Local time
Today, 04:45
Joined
Jan 14, 2017
Messages
18,221
I've not tested your code but a few comments...

1. Its not really a matter of skill level.
The standard Access textbox simply does NOT allow the scroll bars to be visible unless it has the focus
This can only be overcome by:
a) doing a kludge such as that suggested by Static & myself
b) the very clever (but complex) code by Stephen Lebans
c) by using an alternative such as the ActiveX control

If you want to use a), I would suggest you set a number of characters (or lines) to be visible.
This is much easier than using a % and will avoid the issue of part of a line being visible at the bottom of the textbox.
Static used 10 characters, I used 20.
Choose your own number

Whilst I wish the functionality you want was available, it isn't.
Solutions involving wizhook, twips etc seem way over the top
Is it really worth doing this sort of kludge on every textbox with a memo/long text field throughout your database?

Suggest instead you add this to the MS Access suggestions forum on the MS website. You never know, they may like it & do it....

P.S. I'm impressed you managed to find out the wizhook key!
I only know it from the author of the V-Tools addin.
He found it out by 'brute force' testing!
 

Minty

AWF VIP
Local time
Today, 04:45
Joined
Jul 26, 2013
Messages
10,371
The other option if the data doesn't need to be edited is to bind the form to a report and allow the variable sections to grow to display all the text.

I use this for a continuous "form" to display ongoing notes on service calls, without the restriction of a specific size of textbox.
 

sja13

Professional Idiot
Local time
Today, 04:45
Joined
May 3, 2017
Messages
63
I know it's "over the top" ridders, but I've spent my professional I.T. life writing applications for seriously non-I.T. specialists.

I'm old fashioned (or is that just 'old'? - is 66 old?) - I still believe it's often worth going the extra mile to give Users the extra inch (no sniggering please!)

I use a great code library manager called MZ-Tools (no I'm not flogging it - just Google it if you're interested), so once I've got a working routine I stick it in the Library and can therefore quickly install it in a "subroutines" module which all of my Office VBA code tends to contain. So in this case, if I want to pay special attention to a textbox I can just call a Function to see if text will overflow, then decide what appropriate action to take.

OK, it took a couple of weeks to develop this code, but once it's in my MZ-Tools library I can redeploy it in a couple of seconds.

Thanks again to all who've taken the time to reply - I posted the full code in this forum to try to help others by showing another approach to a potential solution.

Oh, and by the way, the simple character count solution is a good solution but would need to be recalculated if during development you decided to change the font face or font size. And how many times have we all had the "Oh bums!" moment on realising we forgot to make an appropriate adjustment following a change?

The Wizhook solution uses the textbox's run-time font attributes to determine the space used, so if you change anything during development you don't need to recalculate the textbox's capacity.
 

isladogs

MVP / VIP
Local time
Today, 04:45
Joined
Jan 14, 2017
Messages
18,221
You sound very much like me .. once I get my teeth into a problem, I rarely let go until I've solved it to my satisfaction.

I'm old fashioned (or is that just 'old'? - is 66 old?) - I still believe it's often worth going the extra mile to give Users the extra inch (no sniggering please!)

Yes, 66 is absolutely ancient or at least it will be till May 2018 when I hit 66 in which case it will seem young again .... ;)

And at our age, that extra inch isn't always so easy to achieve!

I did look at MZ-Tools a while ago but, as its no longer free, I removed it again
However, like you, I have my own code repository where, in theory, I can find useful code quickly when I need it again.

the simple character count solution is a good solution but would need to be recalculated if during development you decided to change the font face or font size.
I just stick to the same style throughout with Calibri 11 for every form.
It used to be Tahoma until I got bored with that ....

The Wizhook solution uses the textbox's run-time font attributes to determine the space used, so if you change anything during development you don't need to recalculate the textbox's capacity.

Ah - I didn't know that
I came across Wizhook when I was developing my own database full SQL search facility.
This is used to search all database components for specified strings in table fields, query SQL, form/report/standard & class modules and if required, replace with a different string
Very useful for tidying up old databases when my naming convention left something to be desired!

Once I'd got that far, I thought I'd tackle macros although I don't use them myself. That was much trickier.
Someone on this forum thought I was reinventing the wheel (thanks Galaxiom!) and mentioned V-Tools which is free and comes with full program code.
The author (Skrol) used Wizhook to extract macro code into a readable form.
However, he couldn't find a way of then replacing the macro 'text' using Wizhook

So I investigated and eventually found a way BUT not using Wizhook (which I've never used again)

I was happy - and Skrol was interested in how I'd done it.
Does anyone else care - probably not!

P.S. How is Yorkshire these days. I lived in York for almost 10 years a long time ago....
 

static

Registered User.
Local time
Today, 04:45
Joined
Nov 2, 2015
Messages
823
Trouble with undocumented/hidden functions is that they generally aren't supported so you've no guarantee that they'll work in future versions.
I'd use the code CJ_London linked to that uses the Windows API. The fact that's it's been up so long and had a few revisions also means it should be well tested and bug free.
 

tif

Registered User.
Local time
Yesterday, 21:45
Joined
Mar 1, 2017
Messages
13
I am trying to employ the exact same solution as ridder suggested for being able to see that a form field has more text without requiring focus.



However, I keep getting an error. I have a continuous form called Members with a subform called MemberDetailsSubform which contains a Textbox called Details.



I have used your code. I keep getting a variable not defined error. Is it possible the error has something to do with referencing the subform incorrectly? I have pasted my code into yours below.


I also tried using the On Current and On Open Events in the subform instead of the parent form but still got an error.



On My Parent Form called Members I have:


Private Sub Form_Current()
If Len(Details) > 20 Then
Me.Details.ControlSource = ""
Me.Details = Left(Recordset!Details, 20) & ". . ."
Me.FullRecordLabel.Visible = True
Else
Me.Details.ControlSource = "Details"
Me.FullRecordLabel.Visible = False
End If
End Sub

Private Sub Form_Open(Cancel As Integer)
Me.Details.ScrollBars = 2
End Sub


On my Subform called MemberDetailsSubform in my TextBox called Details, I have:


Private Sub Details_Enter()
If Me.Details.ControlSource = "" Then
Me.Details.ControlSource = "Details"
Me.FullRecordLabel.Visible = False
End Sub

Private Sub Details_Exit(Cancel As Integer)
Form_Current
End Sub





Thank you for any guideance you can give. I am using MS Access 2016 btw.
 

isladogs

MVP / VIP
Local time
Today, 04:45
Joined
Jan 14, 2017
Messages
18,221
Hi tif

I just happen to be online but its over a year since I posted my solution & its not something I've used since then

It would make more sense if you post a stripped down copy of your database so somebody can look at it and hopefully help fix it.

Remove all confidential data and all items not relevant to this issue, compact & zip before uploading

It may not matter but are you using 32-bit or 64-bit Access 2016?

Also, when posting code, please use code tags (the # button on the post window) to make it easier to read & to preserve the original layout
 

tif

Registered User.
Local time
Yesterday, 21:45
Joined
Mar 1, 2017
Messages
13
Thanks for your help Ridders. Sorry for the slow reply....your email was in my spam filter.


I am trying to employ Ridders solution for a continous form with a label that goes visible/invisible based on the number of characters to show me that there is additional information in a long field text box without requiring focus. Unfortunately, I am getting an error.



Would anyone be able to help me solve this problem? I have attached a scrubbed, compacted, and compressed version of the database. It does open to a form with navigation disabled, but the shift while opening key is still enabled to get to design view.


Thanks!
 

Attachments

  • Member Log.zip
    101.6 KB · Views: 144

isladogs

MVP / VIP
Local time
Today, 04:45
Joined
Jan 14, 2017
Messages
18,221
You have a missing End If in the following event of your subfform:

Code:
Private Sub Details_Enter()
   If Me.Details.ControlSource = "" Then
        Me.Details.ControlSource = "Details"
        Me.Lbl1.Visible = False
  [COLOR="Red"][B] End If[/B][/COLOR]  <== Add this line
End Sub

Try adding that and see whether it now works as you expect.
I can't see how to load the members form and subform from the startup form so can't test it properly
 

Cronk

Registered User.
Local time
Today, 13:45
Joined
Jul 4, 2013
Messages
2,772
I'm coming to this thread late and without taking in all the posts.



I like to use a zoombox to open a window of the full text when it is likely not to fit in the available text box space.


Code:
private sub textBoxControl_Enter()
   docmd.runcommand acCmdZoombox
end sub
 

tif

Registered User.
Local time
Yesterday, 21:45
Joined
Mar 1, 2017
Messages
13
Thanks Ridders.


I made that change but I am still getting the same error. When they open the db, it opens to Dashboard form. From there they will click on Member List button, then the Member Log button for any of the Members.


If I navigate in that method, when I click on Member Log button (of any Member from the List), I am getting a No Current Record error with the debugger opening and highlighted on the third line.



Code:
Private Sub Form_Current()
   If Len(Details) > 120 Then
        Me.Details.ControlSource = ""
        Me.Details = Left(Recordset!Details, 120) & ". . ."
        Me.Lbl1.Visible = True
    Else
        Me.Details.ControlSource = "Details"
        Me.Lbl1.Visible = False
    End If
End Sub


Also, I forgot to tell you before that I am on Access 365 32 bit. (Side Note: The db worked perfectly (without this current form effort) on all of my computers until I installed it on a machine with Access 64 bit. I tried everything including defining the global variable for 64 bit, etc with no luck. I found a google article that said just uninstall the 64 bit and reinstall the 32 bit. As soon as I did that, it worked there as well.)


Thanks!
 

tif

Registered User.
Local time
Yesterday, 21:45
Joined
Mar 1, 2017
Messages
13
Thanks Cronk.



I've seen that method recommended many times but I want the user on a continuous form to be able to know which boxes have additional text (at a glance) and without requiring focus on the specific box.
 

isladogs

MVP / VIP
Local time
Today, 04:45
Joined
Jan 14, 2017
Messages
18,221
OK now I know what error you meant

One slight change & that part then opens OK
Change recordset to rst in the line triggering the error

Code:
Private Sub Form_Current()
   If Len(Details) > 120 Then
        Me.Details.ControlSource = ""
        Me.Details = Left([B][COLOR="Red"]rst![/COLOR][/B]Details, 120) & ". . ."
        Me.Lbl1.Visible = True
    Else
        Me.Details.ControlSource = "Details"
        Me.Lbl1.Visible = False
    End If
End Sub

However other errors then occur on your stripped down db.Try this in your full version & see if it works

@Cronk
I also use the zoombox or my own popup form with additional functionality.
However the reason tif provided was the main point of this thread in the first place
 

tif

Registered User.
Local time
Yesterday, 21:45
Joined
Mar 1, 2017
Messages
13
Thanks Ridders.


I made that change but now I am getting a variable not defined error. I can dim an rst varaiable as a recordset but I am not sure how to then define the variable so the lines return correctly.


Attached is the full database (only data has been scrubbed) if it helps.


Thanks for all of your help.
 

Attachments

  • Member Log.zip
    105.7 KB · Views: 120

Users who are viewing this thread

Top Bottom