Макрос VBA Word, позволяющий пользователю выбирать и копировать текст несколько раз - PullRequest
0 голосов
/ 30 августа 2018

Я работаю над сценарием VBA с Microsoft Word, который позволяет пользователю выбирать текст, который будет скопирован в буфер обмена, чтобы его можно было экспортировать в файл Excel. Пользователь сделает несколько выборов и, наконец, укажет, что он / она сделал, когда содержимое буфера обмена будет скопировано в файл шаблона Excel.

Существует две формы: первая (UserForm1 в приведенном ниже коде) запрашивает у пользователя имя файла Word. Переменная имени файла передается во вторую форму. Вторая форма (frmModeLessForInput) является немодальной формой. Мне нужно поведение, при котором управление программой переходит во вторую форму с помощью двух кнопок «Продолжить» и «Готово».

Пользователь может перемещаться по документу и размещать курсор в любом месте документа. Затем при нажатии кнопки «Продолжить» форма вызовет подпрограмму (Highlight_Sentence) для копирования выделенного текста в переменную «буфер обмена». При нажатии кнопки «Готово» управление передается вызываемому основному модулю, который затем копирует буфер обмена в файл Excel.

Ниже приведен код. Я отметил с комментариями, где у меня проблемы с кодом. Одной из проблем является то, что переменные, определенные как Public в модуле ThisDocument, не определены в пользовательских формах и их подпрограммах.

Вторая проблема заключается в том, что в главном модуле должен отображаться frmModelessForInput, а элемент управления не должен передаваться в следующий оператор {MsgBox «Предложения теперь будут скопированы в файл Excel»… вот где я поместит код для копирования буфера обмена в файл Excel.}, но сообщение появляется до запуска формы frmModelessForInput ... таким образом, буфер обмена будет пустым.

Третья проблема заключается в том, что в форме frmModelessForInput оператор str_clipboard = str_clipboard + str_clipboard_line не работает. Каждый раз, когда нажимается кнопка «Продолжить», str_clipboard теряет предыдущее содержимое.

Любая помощь в решении этих проблем приветствуется. Поскольку программирование на VBA является для меня второстепенным, я все еще учусь.

Обратите внимание на обновленный вопрос Приостановите макрос VBA Word, позвольте пользователю сделать выбор и перезапустите его с остановленного состояния , добавив некоторые дополнительные сведения о требовании и примере кода.

ОСНОВНОЙ МОДУЛЬ:

Option Explicit
Public str_clipboard As String
Public txt_active_document As String
Public i_how_many_sentences As Integer
Private Sub Test_master_macro()
    UserForm1.Show
    i_how_many_sentences = 0
    Call DisplayModeless
    MsgBox "Sentences will now be copied to Excel file" 'Problem: this msg displays before the frmModelessForInput is displayed
End Sub
Sub DisplayModeless()
    Dim frm As frmModelessForInput
    Set frm = New frmModelessForInput
    With frmModelessForInput
        .str_word_doc_filename = txt_active_document
        .str_no_copied = "0"
        .Show False
    End With
    Set frm = Nothing
End Sub

USERFORM1: в форме есть поле для ввода пользователем имени файла документа для пользователя (имя_строки) и командная кнопка для закрытия формы (cmd_start_selecting_text)

Private Sub cmd_start_selecting_text_Click()
    'User enters filename on form for use in frmModelessForInput subroutine 
    txt_active_document = UserForm1.str_filename  'Problem: VBA reports txt_active_document as undefined even though it is a Public variable
    Unload Me
End Sub

FRMMODELESSFORINPUT: Форма отображает имя файла Word, введенного в UserForm1, и количество предложений, скопированных в буфер обмена

Option Explicit

Private Sub cmdContinue_Click()
 Dim str_clipboard, str_clipboard_line As String
       Call Highlight_Sentence(str_clipboard_line)
        i_how_many_sentences = i_how_many_sentences + 1 'Problem: VBA reports i_how_many_sentences as undefined even though it is a Public variable 
        frmModelessForInput.str_no_copied = i_how_many_sentences  'Same Problem
    str_clipboard = str_clipboard + str_clipboard_line 'Problem: each time I select a new text/sentence str_clipboard does not contain the contents of the previous selection
End Sub


Private Sub cmdDone_Click()
    Me.Hide
End Sub

Private Sub UserForm_Activate()
    'Position the form near the top-left of the window
    'So that the user can work with the document
    Me.Top = Application.ActiveWindow.Top + 15
    Me.Left = Application.ActiveWindow.Left + 15
End Sub

Private Sub Highlight_Sentence(clipboard As String)
    'This sub extends the selection to the entire sentence and copies the selection, the page number on which the selection is contained and the filename to the clipboard variable
    Dim txt_sentence, txt_page_no As String
    With Selection
     ' Collapse current selection.
     .Collapse
     ' Expand selection to current sentence.
     .Expand Unit:=wdSentence
    End With
    txt_sentence = Selection.Text
    txt_page_no = Selection.Information(wdActiveEndPageNumber)
    clipboard = txt_active_document & vbTab & txt_page_no & vbTab & txt_sentence & vbCrLf 'Problem: VBA reports txt_active_document as undefined even though it is a Public variable 
End Sub

1 Ответ

0 голосов
/ 30 августа 2018

Из того, что вы заявили, вы запускаете это из модуля класса ThisDocument, и если вы не полностью квалифицируете свои ссылки на эти публичные переменные с помощью имени класса, поэтому вы не можете получить к ним доступ из модулей класса UserForms.

Если вы собираетесь оставить свой код "Main Module" в модуле класса ThisDocument, то при каждой ссылке на эту переменную Public вам нужно добавить ThisDocument.str_clipboard к команде.

Тем не менее, я рекомендую поместить ваш основной модуль в общий модуль, такой как NewModule, и, если вам нужно запустить его в событии Document_Open, вы вызываете основной модуль и его открытые переменные в событии Private Sub Document_Open модуль класса ThisDocument.

Ваш Msgbox появляется не в то время, потому что вы отображаете немодальную пользовательскую форму, что означает, что поток сценариев VBA продолжает работать после отображения пользовательской формы. Переместите Msgbox в процедуру UserForm_Activate второй отображаемой пользователем пользовательской формы или переместите ее в процедуру Click_Done первой пользовательской формы, прежде чем скрывать или выгружать ее.

Наконец, вы на самом деле не используете буфер обмена, и использование этого термина делает мой код запутанным, на мой взгляд. Я думаю, вы должны переименовать его. Ваш код также, кажется, просто строит одну непрерывную строку текста. Это действительно то, что вы хотите сделать? Или вы действительно хотите записать каждую выбранную текстовую строку и в конечном итоге поместить ее в отдельные ячейки в рабочей таблице Excel? Если это так, используйте массив для отдельных текстовых строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...