Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto scroll to bottom with a textbox

I have an mdb file made by ms access. It got a form inside and inside the form there are one large textbox.

The intention of making this textbox is to show the progress of some work by adding messages inside the textbox:

txtStatus.value = txtStatus.value & "Doing something..." & vbCrLf
txtStatus.value = txtStatus.value & "Done." & vbCrLf

But the problem is, when the height of the text > height of the textbox, the new message is not displayed automatically. The textbox has a scroll bar, but I have to scroll it manually. I would like to auto scroll to the bottom whenever new text pop up.

I tried to add this code(copied from internet) in the On Change property, but the code failed, it does nothing:

Private Sub txtStatus_Change()
    txtStatus.SelStart = Len(txt) - 1
End Sub

I wish there would be some simple and beautiful way to achieve this. I don't want to add some code which only work on some computers due to its dependence on the windows platform's kernel/etc.

like image 339
lamwaiman1988 Avatar asked Jul 07 '11 07:07

lamwaiman1988


2 Answers

You can do it via a call to a sub;

AppendText "Bla de bla bla."
.
.
sub AppendText(strText As String)
    with txtStatus
        .setfocus '//required
        .value = .value & strText & vbNewLine
        .selstart = len(.Value)
    end with
end sub
like image 72
Alex K. Avatar answered Oct 21 '22 10:10

Alex K.


There is a workaround to the design flaw mentioned by steve lewy in his comment on the original post. It is possible to have a text box that appears to do both of the following:

  • When the contents are too large for the box, and the box does not have the focus, the box displays the last part of its contents, rather than the first part of it.
  • When the box has the focus, it can scroll to any part of the text, but it initially shows only the last part of the text, with the cursor at the end of the text.

This is accomplished by actually having two identically-sized, overlaid text boxes, where one is visible only when the focus is elsewhere, while the other is visible only when it has the focus.

Here’s an example of how to do it in Access 2010.

Create a new Access database, and create a memo field named LongNote in its only table. Fill LongNote with some examples of long text. Create a form for editing that table.

Create a text box called BackBox with the desired size and font, too small to completely show a typical value of its data source, LongNote. (Instead of creating this box, you can rename the default text box created on the form.)

Make an exact copy of that box called FrontBox. Set the data source of FrontBox to be either the entire contents of BackBox or the last part of the contents, as shown below. The size of the last part, measured in characters, depends on the size of the box and its font, as well as on the kind of text to be displayed. It needs to be chosen by trial and error to reliably allow that many characters to be displayed in the box. For instance, here’s the formula for a box that can reasonably hold only 250 characters:

=iif(Len([BackBox])>=250,"... " & Right([BackBox],246),[BackBox]) 

If the whole value is too large to be shown, three dots precede the part that is shown to indicate that it’s incomplete.

Create another text box called OtherBox, just to have somewhere you can click besides the two boxes already mentioned, so neither of them has the focus. Also create a tiny (0.0097 x 0.0097) text box called FocusTrap, which is used to avoid selecting the entire contents of whatever text box gets the focus when the form is displayed (because text selected that way is hard to read).

Enter the following event-handling VBA code:

' Prevent all text boxes from being focused when a new record becomes
' current, because the focus will select the whole text and make it ugly
Private Sub Form_Current()
   FocusTrap.SetFocus
End Sub
Private Sub Form_Open(Cancel As Integer)
   FocusTrap.SetFocus
End Sub

' When FrontBox receives focus, switch the focus to BackBox,
' which can display the entire text
Private Sub FrontBox_GotFocus()
   BackBox.SetFocus
   FrontBox.Visible = False
End Sub

' When BackBox receives the focus, set the selection to 
' the end of the text
Private Sub BackBox_GotFocus()
   BackBox.SelStart = Len([LongNote])
   BackBox.SelLength = 0
End Sub

' When BackBox loses focus, re-display FrontBox – if the text in 
' BackBox has changed, then FrontBox will follow the change
Private Sub BackBox_LostFocus()
   FrontBox.Visible = True
End Sub

Test the form. When you click on FrontBox, it should disappear, letting you work on BackBox. When you click in OtherBox to remove the focus from BackBox, FrontBox should reappear. Any edits made in BackBox should be reflected in FrontBox.

Back in design mode, move FrontBox so it exactly covers BackBox, and click Position | Bring to Front to ensure that it covers BackBox. Now test the form again. It should appear that a single text box switches between display-the-last-few-lines mode and edit-the-entire-contents mode.

like image 20
Frogrammer-Analyst Avatar answered Oct 21 '22 11:10

Frogrammer-Analyst