Автоматическая прокрутка вниз с текстовым полем - PullRequest
4 голосов
/ 07 июля 2011

У меня есть файл MDB, созданный MS Access. Он получил форму внутри, а внутри формы есть одно большое текстовое поле.

Цель создания этого текстового поля - показать ход выполнения некоторой работы, добавив сообщения в текстовое поле:

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

Но проблема в том, что когда высота текста> высота текстового поля, новое сообщение не отображается автоматически. В текстовом поле есть полоса прокрутки, но я должен прокрутить ее вручную. Я хотел бы автоматически прокручивать страницу вниз при появлении нового текста.

Я пытался добавить этот код (скопированный из Интернета) в свойстве On Change, но код не удался, он ничего не делает:

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

Хотелось бы, чтобы был какой-то простой и красивый способ достичь этого. Я не хочу добавлять код, который работает только на некоторых компьютерах из-за его зависимости от ядра платформы Windows / и т. Д.

Ответы [ 3 ]

12 голосов
/ 07 июля 2011

Вы можете сделать это посредством вызова к сабвуферу;

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
0 голосов
/ 15 июля 2019

Существует обходной путь к недостатку дизайна, упомянутый Стивом Леви в его комментарии к оригинальному сообщению. Возможно иметь текстовое поле, которое выполняет оба следующих действия:

  • Когда содержимое слишком велико для коробки, а поле не иметь фокус, поле отображает последнюю часть его содержимого, а не первая его часть.
  • Когда поле имеет фокус, оно может прокрутить до любой части текста, но он первоначально показывает только последнюю часть текста, с курсор в конце текста.

Это достигается благодаря наличию двух наложенных текстовых полей одинакового размера, где одно видно только тогда, когда фокус находится в другом месте, а другое - только когда оно имеет фокус.

Вот пример того, как это сделать в Access 2010.

Создайте новую базу данных Access и создайте памятное поле с именем LongNote в его единственной таблице. Заполните LongNote несколькими примерами длинного текста. Создайте форму для редактирования этой таблицы.

Создайте текстовое поле с именем BackBox с желаемым размером и шрифтом, слишком маленьким, чтобы полностью показать типичное значение его источника данных, LongNote. (Вместо создания этого поля вы можете переименовать текстовое поле по умолчанию, созданное в форме.)

Сделайте точную копию этого окна с именем FrontBox. Задайте в качестве источника данных FrontBox либо все содержимое BackBox, либо последнюю часть содержимого, как показано ниже. Размер последней части, измеряемый в символах, зависит от размера поля и его шрифта, а также от типа отображаемого текста. Он должен быть выбран методом проб и ошибок, чтобы надежно разрешить отображение такого количества символов в поле. Например, вот формула для поля, которое может содержать до 250 символов:

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

Если все значение слишком велико для отображения, перед отображаемой частью указывается три точки, указывающие на то, что оно неполное.

Создайте еще одно текстовое поле с именем OtherBox, просто чтобы где-то можно было щелкнуть, кроме двух уже упомянутых полей, чтобы ни одно из них не имело фокусировки. Также создайте крошечное (0,0097 x 0,0097) текстовое поле с именем FocusTrap, которое используется, чтобы избежать выделения всего содержимого любого текстового поля, которое получает фокус при отображении формы (поскольку текст, выбранный таким образом, трудно читать).

Введите следующий код 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

Проверьте форму. Когда вы нажимаете на FrontBox, он должен исчезнуть, позволяя вам работать с BackBox. Когда вы щелкаете в OtherBox, чтобы удалить фокус из BackBox, FrontBox должен появиться снова. Любые изменения, сделанные в BackBox, должны быть отражены в FrontBox.

Вернувшись в режим разработки, переместите FrontBox так, чтобы он точно покрывал BackBox, и нажмите «Положение | Вывести на фронт, чтобы убедиться, что он покрывает BackBox. Теперь проверьте форму еще раз. Похоже, что одно текстовое поле переключается между режимом отображения последних нескольких строк и режимом редактирования всего содержимого.

0 голосов
/ 18 декабря 2016

Просто введите следующий код после linefeed или Change event txtStatus

txtStatus.SelStart = Len(txtStatus) - 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...