I am trying to use a master file, referred to as mDoc to copy charts from a slave file, called sDoc. It seems the code works during the first loop, but on the second and all subsequent loops, no charts are copied from the master to the slave.
Sub CopyAllCharts()
Dim objShape As InlineShape
Dim mDoc As Document
Dim sDoc As Document
Path = "C:\Users\ryans\Desktop\word_docs\"
File = Dir(Path & ".")
Do While File <> ""
Set mDoc = Documents("Testing.docm")
Set sDoc = Documents.Open(FileName:=Path & File)
Windows(sDoc).Activate
Debug.Print ActiveDocument.Name
For Each objShape In sDoc.InlineShapes
Debug.Print objShape.HasChart
If objShape.HasChart Then
objShape.Chart.Select
Selection.Copy
Windows(mDoc).Activate
Debug.Print ActiveDocument.Name
Selection.PasteAndFormat (wdPasteDefault)
Selection.Collapse Direction:=wdCollapseStart
End If
Next objShape
sDoc.Close SaveChanges:=False
File = Dir()
Loop
End Sub
During the first loop, these lines select and print the active document's name.
Windows(mDoc).Activate
Debug.Print ActiveDocument.Name
On the second and all other loops, Windows(mDoc).Activate does NOT activate the master document and Debug.Print ActiveDocument.Name prints the slave document's name but not the master document's name.
I tried to get the Range thing working, and made some progress, but in the end, I couldn't quite get it to work the way I wanted. Ultimately, I went with the code sample below, which does what I want.
Sub CopyAllCharts()
Dim objShape As InlineShape
Dim mDoc As Document
Dim sDoc As Document
Path = "C:\Users\ryans\Desktop\word_docs\"
File = Dir(Path & ".")
Do While File <> ""
Set mDoc = Documents("Control One Word Document From Another Word Document.docm")
Set sDoc = Documents.Open(FileName:=Path & File)
Windows(sDoc).Activate
If sDoc.Name = ActiveDocument.Name Then
Windows(sDoc).Activate
Debug.Print ActiveDocument.Name
For Each objShape In sDoc.InlineShapes
Debug.Print ActiveDocument.Name
Debug.Print objShape.HasChart
If objShape.HasChart Then
objShape.Chart.Select
Selection.Copy
If mDoc.Name <> ActiveDocument.Name Then
Windows(mDoc).Activate
End If
Debug.Print ActiveDocument.Name
Selection.PasteAndFormat (wdPasteDefault)
Selection.Collapse Direction:=wdCollapseStart
End If
Windows(sDoc).Activate
Debug.Print ActiveDocument.Name
Next objShape
End If
sDoc.Close SaveChanges:=False
File = Dir()
Loop
End Sub
Related
I'm trying to make the following code work but am getting not getting the expected results.
The code recursively loops through all the folders and subfolders of where the file is located and joins all the PowerPoint documents into a single file.
The thing is that at times it seems to loop twice, duplicating the set of slides after the first pass of all the files.
What could be causing such behavior?
Sub loopAllSubFolderSelectStartDirectory()
Dim FSOLibrary As Object
Dim FSOFolder As Object
Dim folderName As String
folderName = ActivePresentation.Path
If Len(folderName) > 0 Then
MsgBox ActivePresentation.Name & vbNewLine & "saved under" & vbNewLine & folderName
Else
MsgBox "File not saved"
End If
'Set the reference to the FSO Library
Set FSOLibrary = CreateObject("Scripting.FileSystemObject")
'Another Macro must call LoopAllSubFolders Macro to start
LoopAllSubFolders FSOLibrary.GetFolder(folderName)
End Sub
Sub LoopAllSubFolders(FSOFolder As Object)
Dim FSOSubFolder As Object
Dim FSOFile As Object
'For each subfolder call the macro
For Each FSOSubFolder In FSOFolder.subfolders
LoopAllSubFolders FSOSubFolder
Next
On Error GoTo DoNext
'For each file, print the name
For Each FSOFile In FSOFolder.Files
'Insert the actions to be performed on each file
'This example will print the full file path to the immediate window
Debug.Print FSOFile.Path
With ActivePresentation
.Slides.Add Index:=.Slides.Count + 1, Layout:=ppLayoutCustom
With ActivePresentation.Slides(.Slides.Count)
.FollowMasterBackground = False
.Background.Fill.Solid
.Background.Fill.ForeColor.RGB = RGB(255, 0, 0)
.Shapes.Title.TextFrame.TextRange.Text = FSOFile.Path
.Shapes.Title.TextFrame.TextRange.Font.Color = RGB(255, 255, 255)
End With
.Slides.InsertFromFile FSOFile.Path, .Slides.Count
End With
DoNext:
Next
End Sub
Thanks in advance
You should skip active presentation file:
With ActivePresentation
...
If FSOFile.Path <> .FullName Then
.Slides.InsertFromFile FSOFile.Path, .Slides.Count
End If
End With
I an using a code copied from "Macropod" (sorry if the name is incorrect) to replace every header and footer in a folder of documents with a new header and footer as displayed in the macro document. It is slightly altered to apply to only footers. This works, but my problem is that it leaves an extra paragraph mark on a line by itself at the end of the footer text and I cannot figure out where to add something that would remove the extra paragraph mark. When doing this copy/paste function manually, only a backspace is required to remove the extra paragraph mark. I've tried adding it a few different ways, but it either does nothing or produces an error. The macro text is provided below.
Sub UpdateDocumentFooters()
Application.ScreenUpdating = False
Dim strFolder As String, strFile As String
Dim wdDocTgt As Document, wdDocSrc As Document
Dim Sctn As Section, HdFt As HeaderFooter
strFolder = GetFolder
If strFolder = "" Then Exit Sub
Set wdDocSrc = ActiveDocument
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
If strFolder & "\" & strFile <> wdDocSrc.FullName Then
Set wdDocTgt = Documents.Open(FileName:=strFolder & "\" & strFile, _
AddToRecentFiles:=False, Visible:=False)
With wdDocTgt
For Each Sctn In .Sections
'For footers
For Each HdFt In Sctn.Footers
With HdFt
If .Exists Then
If Sctn.Index = 1 Then
wdDocSrc.Sections.First.Footers(HdFt.Index).Range.Copy
.Range.PasteAndFormat wdFormatOriginalFormatting
.Range.Characters.Last = vbNullString
ElseIf .LinkToPrevious = False Then
wdDocSrc.Sections.First.Footers(HdFt.Index).Range.Copy
.Range.PasteAndFormat wdFormatOriginalFormatting
.Range.Characters.Last = vbNullString
End If
End If
End With
Next
Next
.Close SaveChanges:=True
End With
End If
strFile = Dir()
Wend
Set wdDocSrc = Nothing: Set wdDocTgt = Nothing
Application.ScreenUpdating = True
End Sub
Function GetFolder() As String
Dim oFolder As Object
GetFolder = ""
Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path
Set oFolder = Nothing
End Function
Have reviewed the responses below, but no improvement yet.
I start with this:
Footer to Replace
And want to get this:
Desired Footer
But end up with this:
Resulting Footer
I have a question about bookmarks. I made a macro that deletes all the bookmarks in a Word document and adds a new bookmark:
Sub AddBookmarkInCurrentFile()
'
' Deletes all the bookmarks in an already opened file
' and add one new bookmark in the file
'
' Deletes al current bookmarks
For Each bkm In ActiveDocument.Bookmarks
bkm.Delete
Next bkm
' Put Cursor add the beginning of the file and adds the bookmark
Selection.HomeKey Unit:=wdStory
ActiveDocument.Bookmarks.Add Name:="testBookmarkAdd"
MsgBox "Finished"
End Sub
When I run this it works fine.
Because I have to do this for more then 100 documents and save the *.doc as .docx I made a new version of the macro. Everything works accept the adding of the new bookmark. What is wrong in the code below?
Sub AddBookmarkInAllOpenedFiles()
' Opens all word files in a directory and deletes current bookmarks
' and adds one bookmark and saves the file to a docx file
Dim sSourcePath As String
Dim sTargetPath As String
Dim sDocName As String
Dim docCurDoc As Document
Dim sNewDocName As String
Dim sOrigName As String
Dim intPos As Integer
' Looking in this path
sSourcePath = "H:\Mijn Documenten\test\"
sTargetPath = "H:\Mijn Documenten\test\Converted\"
' Look for first DOC file
sDocName = Dir(sSourcePath & "*.doc")
Do While sDocName <> ""
' Repeat as long as there are source files
'Only work on files where right-most characters are ".doc"
If Right(sDocName, 4) = ".doc" Then
' Open file
Set docCurDoc = Documents.Open(FileName:=sSourcePath & sDocName)
' Deletes all the bookmarks
For Each bkm In ActiveDocument.Bookmarks
bkm.Delete
Next bkm
' Put Cursor add the beginning of the file and adds the bookmark
Selection.HomeKey Unit:=wdStory
ActiveDocument.Bookmarks.Add Name:="testBookmarkAdd"
'Saves the document as a docx
sNewDocName = Replace(sDocName, ".doc", ".docx")
With docCurDoc
.SaveAs FileName:=sTargetPath & sNewDocName, _
FileFormat:=wdFormatDocumentDefault
.Close SaveChanges:=wdDoNotSaveChanges
End With
End If
' Get next source file name
sDocName = Dir
Loop
MsgBox "Finished"
End Sub
Try:
Sub BookmarkAllFilesInFolder()
' Opens all word files in a directory and deletes current bookmarks
' and adds one bookmark and saves the file to a docx file
Dim sSourcePath As String, sTargetPath As String
Dim sDocName As String, docCurDoc As Document
' Looking in this path
sSourcePath = "H:\Mijn Documenten\test\"
sTargetPath = sSourcePath & "Converted\"
' Look for first DOC file
sDocName = Dir(sSourcePath & "*.doc")
' Repeat as long as there are source files
Do While sDocName <> ""
' Only open .doc files"
If Right(sDocName, 4) = ".doc" Then
' Open file
Set docCurDoc = Documents.Open(FileName:=sSourcePath & sDocName, AddToRecentFiles:=False, Visible:=False)
With docCurDoc
'Delete all existing bookmarks
While .Bookmarks.Count > 0
.Bookmarks(1).Delete
Wend
'Add our bookmark
.Bookmarks.Add Name:="TestBookmark", Range:=.Range(0, 0)
'Save the file in .docx format to the output folder
.SaveAs2 FileName:=sTargetPath & sDocName & "x", _
FileFormat:=wdFormatDocumentDefault, AddToRecentFiles:=False
.Close SaveChanges:=wdDoNotSaveChanges
End With
End If
' Get next source file name
sDocName = Dir
Loop
Set docCurDoc = Nothing
MsgBox "Finished"
End Sub
I have a plenty of word documents in a folder to which I want to apply style which I have customized.
This is my VBA-code. I want the VBA as like to go to the particular folder and apply the customized style to all the word documents. Any ideas?
Sub styleapply()
'
' styleapply Macro
'
'
Selection.WholeStory
ActiveDocument.UpdateStyles
'WordBasic.ApplyQFSetTemplate
Selection.Style = ActiveDocument.Styles("sam'style")
End Sub
This should get you most of the way there:
Sub OpenWordFolder()
Dim fd As FileDialog
Dim doc As Document
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
fd.AllowMultiSelect = True
fd.Show
For Each folderItem In fd.SelectedItems
fileItem = Dir(folderItem & "\" & "*.docx")
While fileItem <> ""
Set doc = Documents.Open(FileName:=folderItem & "\" & fileItem)
Selection.WholeStory
Selection.Style = ActiveDocument.Styles("sam'style")
doc.Close SaveChanges:=True
fileItem = Dir
Wend
Next
End Sub
Note that I'm unsure if the ActiveDocument will have the custom style you've created - you may need to set the original document with the custom style to a Document object and then use that Document object to set the style for each file you've opened.
I'm using the VBA code here to copy all the charts and tables from an excel workbook into a new word document from a template which is pre-formatted with bookmarks (labeled Book1, Book2 etc). Unfortunately i only have a few tables but around 20 charts and if i leave a blank in the summary table for the ranges i get
Run-time error '5101':
Application-defined or object defined error
and it only copies and pastes over the charts and table before the gap.
This is my excel summary table:
Any idea how i can modify the code to prevent this?
Sorry - i'm a complete VBA noob
'You must set a reference to Microsoft Word Object Library from Tools | References
Option Explicit
Sub ExportToWord()
Dim appWrd As Object
Dim objDoc As Object
Dim FilePath As String
Dim FileName As String
Dim x As Long
Dim LastRow As Long
Dim SheetChart As String
Dim SheetRange As String
Dim BookMarkChart As String
Dim BookMarkRange As String
Dim Prompt As String
Dim Title As String
'Turn some stuff off while the macro is running
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
'Assign the Word file path and name to variables
FilePath = ThisWorkbook.Path
FileName = "WorkWithExcel.doc"
'Determine the last row of data for our loop
LastRow = Sheets("Summary").Range("A65536").End(xlUp).Row
'Create an instance of Word for us to use
Set appWrd = CreateObject("Word.Application")
'Open our specified Word file, On Error is used in case the file is not there
On Error Resume Next
Set objDoc = appWrd.Documents.Open(FilePath & "\" & FileName)
On Error Goto 0
'If the file is not found, we need to end the sub and let the user know
If objDoc Is Nothing Then
MsgBox "Unable to find the Word file.", vbCritical, "File Not Found"
appWrd.Quit
Set appWrd = Nothing
Exit Sub
End If
'Copy/Paste Loop starts here
For x = 2 To LastRow
'Use the Status Bar to let the user know what the current progress is
Prompt = "Copying Data: " & x - 1 & " of " & LastRow - 1 & " (" & _
Format((x - 1) / (LastRow - 1), "Percent") & ")"
Application.StatusBar = Prompt
'Assign the worksheet names and bookmark names to a variable
'Use With to group these lines together
With ThisWorkbook.Sheets("Summary")
SheetChart = .Range("A" & x).Text
SheetRange = .Range("B" & x).Text
BookMarkChart = .Range("C" & x).Text
BookMarkRange = .Range("D" & x).Text
End With
'Tell Word to goto the bookmark assigned to the variable BookMarkRange
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkRange
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetRange).UsedRange.Copy
'Paste into Word
appWrd.Selection.Paste
'Tell Word to goto the bookmark assigned to the variable BookMarkChart
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkChart
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetChart).ChartObjects(1).Copy
'Paste into Word
appWrd.Selection.Paste
Next
'Turn everything back on
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
Application.StatusBar = False
'Let the user know the procedure is now complete
Prompt = "The procedure is now completed." & vbCrLf & vbCrLf & "www.VBAExpress.com"
Title = "Procedure Completion"
MsgBox Prompt, vbOKOnly + vbInformation, Title
'Make our Word session visible
appWrd.Visible = True
'Clean up
Set appWrd = Nothing
Set objDoc = Nothing
End Sub
full working code is below. I've modified the code so it pastes charts as enhanched metafiles because that's what my boss wants.
'You must set a reference to Microsoft Word Object Library from Tools | References
Option Explicit
Sub ExportToWord()
Dim appWrd As Object
Dim objDoc As Object
Dim FilePath As String
Dim FileName As String
Dim x As Long
Dim LastRow As Long
Dim SheetChart As String
Dim SheetRange As String
Dim BookMarkChart As String
Dim BookMarkRange As String
Dim Prompt As String
Dim Title As String
'Turn some stuff off while the macro is running
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
'Assign the Word file path and name to variables
FilePath = ThisWorkbook.Path
FileName = "WorkWithExcel.doc"
'Determine the last row of data for our loop
LastRow = Sheets("Summary").Range("A" & Rows.Count).End(xlUp).Row
'Create an instance of Word for us to use
Set appWrd = CreateObject("Word.Application")
'Open our specified Word file, On Error is used in case the file is not there
On Error Resume Next
Set objDoc = appWrd.Documents.Open(FilePath & "\" & FileName)
On Error GoTo 0
'If the file is not found, we need to end the sub and let the user know
If objDoc Is Nothing Then
MsgBox "Unable to find the Word file.", vbCritical, "File Not Found"
appWrd.Quit
Set appWrd = Nothing
Exit Sub
End If
'Copy/Paste Loop starts here
For x = 2 To LastRow
'Use the Status Bar to let the user know what the current progress is
Prompt = "Copying Data: " & x - 1 & " of " & LastRow - 1 & " (" & _
Format((x - 1) / (LastRow - 1), "Percent") & ")"
Application.StatusBar = Prompt
'Assign the worksheet names and bookmark names to a variable
'Use With to group these lines together
With ThisWorkbook.Sheets("Summary")
SheetChart = .Range("A" & x).Text
SheetRange = .Range("B" & x).Text
BookMarkChart = .Range("C" & x).Text
BookMarkRange = .Range("D" & x).Text
End With
If Len(BookMarkRange) > 0 Then
'Tell Word to goto the bookmark assigned to the variable BookMarkRange
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkRange
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetRange).UsedRange.Copy
'Paste into Word
appWrd.Selection.Paste
End If
If Len(BookMarkChart) > 0 Then
'Tell Word to goto the bookmark assigned to the variable BookMarkChart
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkChart
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetChart).ChartObjects(1).Copy
'Paste into Word
'appWrd.Selection.PasteSpecial ppPasteEnhancedMetafile
appWrd.Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
Placement:=wdInLine, DisplayAsIcon:=False
End If
Next
'Turn everything back on
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
Application.StatusBar = False
'Let the user know the procedure is now complete
Prompt = "The procedure is now completed." & vbCrLf & vbCrLf & "www.VBAExpress.com"
Title = "Procedure Completion"
MsgBox Prompt, vbOKOnly + vbInformation, Title
'Make our Word session visible
appWrd.Visible = True
'Clean up
Set appWrd = Nothing
Set objDoc = Nothing
End Sub
There are multiple problems with this code, including the fact that if you had more ranges than charts it would only copy as many ranges as there was charts.
But to quickly fix your problem, replace
'Tell Word to goto the bookmark assigned to the variable BookMarkRange
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkRange
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetRange).UsedRange.Copy
'Paste into Word
appWrd.Selection.Paste
'Tell Word to goto the bookmark assigned to the variable BookMarkChart
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkChart
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetChart).ChartObjects(1).Copy
'Paste into Word
appWrd.Selection.Paste
with
if len (BookMarkRange) > 0 then
'Tell Word to goto the bookmark assigned to the variable BookMarkRange
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkRange
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetRange).UsedRange.Copy
'Paste into Word
appWrd.Selection.Paste
end if
if len(BookMarkChart) > 0 then
'Tell Word to goto the bookmark assigned to the variable BookMarkChart
appWrd.Selection.Goto What:=wdGoToBookmark, Name:=BookMarkChart
'Copy the data from Thisworkbook
ThisWorkbook.Sheets(SheetChart).ChartObjects(1).Copy
'Paste into Word
appWrd.Selection.Paste
end if