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
Related
Good day guys, I created a form in MS Access and I am trying to write some codes that prevents duplication of files when it is added to a listbox. As it is now, if I select the folder of interest and click on Display button, it re-adds the same files already in the listbox. Please advise. Below is my code so far:
Public Sub btn_folderimp_Click()
' Displays Excel SpreadSheets In Selected Folder
Dim myFSO As New FileSystemObject
Dim MyFile As File
Dim mFolder As Folder
' Dim lbx As ListBox
'Checks If No Folder Was Selected
If Nz(Me.txt_folderpath, "") = "" Then
Beep
MsgBox "No Folder Selected!"
Exit Sub
End If
'Checks If Folder Exists, If Yes, it displays a list of spreadsheets in the Folder
If myFSO.FolderExists(Nz(Me.txt_folderpath, "")) Then
Set mFolder = myFSO.GetFolder(Me.txt_folderpath)
For Each MyFile In mFolder.Files
If (myFSO.GetExtensionName(MyFile.Name) = "xlsx") Then 'Or (myFSO.GetExtensionName(MyFile.Name) = "xls")
Me.lbx_show.AddItem MyFile.Path
' Debug.Print MyFile
End If
Next MyFile
' Checks if there are excel spreadsheets in the folder
If Dir(Me.txt_folderpath & "*.xlsx") = "" Then
Beep
MsgBox "No Excel Spreadsheet Found!"
End If
Else
Beep
MsgBox "Folder Does Not Exist"
End If
End Sub
I guess you want to add for each directory you choose in the textbox the files to the listbox and if you run the code in your post a second time it should not add the same file a second time. You can do that by using a dictionary and adding the filenames to the dictionary
Option Compare Database
Option Explicit
' Dictionary for the filenames
Dim dict As New Scripting.Dictionary
Public Sub btn_folderimp_Click()
' Displays Excel SpreadSheets In Selected Folder
Dim myFSO As New FileSystemObject
Dim MyFile As File
Dim mFolder As Folder
' Dim lbx As ListBox
'Checks If No Folder Was Selected
If Nz(Me.txt_folderpath, "") = "" Then
Beep
MsgBox "No Folder Selected!"
Exit Sub
End If
' clear the listbox
lbx_show.RowSource = ""
'Checks If Folder Exists, If Yes, it displays a list of spreadsheets in the Folder
If myFSO.FolderExists(Nz(Me.txt_folderpath, "")) Then
Set mFolder = myFSO.GetFolder(Me.txt_folderpath)
For Each MyFile In mFolder.Files
If (myFSO.GetExtensionName(MyFile.Name) = "xlsx") Then 'Or (myFSO.GetExtensionName(MyFile.Name) = "xls")
' will add a new entry if it not exists
dict(MyFile.Path) = MyFile.Path
'Me.lbx_show.AddItem MyFile.Path
End If
Next MyFile
' add the filenames to the listbox
Dim key As Variant
For Each key In dict.Keys
Me.lbx_show.AddItem key
Next
' Checks if there are excel spreadsheets in the folder
If Dir(Me.txt_folderpath & "*.xlsx") = "" Then
Beep
MsgBox "No Excel Spreadsheet Found!"
End If
Else
Beep
MsgBox "Folder Does Not Exist"
End If
End Sub
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
I have several directories of files (shell, Perl, and SQL) that I use for building books and doing healthchecks of databases. What I am trying to do is take the directory and produce a Word document which should hopefully look like:
(Heading-2) file-name (no spacing) the filecontents (page break).
Repeat until done.
What I'm getting with the code that I mostly reused below is
(Heading 2) file name (Heading 2) next file name (until end of directory)
followed by the contents of the files. What would I need to do to make this work like I want?
Sub DirLoop()
Dim MyFile As String, Sep As String, OFolder As String
Dim wdDoc As Document
Dim txtFiles As Document
' Sets up the variable "MyFile" to be each file in the directory
' This example looks for all the files that have an .xls extension.
' This can be changed to whatever extension is needed. Also, this
' macro searches the current directory. This can be changed to any
' directory.
Sep = Application.PathSeparator
OFolder = openFolder
Sep = "\"
' Look for the right type of file.....
MyFile = Dir(OFolder & Sep & "*.sh")
Set wdDoc = ActiveDocument
' Starts the loop, which will continue until there are no more files
' found.
Do While MyFile <> ""
' Get the directory
Set txtFiles = Documents.Open(FileName:=OFolder & "\" & MyFile, AddToRecentFiles:=False, Visible:=False, ConfirmConversions:=False)
Selection.InsertBreak (wdPageBreak)
Selection.Style = ActiveDocument.Styles("Heading 2")
Selection.TypeText Text:=MyFile & vbCr
Selection.Style = ActiveDocument.Styles("No Spacing")
wdDoc.Range.InsertAfter txtFiles.Range.Text & vbCr
txtFiles.Close SaveChanges:=False
MyFile = Dir()
Loop
End Sub
The problem comes from the way you're mixing the Selection and Range objects. When you open a document the Selection will be at the beginning of the document. Everything you add to the document using Selection will be at the beginning.
wdDocRange.InsertAfter, on the other hand, will insert at the end of the document.
Generlly, accepted practise is to use the Range object rather than the Selection object whenever possible. There's more than one way to write code to do what you intend, my approach would look more like this (untested since I'm on a mobile device):
Sub DirLoop()
Dim MyFile As String, Sep As String, OFolder As String
Dim txtFiles As Word.Document, wdDoc as Word.Document
Dim rngNewEntry as Word.Range
' Sets up the variable "MyFile" to be each file in the directory
' This example looks for all the files that have an .xls extension.
' This can be changed to whatever extension is needed. Also, this
' macro searches the current directory. This can be changed to any
' directory.
Sep = Application.PathSeparator
OFolder = openFolder
Sep = "\"
' Look for the right type of file.....
MyFile = Dir(OFolder & Sep & "*.sh")
Set wdDoc = ActiveDocument
' Starts the loop, which will continue until there are no more files
' found.
Do While MyFile <> ""
' Get the directory
Set txtFiles = Documents.Open(FileName:=OFolder & "\" & MyFile, AddToRecentFiles:=False, Visible:=False, ConfirmConversions:=False)
'Content is a property, so more "correct" for use than Range
Set rngNewEntry = wdDoc.Content
rngNewEntry.Collapse wdCollapseEnd 'Puts focus at end of doc
rngNewEntry.InsertBreak wdPageBreak
rngEntry.Text = My File & vbCr
'Format Range after adding text
rngEntry.Style = wdDoc.Styles("Heading 2")
rngEntry.Collapse wdCollapseEnd
rngEntry.Range.Text = txtFiles.Content.Text & vbCr
rngEntry.Style = wdDoc.Styles("No Spacing")
txtFiles.Close SaveChanges:=False
MyFile = Dir()
Loop
End Sub
I have VBA in Word that opens multiple files from a folder that I select, replaces the logo in the header with a new file that I direct it to, and then saves the files in a different folder.
I have the files saving in a different folder not because I want to, but because they are opening as read-only and I can't figure out how to make that not happen. I have tried everything I can find on here. I'm fine with them saving to a new folder. That's not the issue for me right now.
Right now, this code works, but I have to click "Save" for each document. I would like that to be automated. The code right here is the saveas
End With
With Dialogs(wdDialogFileSaveAs)
.Name = "\\i-worx-san-07.i-worx.ca\wardell$\Redirection\billy.bones\Desktop\Test 3\" & ActiveDocument.Name
.Show
End With
End With
objDocument.SaveAs
objDocument.Close (True)
The following is the complete VBA code. I'm an absolute novice, so go easy. I want to know how to go about making the saveas include the original filename, a new specified folder (can be specified in the code, doesn't have to be specified by the user) and do it without the user having to press "save" a brazillion times. I appreciate your help.
Sub Example1()
'Declaring the required variables
Dim intResult As Integer
Dim strPath As String
Dim arrFiles() As String
Dim i As Integer
'the dialog is displayed to the user
intResult = Application.FileDialog(msoFileDialogFolderPicker).Show
'checks if user has cancled the dialog
If intResult <> 0 Then
'dispaly message box
strPath = Application.FileDialog( _
msoFileDialogFolderPicker).SelectedItems(1)
'Get all the files paths and store it in an array
arrFiles() = GetAllFilePaths(strPath)
'Modifying all the files in the array path
For i = LBound(arrFiles) To UBound(arrFiles)
Call ModifyFile(arrFiles(i))
Next i
End If
End Sub
Private Sub ModifyFile(ByVal strPath As String)
Dim objDocument As Document
Set objDocument = Documents.Open(strPath)
With ActiveDocument.Sections(1)
With ActiveDocument.Sections(1)
.Headers(WdHeaderFooterIndex.wdHeaderFooterPrimary).Range.Delete
End With
Dim imagePath As String
'Please enter the relative path of the image here
imagePath = "C://FILEPATH\FILENAME.jpg"
Set oLogo = .Headers(wdHeaderFooterPrimary).Range.InlineShapes.AddPicture(FileName:=imagePath, LinkToFile:=False, SaveWithDocument:=True)
With oLogo.Range
.ParagraphFormat.Alignment = wdAlignParagraphRight
'Right alignment for logo image
.ParagraphFormat.RightIndent = InchesToPoints(-0.6)
End With
End With
With oLogo
.Height = 320
.Width = 277
With Selection.PageSetup
'Header from Top value
.HeaderDistance = InchesToPoints(0.5)
End With
With Dialogs(wdDialogFileSaveAs)
.Name = "\\i-worx-san-07.i-worx.ca\wardell$\Redirection\billy.bones\Desktop\Test 3\" & ActiveDocument.Name
.Show
End With
End With
objDocument.SaveAs
objDocument.Close (True)
End Sub
Private Function GetAllFilePaths(ByVal strPath As String) _
As String()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
Dim arrOutput() As String
ReDim arrOutput(1 To 1)
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder(strPath)
i = 1
'loops through each file in the directory and
'prints their names and path
For Each objFile In objFolder.Files
ReDim Preserve arrOutput(1 To i)
'print file path
arrOutput(i) = objFile.Path
i = i + 1
Next objFile
GetAllFilePaths = arrOutput
End Function
Remove this line which calls the FileSaveAs dialogue.
With Dialogs(wdDialogFileSaveAs)
.Name = "\\i-worx-san-07.i-worx.ca\wardell$\Redirection\billy.bones\Desktop\Test 3\" & ActiveDocument.Name
.Show
End With
Then modify this line:
objDocument.SaveAs
and include the filepath like this:
objDocument.SaveAs "\\i-worx-san-07.i-worx.ca\wardell$\Redirection\" _
& "billy.bones\Desktop\Test 3\" & ActiveDocument.Name
In newer version of Word, it was change to SaveAs2 but SaveAs still works.
That method takes the file path where you want the file saved as first argument.
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.