How macro to change excel source file path - vba

I'm Very New to Macro and VB. I recorded one macro in Word, below is some portion of the code.
ActiveDocument.MailMerge.OpenDataSource Name:= _
"Choosen/Folder/Path/file.xlsx", ConfirmConversions:= _
False, ReadOnly:=False, LinkToSource:=True, AddToRecentFiles:=False, _
PasswordDocument:="", PasswordTemplate:="", WritePasswordDocument:="", _
WritePasswordTemplate:="", Revert:=False, Format:=wdOpenFormatAuto, _
Connection:= _
"User ID=Admin;Data Source=Choosen/Folder/Path/file.xlsx;Mode=Read;Extended Properties=""HDR=YES;IMEX=1;"";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Engine Type=35;Jet OLEDB:Database L" _
, SQLStatement:="SELECT * FROM `Sheet1$`", SQLStatement1:="", SubType:= _
wdMergeSubTypeAccess
How can I allow user to choose DataSource every time?
I tried the following:
Public Function ChooseFolder()
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFilePicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = Replace(.SelectedItems(1), "\", "\\")
End With
NextCode:
ChooseFolder = sItem
Set fldr = Nothing
End Function
Sub .....
..
Dim fldr As String
fldr = ChooseFolder()
ActiveDocument.MailMerge.OpenDataSource Name:= _
fldr, ConfirmConversions:= _
....
End Sub
But have the following error:

There's a Word dialog box specifically for opening a mailmerge data source.
e.g. at its simplest,
Sub openmmds1()
Dialogs(WdWordDialog.wdDialogMailMergeOpenDataSource).Show
End Sub
although some people say the "correct" way to use these dialogs is as follows:
Sub openmmds2()
Dim dlg As Word.Dialog
Set dlg = Dialogs(WdWordDialog.wdDialogMailMergeOpenDataSource)
dlg.Show
Set dlg = Nothing
End Sub
and you may find that closing any existing data source first avoids some problems. In modern versions of Word on both Windows and Mac you should be able to do that this way:
ActiveDocument.MailMerge.DataSource.Close
but in older versions there is no .Close method and you have to remove all the MailMerge info using, e.g.
ActiveDocument.MailMerge.MainDocumentType = WdMailMergeMainDocType.wdNotAMergeDocument

Related

Ask where to store the file before saving a file as .pdf

I have the following code that enable to print a certain selection to a .pdf file.
Sub printIt()
Dim input_value As String
Dim file_name As String
Dim Time As Date
input_value = InputBox("Please state the name of the sheet")
Time = TimeValue("9:20:01")
MsgBox (Time)
file_name = "C:\Users\Marc\Desktop\" + input_value + ".pdf"
Worksheets("end_screen").PageSetup.PrintArea = "$B$2:$D$27"
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
file_name, Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
True
End Sub
This all works fine. However, as I would also like to implement it on other computer I would like the function to ask where to save the file before saving it.
Could anybody tell me whether it's possible to change code below so it can pop a file screen so i decide where to save file?
You need the GetSaveAsFilename method of the Application object. It will display a Save As dialog and return a string. You use it like this:
Option Explicit
Sub Test()
Dim strOutFile As String
strOutFile = Application.GetSaveAsFilename( _
InitialFileName:="export", _
FileFilter:="PDF Files (*.pdf), *.pdf", _
Title:="Save PDF as")
'strOutFile will be False if user hit Escape etc
If CBool(strOutFile) = False Then
' user exits
Exit Sub
Else
' do save
'...
End If
End Sub
In this example where the '... comment is - you would include your line for ActiveSheet.ExportAsFixedFormat ...
Consider:
Sub printIt()
Dim input_value As String
Dim file_name As String
Dim Time As Date, fldr As String
input_value = InputBox("Please state the name of the sheet")
Time = TimeValue("9:20:01")
MsgBox (Time)
fldr = GetFolder() & "\"
file_name = fldr & input_value & ".pdf"
Worksheets("end_screen").PageSetup.PrintArea = "$B$2:$D$27"
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
file_name, Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
True
End Sub
Function GetFolder() As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
Try this:
Sub printIt()
Dim input_value As String
Dim file_name As String
Dim Time As Date
input_value = InputBox("Please state the name of the sheet")
Time = TimeValue("9:20:01")
MsgBox (Time)
file_name = "C:\Users\Marc\Desktop\" + input_value + ".pdf"
myFile = Application.GetSaveAsFilename _
(InitialFileName:=file_name, _
FileFilter:="PDF Files (*.pdf), *.pdf", _
Title:="Select Folder and FileName to save")
Worksheets("end_screen").PageSetup.PrintArea = "$B$2:$D$27"
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
myFile, Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
True
End Sub
Added one line in your code.

Mailmerge from Excel using Word template VBA

I have created a Userform where you can flag records as "In Progress", "Completed", and "Not Completed".
This will reflect on the sheet as below:
Records marked as "In Progress" will have the letter "P" in the status column.
Records marked as "Completed" will have the letter "Y" in the status column.
Records marked as "Not Completed" will have the letter "N" in the status column.
DataSheet http://im39.gulfup.com/VZVxr.png!
I want to run a mailmerge using the below buttons on the user form:
Userform http://im39.gulfup.com/98isU.png!
I have created this work template for the fields.
Document http://im39.gulfup.com/4WMLh.png!
This word template file called "MyTemplate" will be in the same directory as the excel file.
I am trying to figure out how:
(1) Select recepients by filtering the "Status" column, so if the user pressed the first button, it will run the mail merge only for records with "P" in the status column.
(2) Run mailmerge without displaying Microsoft Word and only displaying the "Save As" dialog where the user can select where to save the file.
(3) This file should be saved in PDF format.
I am running Office 2013 and so far I have the code in bits and pieces and had no luck when trying to run it.
I have uploaded the data I am trying to work on:
MyBook: https://db.tt/0rLUZGC0
MyTemplate: https://db.tt/qPuoZ0D6
Any help will be highly appreciated.
Thanks.
(1) What I use is the WHERE clause (on the OpenDataSource, you probably don't need all those options)
' setup the SQL
Dim sSQLModel As String, sSQLWhere As String
sSQLModel = " Where ( AssignLtrType = 'T1' or AssignLtrType = 'T2' ) ;"
' replace the appropriate value(s)
sSQLWhere = sSQLModel ' never replace in the model
sSQLWhere = Replace(sSQLWhere, "T1", mydatavariable)
' open the MERGE
doc.MailMerge.OpenDataSource Name:=sIn, _
ConfirmConversions:=False, readOnly:=False, LinkToSource:=True, _
AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", _
WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, _
Format:=wdOpenFormatAuto, Connection:= _
"Provider=Microsoft.Jet.OLEDB.4.0;Password="""";" & _
"User ID=Admin;" & _
"Data Source=" & sXLSPathFile & ";" & _
"Mode=Read;Extended Properties=" & _
"HDR=YES;IMEX=1;"";Jet OLEDB:System database="""";" _
, SQLStatement:="SELECT * FROM `Detail$`", _
SQLStatement1:=sSQLWhere, _
SubType:=wdMergeSubTypeAccess
' do the MERGE
With doc.MailMerge
.Destination = wdSendToPrinter
.SuppressBlankLines = True
With .DataSource
.FirstRecord = wdDefaultFirstRecord
.LastRecord = wdDefaultLastRecord
End With
.Execute Pause:=False
End With
(2) Prior to the above, make the doc Visible (or Invisible)
' setup the template document
Dim doc As Word.Document
Set doc = wrdApp.Documents.Add(sPathFileTemplate)
wrdApp.Visible = True ' you can say False
(3) I have Adobe PDF as a Printer (the registry routines were from the web--Google them). Put this prior to OpenDataSource.
' Get current default printer.
SetDefaultPrinter "Adobe PDF"
'Create the Registry Key where Acrobat looks for a file name
CreateNewRegistryKey HKEY_CURRENT_USER, _
"Software\Adobe\Acrobat Distiller\PrinterJobControl"
'Put the output filename where Acrobat could find it
SetRegistryValue HKEY_CURRENT_USER, _
"Software\Adobe\Acrobat Distiller\PrinterJobControl", _
wrdApp.Application.Path & "\WINWORD.EXE", sPathFilePDF
In the SQL, change the tab name from Detail$ to yourTab$ (needs trailing $)
added later--
Dim sIn As String
sIn = SelectAFile(sInitial:=sDriveSAO, sTitle:=" XLS file")
If (sIn = "" Or sIn = "False") Then Exit Sub
and Google for SelectAFile
added 1/22 aft
' ============= added ===========
Dim xls As Excel.Application ' for me, because I am running in MSAccess as mdb
Set xls = New Excel.Application
Dim wrdApp As Word.Application ' for you, to have WORD running
Set wrdApp = New Word.Application
Dim sPathFileTemplate As String
sPathFileTemplate = xls.GetOpenFilename(" docx file,*.docx", , "Template file")
' ============= added ===========
' changed you only need one variable
sSQLModel = " Where ( Status = 'T1' ) ;"
' changed replace, possibly with some screen value
sSQLWhere = Replace(sSQLWhere, "T1", "P")
' changed because your tab is named Sheet1
, SQLStatement:="SELECT * FROM `Sheet1$`", _
' ============= added ===========
doc.Close False
Set doc = Nothing
wrdApp.Quit False
Set wrdApp = Nothing
' ============= added ===========
OK so with a lot of help from #donPablo I finally got a working code which does exactly what I want.
BTW the "Status" in sSQLModel = " Where ( Status = 'T1' ) ;" can be change to any other column heading, but in my case I am filtering based on a value in the column F (Status).
The "P" in sSQLWhere = Replace(sSQLWhere, "T1", "P") can also be change to the value been filtered on, but in my case I want all the records containing "P" in the "Status" column.
The "Sheet1" in , SQLStatement:="SELECT * FROMSheet1$", _ can be changed to the name of the sheet containing the source data for the merge. (Don't forget to include the $ sign at the end of the sheet name.
Before proceeding make sure to load the Microsoft Word Object Library (VBA - Tools - References)
And here is the working code:
Private Sub CommandButton1_Click()
Dim xls As Excel.Application
Set xls = New Excel.Application
Dim wrdApp As Word.Application
Set wrdApp = New Word.Application
Dim sPathFileTemplate As String
sPathFileTemplate = ThisWorkbook.Path & "\MyTemplate.docx" 'This gets the file called MyTemplate from the same directory
'in which this excel file is running from
' setup the template document
Dim doc As Word.Document
Set doc = wrdApp.Documents.Add(sPathFileTemplate)
wrdApp.Visible = False ' Make MS Word Invisible
Dim sIn As String
sIn = ThisWorkbook.FullName 'This Workbook is set the merge data source
' setup the SQL
Dim sSQLModel As String, sSQLWhere As String
sSQLModel = " Where ( Status = 'T1' ) ;"
' replace the appropriate value(s)
sSQLWhere = sSQLModel
sSQLWhere = Replace(sSQLWhere, "T1", "P")
' open the MERGE
doc.MailMerge.OpenDataSource Name:=sIn, _
ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", _
WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, _
Format:=wdOpenFormatAuto, Connection:= _
"Provider=Microsoft.Jet.OLEDB.4.0;Password="""";" & _
"User ID=Admin;" & _
"Data Source=" & sXLSPathFile & ";" & _
"Mode=Read;Extended Properties=" & _
"HDR=YES;IMEX=1;"";Jet OLEDB:System database="""";" _
, SQLStatement:="SELECT * FROM `Sheet1$`", _
SQLStatement1:=sSQLWhere, _
SubType:=wdMergeSubTypeAccess
' do the MERGE
With doc.MailMerge
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .DataSource
.FirstRecord = wdDefaultFirstRecord
.LastRecord = wdDefaultLastRecord
End With
.Execute Pause:=False
End With
'If you want you can delete this part and proceed to diretly define the
'filename and path below in "OutputFileName"
On Error Resume Next
Dim FileSelected As String
FileSelected = Application.GetSaveAsFilename(InitialFileName:="Export", _
FileFilter:="PDF Files (*.pdf), *.pdf", _
Title:="Save PDF as")
If Not FileSelected <> "False" Then
MsgBox "You have cancelled"
doc.Close False
Set doc = Nothing
wrdApp.Quit False
Set wrdApp = Nothing
Exit Sub
End If
If FileSelected <> "False" Then
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
wrdApp.Application.Options.SaveInterval = False
'Saves Documents as PDF and does not open after saving, you can change OpenAfterExport:=False to True
wrdApp.Application.ActiveDocument.ExportAsFixedFormat OutputFileName:=FileSelected, _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:=wdExportOptimizeForPrint, _
Range:=wdExportAllDocument, FROM:=1, To:=1, Item:=wdExportDocumentContent, IncludeDocProps:=True, _
KeepIRM:=True, CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
doc.Close False
Set doc = Nothing
wrdApp.Quit False
Set wrdApp = Nothing
MsgBox "Done"
End If ' this EndIf pretains to the SaveAs code above
End Sub
I cannot stress enough how much help was #donPablo, thanks again, you just made my weekend and I am selecting your answer as accepted :)

word document opens minimized after mail merge using msaccess

I have the following code to perform a mail merge using VBA, after the mail merge is performed the word document opens minimized, is there a way to have the document opened as normal(maximized)?
Dim DocName As String
Echo -1, "Merge in progress..."
Dim templateName As String, tempRoot As String
tempRoot = "c:\temp\mailmerge"
templateName = tempRoot & "CertificateRSZDutch.dotx"
Dim objDoc As Word.Document
Dim objWord As New Word.Application
Set objDoc = objWord.Documents.Open(templateName)
objWord.Visible = True
DoCmd.TransferText acExportDelim, , "Mailmerge_CertificateRSZDutch", "Q:\jas\hr\mailmerge\LES\CertificateRSZDutch.txt", True
objDoc.MailMerge.OpenDataSource Name:= _
tempRoot & "CertificateRSZDutch.txt", ConfirmConversions:=False, ReadOnly _
:=False, LinkToSource:=True, AddToRecentFiles:=False, PasswordDocument:= _
"", PasswordTemplate:="", WritePasswordDocument:="", _
WritePasswordTemplate:="", Revert:=False, Format:=wdOpenFormatAuto, _
Connection:="", SQLStatement:="", SQLStatement1:="", SubType:= _
wdMergeSubTypeOther
objDoc.MailMerge.Execute
objDoc.Close False
objWord.ActiveDocument.SaveAs tempRoot & "CertificateRSZ.docx"
Set objDoc = objWord.Documents.Open(Filename:=tempRoot & "CertificateRSZ.docx")
Set objWord = Nothing
Set objDoc = Nothing
Thanks
Put the following code in your program before opening the word document
Dim shell As New shell
shell.MinimizeAll
this will minimize all the opened applications windows
and put this code after opening the word document.
objWord.Application.WindowState = wdWindowStateMaximize
this will maximize the word document to be opened.

Loop through all Word Files in Directory

I have the following code:
Sub WordtoTxtwLB()
'
' WordtoTxtwLB Macro
'
'
Dim fileName As String
myFileName = ActiveDocument.Name
ActiveDocument.SaveAs2 fileName:= _
"\\FILE\" & myFileName & ".txt", FileFormat:= _
wdFormatText, LockComments:=False, Password:="", AddToRecentFiles:=True, _
WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _
SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _
False, Encoding:=1252, InsertLineBreaks:=True, AllowSubstitutions:=False, _
LineEnding:=wdCRLF, CompatibilityMode:=0
End Sub
I want to loop this sub through all of the word (.doc) files in a directory. I have the following code:
Sub LoopDirectory()
vDirectory = "C:\programs2\test"
vFile = Dir(vDirectory & "\" & "*.*")
Do While vFile <> ""
Documents.Open fileName:=vDirectory & "\" & vFile
ActiveDocument.WordtoTxtwLB
vFile = Dir
Loop
End Sub
But it is not working. How do I get this to work either by altering the current code or using new code?
You don't actually need the WordtoTxtwLB Macro. You can combine both the codes. see this example
Sub LoopDirectory()
Dim vDirectory As String
Dim oDoc As Document
vDirectory = "C:\programs2\test\"
vFile = Dir(vDirectory & "*.*")
Do While vFile <> ""
Set oDoc = Documents.Open(fileName:=vDirectory & vFile)
ActiveDocument.SaveAs2 fileName:="\\FILE\" & oDoc.Name & ".txt", _
FileFormat:=wdFormatText, _
LockComments:=False, _
Password:="", _
AddToRecentFiles:=True, _
WritePassword:="", _
ReadOnlyRecommended:=False, _
EmbedTrueTypeFonts:=False, _
SaveNativePictureFormat:=False, _
SaveFormsData:=False, _
SaveAsAOCELetter:=False, _
Encoding:=1252, _
InsertLineBreaks:=True, _
AllowSubstitutions:=False, _
LineEnding:=wdCRLF, _
CompatibilityMode:=0
oDoc.Close SaveChanges:=False
vFile = Dir
Loop
End Sub
BTW, are you sure you want to use the *.* wildcard? What if there are Autocad files in the folder? Also ActiveDocument.Name will give you the file name with the Extension.
To edit all the word documents in a directory I built this simple subroutine.
The subRoutine loops through the directory and
opens each *.doc file it finds. Then on the open document file it calls
the second subRoutine. After the second subRoutine is finished the document
is saved and then closed.
Sub DoVBRoutineNow()
Dim file
Dim path As String
path = "C:\Documents and Settings\userName\My Documents\myWorkFolder\"
file = Dir(path & "*.doc")
Do While file <> ""
Documents.Open FileName:=path & file
Call secondSubRoutine
ActiveDocument.Save
ActiveDocument.Close
file = Dir()
Loop
End Sub
~~~~~~
Here's my solution. I think it's easy to understand and straight forward for newbies like me that I will post my code here. Because I searched around and the codes I saw were kind of complicated. Let's go.
Sub loopDocxs()
Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim mySource As Object
Set obj = CreateObject("Scripting.FileSystemObject")
Set mySource = obj.GetFolder("D:\docxs\")
For Each file In mySource.Files 'loop through the directory
If Len(file.Name) > 0 And InStr(1, file.Name, "$") = 0 Then '$ is temp file mask
Set wApp = CreateObject("Word.Application")
wApp.Visible = True
'Word.Application doesn't recognize file here event if it's a word file.
'fortunately we have the file name which we can use.
Set wDoc = wApp.Documents.Open(mySource & "\" & file.Name, , ReadOnly)
'Do your things here which will be a lot of code
wApp.Quit
Set wApp = Nothing
End If
Next file

getting save as file name in word

In the code below the file name is hard coded, but I want the user to be able to pick it.
I was reading about GetSaveAsFilename but I get an error when using it: "method or member not found".
fileSaveName = Application.GetSaveAsFilename _
(fileFilter:="Excel Files (*.txt), *.txt")
This is written for Word 2010. Am I wrong in thinking GetSaveAsFilename is available in word VBA?
Sub Macro3()
'
' Macro3 Macro
'
'
ActiveDocument.SaveAs2 FileName:="Questionnaire01-05-20122.txt", _
FileFormat:=wdFormatText, LockComments:=False, Password:="", _
AddToRecentFiles:=True, WritePassword:="", ReadOnlyRecommended:=False, _
EmbedTrueTypeFonts:=False, SaveNativePictureFormat:=False, SaveFormsData _
:=True, SaveAsAOCELetter:=False, Encoding:=1252, InsertLineBreaks:=False, _
AllowSubstitutions:=False, LineEnding:=wdCRLF, CompatibilityMode:=0
End Sub
I didn't realize that Word doesn't have GetSaveAsFileName or GetOpenFileName methods (which Excel has). But it doesn't. Instead you can try the SaveAs FileDialog (2003, 2007, 2010):
Sub ShowSaveAsDialog()
Dim dlgSaveAs As FileDialog
Set dlgSaveAs = Application.FileDialog(FileDialogType:=msoFileDialogSaveAs)
dlgSaveAs.Show
End Sub
You can provide a default path including filename like so to the dialog, ie
Sub SaveName()
Dim strFileName As String
Dim StrPath As String
'provide default filename
StrPath = "c:\temp\test.docx"
With Dialogs(wdDialogFileSaveAs)
.Name = StrPath
If .Display <> 0 Then
strFileName = .Name
Else
strFileName = "User Cancelled"
End If
End With
MsgBox strFileName
End Sub
Dim strFilePath, strFileName
strFilePath = "C:\Users\Public\Documents\"
strFileName = "put-filename-here.docx"
With Dialogs(wdDialogFileSaveAs)
.Name = strFilePath & strFileName
.Show
End With