Есть ли способ отключить ввод многострочных записей в текстовое поле (т.е. я хотел бы запретить моим пользователям использовать ctrl-enter для получения новой строки)?





не совсем уверен в этом, вы должны иметь возможность удалить разрывы строк при рендеринге контента или даже запустить vbscript, чтобы очистить его, вам просто нужно проверить chr (13) или vbCrLf.
То, как я делал это раньше (а в последний раз я работал в Access, было где-то в 97-м, так что моя память не ахти), вызывал событие нажатия клавиши и выполнял функцию VBA. Это метод, аналогичный тому, что вы делаете с текстовым полем предложения AJAX в современном приложении веб-формы, но, насколько я помню, он может отключиться, если в вашей форме Access есть другие события, которые, как правило, часто происходят, например onMouseMove, по всему объекту формы.
Опять же, событие KeyUp сначала при каждом нажатии клавиши, и это может привести к мерцанию экрана. И это просто неэффективно - лучшим событием для этого по-прежнему является событие AfterUpdate элемента управления, который вы используете для редактирования заметки, потому что оно запускается только один раз.
Я смог сделать это с помощью события KeyPress. Вот пример кода:
Private Sub SingleLineTextBox_ KeyPress(ByRef KeyAscii As Integer)
If KeyAscii = 10 _
or KeyAscii = 13 Then
'10 -> Ctrl-Enter. AKA ^J or ctrl-j
'13 -> Enter. AKA ^M or ctrl-m
KeyAscii = 0 'clear the the KeyPress
End If
End Sub
Это ни в коем случае не лучшее решение, потому что оно использует неправильное событие и срабатывает при каждом нажатии клавиши. Событие AfterUpdate элемента управления является более подходящим и запускается только один раз.
У меня это работает. Нет мерцания экрана. И в этом случае я хочу предотвратить неправильный ввод изначально, а не пытаться отсеять его позже и либо выдать пользователю тупую ошибку, либо изменить его ввод на нем.
Я использую это решение в сочетании с Решение AfterUpdate, потому что последний также учитывает разрывы строк, вставленные с помощью копирования и вставки.
Если вы не хотите, чтобы событие мешало, вы можете настроить свойство Validation Rule, чтобы текстовое поле было
NOT LIKE "*"+Chr(10)+"*" OR "*"+Chr(13)+"*"
Вероятно, вы также захотите установить текст проверки, чтобы конкретно объяснить, почему Access выдает окно с ошибкой.
Не совсем то, что я хотел, пользователь, кажется, никогда не понимает текст проверки. Спасибо хоть.
Использование события KeyPress означает, что ваш код будет запускаться каждый раз, когда пользователь вводит. Это может привести к мерцанию экрана и другим проблемам (событие OnChange будет таким же).
Мне кажется, что вы должны использовать одно событие для удаления CrLf, и правильным событием будет AfterUpdate. Вы бы просто сделали это:
If InStr(Me!MyMemoControl, vbCrLf) Then
Me!MyMemoControl = Replace(Me!MyMemoControl, vbCrLf, vbNullString)
End If
Обратите внимание на использование глобальных констант Access, vbCrLf (для Chr (10) и Chr (13)) и vbNullString (для строки нулевой длины).
Использование правила проверки означает, что вы собираетесь выдать уродливое сообщение об ошибке для своего пользователя, но предоставляете им мало инструментов для исправления проблемы. Мне кажется, что подход AfterUpdate намного чище и проще для пользователей.
Учитывая, что вы обрабатываете его во внешнем интерфейсе, нет ничего плохого в добавлении правила проверки в базу данных. Это может быть даже благом, например, когда пользователь пытается получить доступ к данным через Excel, как всегда рано или поздно :)
Но если вы введете правило проверки, вы должны использовать событие BeforeUpdate вместо AfterUpdate. В противном случае вы получите сообщение об ошибке данных Jet о нарушении правила проверки.
Я понимаю ваш аргумент. Однако на практике я не получаю мерцания экрана с помощью моего метода. Кроме того, очистка CrLf после того, как пользователь внес обновления, изменит способ представления данных по сравнению с тем, как они были введены. Что, в свою очередь, приведет к еще большему крику пользователей. Я предпочитаю, чтобы при вводе данных «они видели то, что получали».
Спасибо, Ян и BIBD. На основе вашего ответа я создал общедоступную подписку, которую можно использовать повторно.
Public Sub PreventNewlines(ByRef KeyAscii As Integer)
If KeyAscii = 10 Or KeyAscii = 13 Then KeyAscii = 0
End Sub
Private Sub textbox_KeyPress(KeyAscii As Integer)
Call PreventNewlines(KeyAscii)
End Sub
Мерцание экрана никогда не должно быть проблемой, поскольку это обрабатываемые события, а не постоянный опрос (и это для каждого элемента управления еще больше ограничивает область действия). Мне кажется недопустимым аргументом, поскольку каждый текстовый редактор выполняет какой-то код при нажатии клавиши.
Спасибо
Ответ Джейсона работает хорошо. Просто чтобы добавить к этому ..
Если вы хотите разрешить пользователю оставлять текстовое поле пустым, вы можете использовать это:
Не похоже на ""+ Chr (10) +"" или ""+ Chr (13) +"" или равно нулю
Не совсем то, что я хотел. Это означает, что мне нужно обезьянничать с данными пользователя в фоновом режиме (не WYSIWYG) или выдавать ошибки, которые я бы дал много объяснений. Спасибо хоть.