I need to copy/paste table from Excel to owrd to a specific line. I have written the code and it works fine in the Excel and Word 2016 I used, but when I tried running in other versions (2013,2010,2007) it didn't work at all. So i try to use late binding, but it throws a Bad Parameters error in .selection
How to remove Bad Parameters? Thanks,
Here's the code :
Sub Movetable ()
'Name of the existing Word document
Const stWordDocument As String = "Test.docx"
'Word objects.
Dim wdApp As Object
Dim wdDoc As Object
Dim wdRange As Object
'Excel objects
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim xlRange As Excel.Range
'Initialize the Excel objects
Set wbBook = ThisWorkbook
Worksheets("RJ").Select
LastRow = Range("A" & Rows.Count).End(xlUp).Row
Set xlRange = Range("A4:D" & LastRow)
xlRange.Select
xlRange.Copy
'Instantiate Word and open the "Test" document.
Set wdApp = CreateObject("Word.Application")
Set wdDoc = wdApp.Documents.Open(wbBook.Path & "\" & stWordDocument)
wdDoc.Application.Selection.Find.Execute "Table 1. Summary", MatchCase:=True
wdApp.Selection.MoveDown Unit:=wdLine, Count:=2, Extend:=wdMove
wdApp.Selection.PasteExcelTable False, False, False
wdDoc.Tables(1).AutoFitBehavior wdAutoFitWindow
'Save and close the Word doc.
With wdDoc
.Save
.Close
End With
wdApp.Quit
'Null out the variables.
Set wdRange = Nothing
Set wdDoc = Nothing
Set wdApp = Nothing
End Sub
Very probably, the reason is that you've set a Refernce to the Microsoft Word library for version 2016. When you open and run the project in an earlier version, the reference doesn't change to the Microsoft Word library for that version. This is expected behavior.
To fix the problem you can either
Open the project in the earliest version of Office (2007,
apparently). Go to Tools/References in the VBA Editor and select the
Microsoft Word library for that version. Test, then save.
Office applications will change References to a newer version, but they don't do so the other way around. That's why it's always recommended to develop using the oldest version of Office the project should work in.
Don't use named arguments in the method calls. Remove, for example, MatchCase:=, Unit, Count, Extend. In addition, don't use the Word enumerations: wdLine, wdMove, wdAutoFitWindow- these all have numerical equivalents, use those instead.
This is known as "late-binding", which makes your project independent of the version of Word. You can then completely remove the Reference to the Microsoft Word library.
In order to find out the numerical equivalents you can look up the enumerations in the VBA Object Browser (F2 in the VBA Editor), look them up in the Word VBA Help or query them in the VBA Editor Immediate Window (Ctrl + G) using syntax like this: ?wdLine and then press Enter to execute.
Related
I am trying to do some relatively simple copy and pasting from Excel 2007 into Word 2007. I've looked through this site and others, and keep getting hung up on the same thing- the third line n the code below keeps giving me the "User type note defined" error msg. I am really confused since I just lifted this from another solution (and had similar issues with other solutions I tried to lift). Could someone please educate me on what is causing the error, and why?
Sub ControlWord()
' **** The line below gives me the error ****
Dim appWD As Word.Application
' Create a new instance of Word & make it visible
Set appWD = CreateObject("Word.Application.12")
appWD.Visible = True
'Find the last row with data in the spreadsheet
FinalRow = Range("A9999").End(xlUp).Row
For i = 1 To FinalRow
' Copy the current row
Worksheets("Sheet1").Rows(i).Copy
' Tell Word to create a new document
appWD.Documents.Add
' Tell Word to paste the contents of the clipboard into the new document
appWD.Selection.Paste
' Save the new document with a sequential file name
appWD.ActiveDocument.SaveAs Filename:="File" & i
' Close this new word document
appWD.ActiveDocument.Close
Next i
' Close the Word application
appWD.Quit
End Sub
This answer was mentioned in a comment by Tim Williams.
In order to solve this problem, you have to add the Word object library reference to your project.
Inside the Visual Basic Editor, select Tools then References and scroll down the list until you see Microsoft Word 12.0 Object Library. Check that box and hit Ok.
From that moment, you should have the auto complete enabled when you type Word. to confirm the reference was properly set.
As per What are the differences between using the New keyword and calling CreateObject in Excel VBA?, either
use an untyped variable:
Dim appWD as Object
appWD = CreateObject("Word.Application")
or
Add a reference to Microsoft Word <version> Object Library into the VBA project via Tools->References..., then create a typed variable and initialize it with the VBA New operator:
Dim appWD as New Word.Application
or
Dim appWD as Word.Application
<...>
Set appWd = New Word.Application
CreateObject is equivalent to New here, it only introduces code redundancy
A typed variable will give you autocomplete.
We copy data from Excel cells to a new Word document based on a .docx template document. The positioning in the Word document is found with a bookmark.
The VBA code has been working, but since upgrading to MS Office 2016 from 2010 we have been getting errors:
run time error 4605 this method or property is not available because
the clipboard is empty or not valid
And then I get
4605 This method or property is not available because this command is
not available for reading
I tried the wdDoc.Bookmarks… and I get
6124 You are not allowed to edit this selection because it is
protected
I checked all the protection, trust center settings, etc. and all look correct.
"editProject" is a single cell label.
Dim wdApp As Object
Dim wdDoc As Object
Set wdApp = CreateObject("Word.application")
Set wdDoc = wdApp.Documents.Open(Filename:=WdocT, ReadOnly:=True)
' Project NAME
wdDoc.Bookmarks("BOOKMARK1").Range.Select ' wdDoc.Bookmarks("CLIENT").Range.Select
xlData = Sheets("Data Input").Range("editProject") ' get the data
'THIS IS THE PROBLEM LINE
wdApp.Selection.TypeText Text:=xlData ' place in doc '8/10/19 FALLING OVER HERE
I know the doc is opening, and the bookmark is found, as I put in the following to check:
'temp TRY THIS
Dim tempRange As Word.Range
Dim tempStart As Long
Dim tempEnd As Long
' Set tempRange = wdDoc.Bookmarks("BOOKMARK1").Range
Set tempRange = wdDoc.Bookmarks("BOOKMARK2").Range ' THIS WORKS
tempStart = tempRange.Start
tempEnd = tempRange.End
I tried clearing the clipboard with the following:
' 8/10/19 Bruce the following may help with clipboard error message 4605
wdDoc.UndoClear
Dim oData As New DataObject ' object to use the clipboard
oData.SetText Text:=Empty ' clear
oData.PutInClipboard ' take in the clipboard to empty it
'Application.Wait (Now + TimeValue("00:00:10")) ' this is required to stop clipboard overflow error
Application.CutCopyMode = False ' 8/10/19 Bruce - this should clear the clipboard
DoEvents ' test fixing error 4605
' DoEvents passes control to the operating system.
' Control is returned after the operating system has
' finished processing the events in its queue
I tried the following in the appropriate place, but it makes no difference:
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
wdApp.Visible = True
I tried the following line instead of the copy, but the same error is thrown;
wdApp.Selection.MoveDown Unit:=wdLine, Count:=1
If Excel General setting "Open e-mail attachments and other uneditable files in reading view" is NOT ticked, it seems to work.
I am having a similar issue after my environment was upgraded to Office 2016. The code I had was working perfectly before the upgrade.
One thing I noticed later was that, after the upgrade to Office 2016, the same VBA code that used to work would open a Word doc in the "reading mode". In this mode, no editing of the document is allowed, no matter via the UI or via code. This is the meaning of the cryptic error message "4605 This method or property is not available because this command is not available for reading".
To get around this, I added the following line to make Word switch back to the "Print layout view".
objWord.ActiveWindow.View.Type = wdPrintView
where objWord is the Word object created by code not listed here.
Then I can use my old code like these to type text via VBA:
objWord.Selection.GoTo What:=wdGoToBookmark, Name:=bookmarkName
objWord.Selection.TypeText Text:=someText
So if you notice your VBA code happens to open a Word doc in the "Reading mode", you can try this work around.
A similar situation is described at this link and I came across it after I found my work around:
https://blogs.msmvps.com/wordmeister/2013/02/22/word2013bug-not-available-for-reading/
I'm making a xls that generates word documents from doc templates.
I'm storing the doc templates into the same folder as the xls.
to move the xls (and have it work), i need to move all the other files too.
is there a way to have just 1 xls file that includes all the others??
I might be missing something... I cannot manually save the embedded object externally. when i double click on the object the word ribbons and the save icon appear , but I can't find the "save as" anywhere.
thx in advance
You can embed a Word Doc as an object in Excel, following this example.
Once that's done you can manipulate it like this
Sub Demp()
' Add a reference to Microsoft Word Object Library,
' or convert to late binding
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim ole As OLEObject
Dim EmbededFile As String
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("NameOfSheetWithEmbeddedObjects")
' Change to suit your needs, or build with code
EmbededFile = "c:\Data\temp\TestDoc1.docx"
' Change Object Names to suit your needs
Set ole = ws.OLEObjects("Object 1")
'ole.Activate
ole.Verb Verb:=xlOpen
Set wdApp = ole.Object.Application
With wdApp.ActiveDocument
.SaveAs EmbededFile, Word.wdFormatDocumentDefault
.Close
End With
Set wdDoc = wdApp.Documents.Open(EmbededFile)
' you can now manipulate the Word App (using wdApp) and document (using wdDoc)
End Sub
How can I modify an opened word document through Excel with VBA?
Here a bit of code I'm writing, but there's something wrong I can't understand.
Dim WordDoc As Word.Document
Dim WordApp As Word.Application
'ThisWorkbook is the opened Excel Workbook through which I control Word documents.
If Len(Dir(ThisWorkbook.path & "\Report.docx")) <> 0 then
'if the document exists in the folder where ThisWorkbook is saved, I check
'if the document is already opened.
If IsFileOpened(ThisWorkbook.path & "\Report.docx")
'if during the run-time I get here, it means that the document exists and
'it's already opened.
'Now I want to get the reference to the opened document "Report.docx",
'so I do a thing like this.
Set WordDoc= Word.Application.Documents(ThisWorkbook.path & "\Report.docx")
'When it tries to excute the instruction over, it gives me a message in which
'it is written that the name is bad or inexistent, even if the document
'is already opened. Is the instruction correct?
Set WordApp= WordDoc.Application
'...other code
Else
'if the document isn't opened, I open it.
Set WordApp = CreateObject("Word.Application")
Set WordDoc = WordApp.Documents.Open(ThisWorkbook.path & "\Report.docx")
'..other code
End If
Else 'I create a new document called "Report.docx" if it doesn't exist
'in the folder where ThisWorkbook is saved.
Set WordApp = CreateObject("Word.Application")
Set WordDoc = WordApp.Documents.Add("Report.docx")
'.... other code
End If
Thanks in advance...
I tried this with an excel workbook and it worked
Set WordDoc= Word.Application.Documents(ThisWorkbook.path & "\Report.docx")
should be
Set WordDoc= Word.Documents("Report")
When I tried using the file path, I got Run-time error "9" Subscript out of range. When I used just the file name, it was successful.
Edit: After trying this with a word document, you do not need the application object and should not use the file extension. I can confirm that this works.
I tried this version
path = ThisWorkbook.path & "\Report.docx"
Set WordApp = GetObject(path).Application
in place of
Set WordDoc= Word.Application.Documents(ThisWorkbook.path & "\Report.docx")
and it works.
I am building a form in Access that will allow a user to select an excel file, and then select a worksheet to import. I have code that allows a user to select an Excel file and it stores the filename in a control on the form.
Now I want to display the names of the worksheets that are in that file. I know how to do the import, what I don't know is how to get the worksheet names in the file and store them either in a table, or a listbox on the form so the user can select one. Sadly, although all the Excel files are supposed to have standard names for the worksheets, some of the sheets are off and that is why I want to display them.
I am using Office 2007.
Set oWkb = oXLApp.Workbooks.Open(FileName)
For Each oSh In oWkb.Worksheets
MsgBox oSh.Name
Next
oXLApp would be an instance of the Excel application, which you can get using Set oXLApp = CreateObject("Excel.Application").
Make sure you close your workbook when you are done getting the sheet names. I would probably store them in a collection or an array (instead of the MsgBox oSh.Name) so that you can collect them, close the workbook, and display them on your form using the contents of the collection.
In my testing, using an ADOX Catalog to retrieve the worksheet names appears significantly faster than opening an Excel application instance to enumerate the WorkSheets collection.
Public Sub List_WorksheetsAdox(ByVal pWorkBook As String)
Dim cat As Object 'ADOX.Catalog
Dim cn As Object 'ADO.Connection
Dim strConnect As String
Dim tbl As Object 'ADOX.Table
strConnect = "Provider=" & _
CurrentProject.Connection.Provider & ";" & _
"Data Source='" & pWorkBook & "';" & _
"Extended Properties=Excel 8.0;"
Set cn = CreateObject("ADODB.Connection")
cn.Open strConnect
Set cat = CreateObject("ADOX.Catalog")
Set cat.ActiveConnection = cn
For Each tbl In cat.Tables
Debug.Print tbl.Name
Next tbl
Set tbl = Nothing
Set cat = Nothing
cn.Close
Set cn = Nothing
End Sub
This approach will include the dollar sign after each sheet name, which may not be what you want. You could strip it off easily.
I tested using Excel 8.0 for my xls 2003 format workbook. It appears the Excel 2007 format would require "Excel 12.0" for Extended Properties. You can find more details at ConnectionStrings.com.
As in the other answers, you will want to do something more useful with tbl.Name other than Debug.Print it.
Note this approach will list both named ranges and worksheets. If that is an issue for you, you can distinguish between them based on whether or not the name includes a dollar sign ("$") on the end. Sheets have the dollar sign; named ranges do not.
Something like this?
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Set wb = Excel.Workbooks.Open("C:\MyBook.xls") ' Or whatever
For Each ws In wb.Worksheets
Debug.Print ws.Name
' This prints the name in the Immediate window.
' You'll want to do something useful with them instead.
Next ws
To use this, must set reference to Excel object library: Tools > References > set checkmark next to Microsoft Excel xx.0 Object Library.