vba 使用文本框自动滚动到底部

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6607344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 13:36:52  来源:igfitidea点击:

Auto scroll to bottom with a textbox

formsms-accessvba

提问by lamwaiman1988

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

我有一个由 ms access 制作的 mdb 文件。它里面有一个表格,表格里面有一个大文本框。

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:

我尝试在 On Change 属性中添加此代码(从 Internet 复制),但代码失败,它什么也没做:

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.

我希望有一些简单而美丽的方法来实现这一目标。我不想添加一些仅在某些计算机上工作的代码,因为它依赖于 Windows 平台的内核/等。

回答by Alex K.

You can do it via a call to a sub;

您可以通过调用 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

回答by Frogrammer-Analyst

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:

steve lewy 在他对原帖的评论中提到的设计缺陷有一个解决方法。有一个文本框可能会执行以下两项操作:

  • 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.

下面是如何在 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.

创建一个新的 Access 数据库,并在其唯一的表中创建一个名为 LongNote 的备注字段。用一些长文本的例子填充 LongNote。创建用于编辑该表的表单。

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.)

使用所需的大小和字体创建一个名为 BackBox 的文本框,该文本框太小而无法完全显示其数据源 LongNote 的典型值。(您可以重命名在表单上创建的默认文本框,而不是创建此框。)

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:

制作一个名为 FrontBox 的盒子的精确副本。将 FrontBox 的数据源设置为 BackBox 的全部内容或内容的最后一部分,如下所示。最后一部分的大小(以字符为单位)取决于框的大小及其字体,以及要显示的文本类型。它需要通过反复试验来选择,以可靠地允许在框中显示这么多字符。例如,下面是一个只能容纳 250 个字符的盒子的公式:

=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).

创建另一个名为 OtherBox 的文本框,只是为了除了已经提到的两个框之外还有可以单击的地方,因此它们都没有焦点。还要创建一个名为 FocusTrap 的小 (0.0097 x 0.0097) 文本框,用于避免在显示表单时选择获得焦点的任何文本框的全部内容(因为以这种方式选择的文本难以阅读)。

Enter the following event-handling VBA code:

输入以下事件处理 VBA 代码:

' 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.

测试表格。当您单击 FrontBox 时,它应该会消失,让您可以在 BackBox 上工作。当您单击 OtherBox 以从 BackBox 中移除焦点时,FrontBox 应重新出现。在 BackBox 中所做的任何编辑都应反映在 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.

返回设计模式,移动 FrontBox 使其完全覆盖 BackBox,然后单击 Position | 带到前面以确保它覆盖 BackBox。现在再次测试表单。应该出现一个文本框在显示最后几行模式和编辑整个内容模式之间切换。

回答by AreMoh

Simply put the following code after linefeedor on Change event txtStatus

只需将以下代码放在后linefeed或上Change event txtStatus

txtStatus.SelStart = Len(txtStatus) - 1