2015-01-23 4 views
1

Я создаю мини-базовый «почтовый клиент» с помощью VBA. пользователь имеет возможность вставить поле «Имя» # имя # одним нажатием кнопки в позиции курсора в текстовом поле с несколькими строками (которое является телом электронной почты). После того, как пользователь нажимает кнопку отправки, код заменяет поле # name # именем, связанным с соответствующим адресом, выбранным из списка.Вставка строки в позицию курсора помещает ее неправильно при использовании многострочного текстового поля

Вкладка и ввод включены для текстового поля. Проблема в том, что, когда пользователь нажимает клавишу ввода, это воспринимается функцией Len() как 3 символа? Например .:

Пользователь вводит:

В

C: |

Len() берет на себя длину шнура как 9 символов здесь. Так позволяет сказать, что пользователь хочет, чтобы вставить поле имени только после того, как «:» в позиции курсора, указанной выше, он помещается следующим образом:

B

«# название # C: |

(Без «) Курсор позиции перемещается правильно, хотя и остается после того, как„:“

Вот код, я использую (Есть большинство из них из другого источника):

'Insert String at cursor 
Sub InsertAtCursor(ControlName As String, InsertString As String) 
Dim Ctrl As Object 'Object ref var 
Dim strPrior As String 'This var records the string before the cursor 
Dim strAfter As String 'This var records the string after the cursor 
Dim lngLen As Integer 'Saves the length (number of chars) currently in the text box 
Dim iSelStart As Integer 'Saves the current cursor position in the text box 

    'Set Ctrl as ref to the MessageBody text box 
    Set Ctrl = AdOp.Controls(ControlName) 

    With Ctrl 
     If .Enabled And Not .Locked Then     
      lngLen = Len(.Text) 
      'SelStart can't cope with more than 32k characters. 
      If lngLen <= 32767& - Len(InsertString) Then 
       'Remember characters before cursor. 
       iSelStart = .SelStart 
       If iSelStart > 1 Then 
        'Saves all text left of cursor 
        strPrior = Left$(.Text, iSelStart) 

       End If 
       'Remember characters after selection. 
       If iSelStart + .SelLength < lngLen Then 
        strAfter = Mid$(.Text, iSelStart + .SelLength + 1) 
       End If 
       'Assign prior characters, new string, and later ones. 
       .Value = strPrior & InsertString & strAfter 
       'Put the cursor back where it was, after the new string. 
       .SelStart = iSelStart + Len(InsertString) 
       'Return True on success 
       'InsertAtCursor = True 
      End If 
     End If 
    End With 

End Sub 

Любая помощь здесь будет замечательной. Спасибо заранее.

ответ

0

Got same issue. Это вызвано наличием CR + LF конца строки в содержимом элемента управления -> 2 символа. Но .SelStart учитывает только одну строку. Итак, полная логика этой подпрограммы должна быть пересмотрена для этого.

Вот, кажется, работает (должно быть улучшено и очищено): Идея состоит в том, чтобы работать с буфером копирования с разделителем строк vbLf (один символ).

Назначение: Вставьте символы в курсор в активном элементе управления. 'Return: True, если символы были вставлены. 'Аргументы: strChars = символ (символы), который вы хотите вставить в курсор. 'strErrMsg = строка для добавления любых сообщений об ошибках. 'Примечание: управление должно иметь фокус. 'Отлаживал: WorkArround для Pointer выпуска на CR + LF (2 символа) в качестве строки разделителей Public Function FormInsertAtCursor (Frm Как UserForm, strChars As String, Дополнительный strErrMsg As String) As Boolean On Error GoTo Err_Handler Dim strPrior As String' Текст перед курсором. Dim strAfter As String 'Текст после курсора. Dim lngLen As Long 'Количество символов Dim iSelStart As Integer' Где курсор.

If strChars <> vbNullString Then 
    With Frm.ActiveControl 
     If .Enabled And Not .Locked Then 

      Dim myText As String: myText = Replace(Frm.ActiveControl.Text, vbCr, "") 
      lngLen = Len(myText) 

      'SelStart can't cope with more than 32k characters. 
      If lngLen <= 32767& - Len(strChars) Then 

       iSelStart = .SelStart 

       myText = Left(myText, iSelStart) & strChars & Mid(myText, iSelStart + 1) 

       Frm.ActiveControl = myText 

       .SelStart = iSelStart + Len(strChars) 

       FormInsertAtCursor = True 
       Frm.ActiveControl.SetFocus 
      End If 
     End If 
    End With 
End If 

Exit_Handler: Выход Функция

Err_Handler: Debug.Print Err.Number, Err.Description Select Case Err.Number Case 438 &, 2135 &, 2144 & «Объект не Поддержите это свойство. Свойство доступно только для чтения. Неверный тип данных. strErrMsg = strErrMsg & «Вы не можете вставлять текст здесь». & vbCrLf Корпус 2474 &, 2185 & 'Активный контроль. Контроль не имеет фокуса. strErrMsg = strErrMsg & «Невозможно определить, какой элемент управления нужно вставить в символы». & vbCrLf Case Else strErrMsg = strErrMsg & "Ошибка" & Err.Number & ":" & Err.Description & vbCrLf End Select Резюме Exit_Handler End Function