我正在使用Microsoft Word处理VBA脚本,该脚本允许用户选择要复制到剪贴板的文本,以便可以将其导出到Excel文件。当剪贴板中的内容复制到模板Excel文件中时,用户将进行很多选择,最后指示完成。
表单frmModelessForInput
允许用户选择复制到字符串变量(str_clipboard
)的文本,按“继续”按钮重复选择其他文本,然后在菜单项中按“完成”。文本字符串被复制到剪贴板,然后粘贴到之前打开的Excel文件中。
问题是,当我尝试将Windows剪贴板中的内容粘贴到frmModelessForInput窗体的cmdDone子项中的Excel文件中时,wb_open对象大约一半时间给我一个错误91。我相信在Check_Excel_RTM_Template_Test子目录中也遇到了同样的问题,并通过将oExcel对象传递给子目录来解决了该问题。我正在尝试将oExcel对象传递给表单,但是即使我按照以下建议合并了表单的Property,它也会呈现与上一个子相同的错误。
我创建了“最小”代码,并添加了注释以解释每个子组件正在完成的关键任务。我已经运行了此代码,但失败的方式与我的“生产”代码相同。
预先感谢您帮助我解决问题。
主模块
' This is the minimal master module where I open the Excel Template and Word document to process
Option Explicit
Public str_clipboard As String
Public i_how_many_sentences, i_starting_row_ID As Integer
Public str_active_document As String
Public str_Excel_Filename As String
Public b_abort As Boolean
Public i_rows_of_data As Integer
Sub Master_Module_Test()
Dim oExcel As Object
Set oExcel = New Excel.Application
str_Excel_Filename = "C:\Test\Excel_Template.xlsx"
str_active_document = "C\Test\Doc_to_process.docx"
Documents.Open (str_active_document)
oExcel.Visible = True
oExcel.ScreenUpdating = True
oExcel.Workbooks.Open str_Excel_Filename
Call Check_Excel_RTM_Template(oExcel)
i_how_many_sentences = 0
Call Select_Sentence_Form_Test(oExcel)
End Sub
主模块中的子
' This sub now works without errors
' The calling routine passes the object oExcel....this approach works
' Previously I didn't pass oExcel but used the following statements
' Dim wb_open as Workbook
' Set Wb_open = ActiveWorkBook
' This also worked sometimes and failed about half the time
' This sub checks the Excel file whether it is of the expected format and then selects the cell where the new data will be pasted
' I have only included the statement to do the selection
' This sub works without any errors
Sub Check_Excel_RTM_Template_Test(oExcel As Object)
oExcel.ActiveSheet.range("A6").Select
End Sub
主模块中的子
' This sub activates the frmModelessForInput so that the user can select sentences; the form executes and works as expected
Sub Select_Sentence_Form_Test(wb_open As Object)
Dim frm As frmModelessForInput
Set frm = New frmModelessForInput
' Here is where I set the property of the frmModelessForInput to open Excel workbook as suggested in the response
Set frmModelessForInput.Book = wb_open
With frmModelessForInput
.str_word_doc_filename = str_active_document
.str_no_copied = "0"
.Show False
End With
Set frm = Nothing
End Sub
从完整路径名提取文件名的功能。
Function getName(pf)
getName = Split(Mid(pf, InStrRev(pf, "\") + 1), ".")(0) & ".xlsx"
End Function
frmModelessForInput表单代码
' Here I implemented the suggested property for the form
' I changed the declaration to "Object" since oExcel in Master_Module_Test is declared as an object
Option Explicit
Private m_Book As Object
Public Property Get Book() As Object
Set Book = m_Book
End Property
Public Property Set Book(ByRef Value As Object)
Set m_Book = Value
End Property
' This sub works without errors
Private Sub cmdContinue_Click()
Dim str_clipboard_line As String
Dim i_row_number As Integer
' When the "Continue" button is pressed the code selects the sentence at the cursor and adds the contents to str_clipboard variable
i_row_number = i_how_many_sentences + i_starting_row_ID
i_how_many_sentences = i_how_many_sentences + 1
Call Highlight_Sentence(str_clipboard_line, i_row_number)
frmModelessForInput.str_no_copied = i_how_many_sentences
str_clipboard = str_clipboard + str_clipboard_line
End Sub
Private Sub cmdDone_Click()
Unload frmModelessForInput
' When the "Done" button is pressed the contents of the str_clipboard variable is copied to the Windows clipboard
Dim str_filename As String
str_filename = getName(str_Excel_Filename)
MsgBox "I will now copy the data to the Excel file."
Dim wb_open As Object
Set wb_open = ActiveWorkbook
Call SendToClipboard(str_clipboard) 'This sub puts the contents of str_clipboard into the Windows clipboard
' The following statement works sometimes but other times it has runtime error 91: Object variable or With block variable not set
wb_open.ActiveSheet.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False, NoHTMLFormatting:=True
MsgBox "Done pasting data to: " & getName(str_Excel_Filename)
End Sub
' This sub works without errors
Private Sub Highlight_Sentence_Test(clipboard As String, i_row_no As Integer)
Dim txt_sentence, txt_page_no As String
Dim txt_section_index 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)
'I Use tabs to line up data in the correct columns in template file
clipboard = i_row_no & vbTab & str_active_document & vbTab & txt_page_no & vbTab & vbTab & vbTab & vbTab & txt_sentence & vbCrLf
End Sub
答案 0 :(得分:1)
这可以通过在表单中添加新的Property
来完成。在您的表单中,添加以下代码:
Private m_Book As WorkBook
Public Property Get Book() As WorkBook
Set Book = m_Book
End Property
Public Property Set Book(ByRef Value As WorkBook)
Set m_Book = Value
End Property
然后在您的调用代码中,添加要使用的工作簿,如下所示:
Set frmModelessForInput.Book = wb_open
或:
Set frmModelessForInput.Book = ActiveWorkbook
答案 1 :(得分:0)
基本问题是问题中的代码不适用于正确的Excel对象。由于与Excel有关的所有事情都声明为数据类型Object
,因此VBA无法提供更准确的错误消息-它必须猜测是什么意思。设置对Excel对象库的引用(工具/参考)并声明确切的数据类型可能会有所帮助,直到代码正常工作为止。然后,如果要使用后期绑定,则可以将声明更改为Object
。
这里有一些示例,说明了如何传递错误的对象类型,这导致VBA感到困惑。
在以下过程中,我添加了一个Excel.Workbook
对象声明,并在打开工作簿时实例化它。由于UserForm需要使用工作簿对象,因此此将传递给Select_Sentence_Form_Test
...
Sub Master_Module_Test()
Dim oExcel As Object
Dim wb As Excel.Workbook 'Object
Set oExcel = New Excel.Application
str_Excel_Filename = "C:\Test\Excel_Template.xlsx"
str_active_document = "C\Test\Doc_to_process.docx"
Documents.Open (str_active_document)
oExcel.Visible = True
oExcel.ScreenUpdating = True
Set wb = oExcel.Workbooks.Open(str_Excel_Filename)
Call Check_Excel_RTM_Template(oExcel)
i_how_many_sentences = 0
Call Select_Sentence_Form_Test(wb)
End Sub
在代码中的问题中,正在传递 Excel应用程序,并将其分配给Book
属性。 VBA允许这样做,因为所有内容都键入为Object
。但是,当需要使用工作簿时,它就不起作用了(从逻辑上讲是不可行的)。
Sub Select_Sentence_Form_Test(wb_open As Object) 'As Excel.Workbook
Dim frm As frmModelessForInput
Set frm = New frmModelessForInput
' Here is where I set the property of the frmModelessForInput to open Excel workbook as suggested in the response
Set frmModelessForInput.Book = wb_open
With frmModelessForInput
.str_word_doc_filename = str_active_document
.str_no_copied = "0"
.Show False
End With
Set frm = Nothing
End Sub
然后cmdDone_Click
不能与属性一起使用,并且即使没有ActiveWorkbook
对象限定符,也尝试访问Excel.Application
,但此过程中也不可用。这是Word VBA,它不是“知道” ActiveWorkbook
。
相反,代码应使用Book
属性(毕竟是创建它的原因)。
Private Sub cmdDone_Click()
Unload frmModelessForInput
' When the "Done" button is pressed the contents of the str_clipboard variable is copied to the Windows clipboard
Dim str_filename As String
str_filename = getName(str_Excel_Filename)
MsgBox "I will now copy the data to the Excel file."
''' Dim wb_open As Object
''' Set wb_open = ActiveWorkbook 'can' work without Excel.Application
Call SendToClipboard(str_clipboard) 'This sub puts the contents of str_clipboard into the Windows clipboard
' Uses the Book property
Me.Book.ActiveSheet.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False, NoHTMLFormatting:=True
MsgBox "Done pasting data to: " & getName(str_Excel_Filename)
End Sub
请注意,我尚未对此进行测试,因为设置环境会花费太多时间。