I have a code that I found to loop through all of the files in the folder named Loop_AllWordFiles_inFolder and it calls whatever code you put in to execute some kind of action on the word documents in your selected folder. This code will run.
However I run into a problem when I try to have it call upon the code.. I don't know how to make them run together. The code it's calling is called ExtractSubject which is the action I need executed. I found this code online which runs through one file at a time and I'm trying to combine it with the looping files.
I'm new to VBA and I'm not sure how to fix the ExtractSubject code so they can run together. My end goal is to have two columns one with the title of the file and then beside it in the next cell the subject which I will be extracting. Something like this 1
Also I can't open a file without this read-only pop-up2 so if anyone knows how to fix that it would be appreciated but this is not my main concern atm.
Here's the two codes:
Option Explicit
Dim wb As Workbook
Dim path As String
Dim myFile As String
Dim myExtension As String
Dim myFolder As FileDialog
Dim wdApp As Object, wddoc As Object
Sub Loop_AllWordFiles_inFolder()
Set wdApp = CreateObject("Word.Application")
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set myFolder = Application.FileDialog(msoFileDialogFolderPicker)
With myFolder
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
path = .SelectedItems(1) & "\"
End With
' if the User select "Cancel"
NextCode:
path = path
If path = "" Then GoTo ResetSettings
' Target File Extension
myExtension = "*.doc"
' Target Path with Ending Extention
myFile = Dir(path & myExtension)
' Loop through all doc files in folder
Do While myFile <> ""
Set wddoc = wdApp.Documents.Open(fileName:=path & myFile)
' HERE you call your other routine
Call ExtractSubject
wddoc.Close SaveChanges:=False
myFile = Dir
Loop
Application.DisplayAlerts = PrevDispAlerts
MsgBox "Finished scanning all files in Folder " & path
ResetSettings:
' Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Set wdApp = Nothing
End Sub
Sub ExtractSubject()
Dim cDoc As Word.Document
Dim cRng As Word.Range
Dim i As Long
i = 2
Dim wordapp As Object
Set wordapp = CreateObject("word.Application")
wordapp.Documents.Open "c:\code practice\file1"
wdApp.Visible = True
Set wddoc = ActiveDocument
Set cRng = wddoc.Content
With cRng.Find
.Forward = True
.Text = "SUBJECT:"
.Wrap = wdFindStop
.Execute
'Collapses a range or selection to the starting or ending position
cRng.Collapse Word.WdCollapseDirection.wdCollapseEnd
cRng.MoveEndUntil Cset:="JOB"
Cells(i, 1) = cRng
cRng.Collapse Word.WdCollapseDirection.wdCollapseEnd
.Execute
i = i + 1
End With
wordapp.Quit
Set wordapp = Nothing
End Sub
I think something like this should be close to what you're trying to do. Note you don't want all your variables as Globals - anything which needs to be shared between methods can be passed as an argument or returned as a function result.
Sub Loop_AllWordFiles_inFolder()
Const FILE_EXT As String = ".doc"
Dim wb As Workbook
Dim path As String
Dim myFile As String, theSubject As String
Dim wdApp As Object, wdDoc As Object
'Retrieve Target Folder Path From User
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show = -1 Then path = .SelectedItems(1) & "\"
End With
If Len(path) = 0 Then Exit Sub
'path = "C:\Temp\Test\" 'testing only
myFile = Dir(path & "*" & FILE_EXT) ' Target Path with Ending Extention
If Len(myFile) = 0 Then
MsgBox "No Word files found"
Exit Sub
End If
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = True
Optimize '(don't really need this for this code though...)
Do While myFile <> ""
Set wdDoc = wdApp.Documents.Open(Filename:=path & myFile)
theSubject = ExtractSubject(wdDoc) 'extract subject from wdDoc
wdDoc.Close SaveChanges:=False
If Len(theSubject) > 0 Then 'subject was found?
Name path & myFile As path & theSubject & FILE_EXT 'rename the file
Else
'output any problems
Debug.Print "Subject not found in '" & path & myFile & "'"
End If
myFile = Dir 'next file
Loop
wdApp.Quit 'no need to set to Nothing
Optimize False 'turn off speed enhancements
'Application.DisplayAlerts = PrevDispAlerts '?????
MsgBox "Finished scanning all files in Folder " & path
End Sub
'Return text between "SUBJECT:" and "JOB" in word document `wdDoc`
Function ExtractSubject(wdDoc As Word.document) As String
Dim cRng As Word.Range
Set cRng = wdDoc.content
With cRng.Find
.Forward = True
.Text = "SUBJECT:"
.Wrap = wdFindStop
If .Execute() Then
cRng.Collapse Word.WdCollapseDirection.wdCollapseEnd
cRng.MoveEndUntil Cset:="JOB"
ExtractSubject = Trim(cRng.Text)
End If
End With
End Function
'make changes to application settings to optimize macro speed in excel
Sub Optimize(Optional goFast As Boolean = True)
With Application
.ScreenUpdating = Not goFast
.EnableEvents = Not goFast
.Calculation = IIf(goFast, xlCalculationManual, xlCalculationAutomatic)
End With
End Sub
Try taking a look at this and see if it helps. From what I understand you are just trying to call one function in the middle of another.
From the first sentence of that link: "To call a Sub procedure from another procedure, type the name of the procedure and include values for any required arguments."
Related
I am trying to copy all the text, with formatting intact, from each of multiple Word Documents, and paste the text of each into a new cell in a single Excel Spreadsheet, placing the name of the Word Doc in an adjacent cell.
So the file name of "Document 1" goes in cell A1, and the entire contents of "Document 1" goes in cell A2.
We have several hundred Documents that need to be imported onto pages on our new corporate Intranet, and the migration tool provided only works off data in an Excel workbook.
I've checked out a number of threads, videos, and searches and tried to cobble together a couple of different attempts but neither is working. The first, if it did work, may not handle the File Name copy and it seems to run into issues with selecting the destination cell for the copy.
The second seems to be exactly what I want, but I can;t get the Paste into Excel bit working.
The first runs into an issue when it hits the "Range("LastRow").PasteSpecial xlPasteValues" line, saying the range is invalid (I have defined "LastRow" in the Excel Workbook but it doesn't help) :
Sub Copy_Data_From_Multiple_WordFiles()
Dim FolderName As String
Dim FileName As String
Dim NewWordFile As New Word.Application
Dim NewDoc As New Word.Document
Application.DisplayAlerts = False
'Application.ScreenUpdating = False
FolderName = "C:\Test\"
FileName = Dir(FolderName)
'Loop start
Do While FileName ⋖⋗ ""
Set NewDoc = NewWordFile.documents.Open(FolderName & FileName)
NewDoc.Range(0, NewDoc.Range.End).Copy
Range("LastRow").PasteSpecial xlPasteValues
NewDoc.Close SaveChanges:=wdDoNotSaveChanges
NewWordFile.Quit
FileName = Dir()
Loop
End Sub
NB: LastRow is defined in Excel Name Manager as:=OFFSET(CopyDataFromWord!$A$1,COUNTA(CopyDataFromWord!$A:$A),0,1,1)
I have tried a second set of code I got from a post on here, which should be closer to what I'm seeking, but again, won't quite get there. This one fails with a "Run-Time error '424': Object Required" at the line where it should paste into Excel. It doesn't seem to be recognising the Object "objDoc"?
Sub Excel_Word()
Dim WordApp As Object 'New Word.Application
Dim objDoc As Object ' New Word.Document
Dim Range As Object 'Word.Range
Dim WordDoc As String
Dim sPath As String
Dim i As Long
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
sPath = "C:\Users\jdodd\Documents\Cleaned\"
WordDoc = Dir(sPath & "*.docx")
Do While WordDoc <> ""
Set objDoc = WordApp.Documents.Open(sPath & WordDoc)
objDoc.Range.Copy
i = i + 1
ImportPolicyfromWord.Cells(i, 1).Value = objDoc
ImportPolicyfromWord.Cells(i, 2).Value = objDoc.Range.PasteSpecial
WordDoc = Dir()
Loop
WordApp.Quit
'elimina variabili
'Set WordApp = Nothing
'Set objDoc = Nothing
End Sub
Appreciate any advice or help
Try:
Sub GetDocData()
'Note: this code requires a reference to the Word object model.
'See under the VBE's Tools|References.
Application.ScreenUpdating = False
Dim strFolder As String: strFolder = GetFolder: If strFolder = "" Then GoTo ErrExit
Dim wdApp As New Word.Application, wdDoc As Word.Document
Dim strFile As String, WkSht As Worksheet, r As Long
Set WkSht = ActiveSheet
'Disable any auto macros in the documents being processed
wdApp.WordBasic.DisableAutoMacros
'Disable any alerts in the documents being processed
wdApp.DisplayAlerts = wdAlertsNone
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
Set wdDoc = wdApp.Documents.Open(Filename:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With wdDoc
.ConvertNumbersToText (wdNumberAllNumbers)
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchWildcards = True
.Text = "[^12^13^l]{1,}"
.Replacement.Text = "¶"
.Execute Replace:=wdReplaceAll
.Text = "[^t]"
.Replacement.Text = " "
.Execute Replace:=wdReplaceAll
End With
r = WkSht.UsedRange.Cells.SpecialCells(xlCellTypeLastCell).Row
If r > 1 Then r = r + 2
WkSht.Range("A" & r).Value = .Name
.Range.Copy
r = r + 1
WkSht.Paste Destination:=WkSht.Range("A" & r)
.Close SaveChanges:=False
End With
strFile = Dir()
Wend
ErrExit:
wdApp.Quit
WkSht.UsedRange.Replace What:="¶", Replacement:=Chr(10), LookAt:=xlPart, SearchOrder:=xlByRows
Set wdDoc = Nothing: Set wdApp = Nothing: Set WkSht = 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
Simply select the folder to process. As coded, the macro places the document name above the contents, which are all pasted into one cell. If you want the document name on the same row, but beside the contents, change:
r = r + 1
WkSht.Paste Destination:=WkSht.Range("A" & r)
to:
WkSht.Paste Destination:=WkSht.Range("B" & r)
I have a folder with more than 300+ excel files and what I want to open each of the excel files inside the folder and run specific macro that's already stored in each of the excel files, save it, close it and move to the next file.
The macro which is stored in each excel file is connected to other macros inside the workbook, you could call it like a Main macro, so for example If I just tried to run the Main macro, without the macros it's connected, to all the files at the same time, it just wouldn't work, because it is connected to other macros. The code below is what I've done so far, but it doesn't work as intended
Sub run_mYearChange
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Dim wb As Workbook, ws As Worksheet
Dim wPath As String, wQuan As Long, n As Long
Dim fso As Object, folder As Object, subfolder As Object, wFile As Object
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
If .Show <> -1 Then Exit Sub
wPath = .SelectedItems(1)
End With
Set fso = CreateObject("scripting.filesystemobject")
Set folder = fso.getfolder(wPath)
wQuan = folder.Files.Count
n = 1
For Each wFile In folder.Files
Application.StatusBar = "Processing folder : " & folder & ". File : " & n & " of : " & wQuan
If Right(wFile, 4) Like "*xlsm*" Then
Set wb = Workbooks.Open(wFile)
Application.Run "'C:\test2\*.xlsm*'!mYearChange.YearChangeFunction"
wb.Save True
wb.Close True
End If
n = n + 1
Next
Set fso = Nothing: Set folder = Nothing: Set wb = Nothing
MsgBox "End"
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
ActiveSheet.DisplayPageBreaks = True
End Sub
I'm trying to find a solution everywhere and without luck. In this website there also hasn't been anything similar to what I'm asking. I would love all the help I could get, I'm kind of desperate, because nothing works.
Thank you for your help in advance.
You need to adjust the file name for each file opened.
Untested:
Sub run_mYearChange
'snipped....
Dim wPath As String, n As Long, f
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
If .Show <> -1 Then Exit Sub
wPath = .SelectedItems(1)
End With
if right(wPath, 1) <> "\" then wPath = wPath & "\"
f = Dir(wPath & "*.xlsm")
Do While Len(f) > 0
With Workbooks.Open(wPath & f)
Application.Run "'" & .Name & "'!mYearChange.YearChangeFunction"
.Close True 'save
End With
n = n + 1
f = Dir()
Loop
MsgBox "End"
'snipped...
End Sub
I'm trying to unmerge and duplicate data for a folder of xlsx files.
Separately, both macros work as intended. When I combine the macros (through "Call"), it executes but then brings me back to the macro screen. It doesn't give me any errors, but I need to close excel to start over.
I'm guessing the "UnMergeFill" macro isn't playing nice with being opened automatically?
I've tried using "call" and also with just the name of the sub. I've also tried separating the subs into different modules.
Sub AllWorkbooks()
Dim MyFolder As String
Dim MyFile As String
Dim wbk As Workbook
On Error Resume Next
Application.ScreenUpdating = False
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select a folder"
.Show
.AllowMultiSelect = False
If .SelectedItems.Count = 0 Then
MsgBox "You did not select a folder"
Exit Sub
End If
MyFolder = .SelectedItems(1) & "\"
End With
MyFile = Dir(MyFolder)
Do While MyFile <> “”
Set wbk = Workbooks.Open(Filename:=MyFolder & MyFile)
UnMergeFill
wbk.Close savechanges:=True
MyFile = Dir
Loop
Application.ScreenUpdating = True
End Sub
Call Sub UnMergeFill()
Dim cell As Range, joinedCells As Range
For Each cell In ThisWorkbook.ActiveSheet.UsedRange
If cell.MergeCells Then
Set joinedCells = cell.MergeArea
cell.MergeCells = False
joinedCells.Value = cell.Value
End If
Next
End Sub
'''
Try This:
Sub AllWorkbooks()
Dim MyFolder As String
Dim MyFile As String
Dim wbk As Workbook
On Error Resume Next
Application.ScreenUpdating = False
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select a folder"
.Show
.AllowMultiSelect = False
If .SelectedItems.Count = 0 Then
MsgBox "You did not select a folder"
Exit Sub
End If
MyFolder = .SelectedItems(1) & "\"
End With
MyFile = Dir(MyFolder)
Do While MyFile <> “”
Set wbk = Workbooks.Open(Filename:=MyFolder & MyFile)
Call UnMergeFill(wbk)
wbk.Close savechanges:=True
MyFile = Dir
Loop
Application.ScreenUpdating = True
End Sub
Sub UnMergeFill(wb As Workbook)
Dim cell As Range, joinedCells As Range
For Each cell In wb.ActiveSheet.UsedRange
If cell.mergeCells Then
Set joinedCells = cell.MergeArea
cell.mergeCells = False
joinedCells.Value = cell.Value
End If
Next
End Sub
I have around 500 Excel files in one directory. All files have a table on the first sheet (same size). My client wants them all in one word file. I am not an VBA expert an experimented with a code I found online. I got it so far to loop through all files in a directory. It also selects and copies the specific range. But how do I get the transfer to a word file?
Here is what I did:
Sub LoopAllExcelFilesInFolder()
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xls"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'Loop through each xls files dir
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Select range and copy
Range("G10:M25").Select
Selection.Copy
'Save and Close Workbook
wb.Close SaveChanges:=True
'Get next file name
myFile = Dir
DoEvents
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
The code below was sourced from here and adjusted to the one you provided. You should read through the link's explanation as it answers what you asked. The only addition I did to the code below was to put a counter (i) so you can add the tables in the word document as you cycle through them.
Sub LoopAllExcelFilesInFolder()
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim tbl As Excel.Range
Dim WordApp As Word.Application
Dim myDoc As Word.Document
Dim WordTable As Word.Table
Dim i As Long
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xls"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
On Error Resume Next
'Is MS Word already opened?
Set WordApp = GetObject(class:="Word.Application")
'Clear the error between errors
Err.Clear
'If MS Word is not already open then open MS Word
If WordApp Is Nothing Then Set WordApp = CreateObject(class:="Word.Application")
'Handle if the Word Application is not found
If Err.Number = 429 Then
MsgBox "Microsoft Word could not be found, aborting."
GoTo EndRoutine
End If
On Error GoTo 0
'Make MS Word Visible and Active
WordApp.Visible = True
WordApp.Activate
'Create a New Document
Set myDoc = WordApp.Documents.Add
'Loop through each xls files dir
i = 1
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Assign range and Copy
Set tbl = Range("G10:M25")
tbl.Copy
'Paste Table into MS Word
myDoc.Paragraphs(i).Range.PasteExcelTable _
LinkedToExcel:=False, _
WordFormatting:=False, _
RTF:=False
'Autofit Table so it fits inside Word Document
Set WordTable = myDoc.Tables(i)
WordTable.AutoFitBehavior (wdAutoFitWindow)
i = i + 1 'Incrementing paragraph and table number
'Save and Close Workbook
wb.Close SaveChanges:=True
'Get next file name
myFile = Dir
DoEvents
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Hi I'm facing a problem on dealing with converting Excel spreadsheets to txt files.
What I want to do is to create a Macro which can takes all the xls files in one folder and convert them to txt files.
The code currently working on
Sub Combined()
Application.DisplayAlerts = False
Const fPath As String = "C:\Users\A9993846\Desktop\"
Dim sh As Worksheet
Dim sName As String
Dim inputString As String
With Application
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
End With
sName = Dir(fPath & "*.xls*")
Do Until sName = ""
With GetObject(fPath & sName)
For Each sh In .Worksheets
With sh
.SaveAs Replace(sName, ".xls*", ".txt"), 42 'UPDATE:
End With
Next sh
.Close True
End With
sName = Dir
Loop
With Application
.Calculation = xlAutomatic
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
But It's not working as expected, I have 0 knowledge on VB. Anyone willing to give a hand?
The code below converts all Excel Workbooks (tests file extension for "xlsx") in a given folder into CSV files. File names will be [workbookname][sheetname].csv, ie "foo.xlsx" will get "foo.xlsxSheet1.scv", "foo.xlsxSheet2.scv", etc. In order to run it, create a plain text file, rename it to .vbs and copy-paste the code below. Change path info and run it.
Option Explicit
Dim oFSO, myFolder
Dim xlCSV
myFolder="C:\your\path\to\excelfiles\"
Set oFSO = CreateObject("Scripting.FileSystemObject")
xlCSV = 6 'Excel CSV format enum
Call ConvertAllExcelFiles(myFolder)
Set oFSO = Nothing
Call MsgBox ("Done!")
Sub ConvertAllExcelFiles(ByVal oFolder)
Dim targetF, oFileList, oFile
Dim oExcel, oWB, oWSH
Set oExcel = CreateObject("Excel.Application")
oExcel.DisplayAlerts = False
Set targetF = oFSO.GetFolder(oFolder)
Set oFileList = targetF.Files
For Each oFile in oFileList
If (Right(oFile.Name, 4) = "xlsx") Then
Set oWB = oExcel.Workbooks.Open(oFile.Path)
For Each oWSH in oWB.Sheets
Call oWSH.SaveAs (oFile.Path & oWSH.Name & ".csv", xlCSV)
Next
Set oWSH = Nothing
Call oWB.Close
Set oWB = Nothing
End If
Next
Call oExcel.Quit
Set oExcel = Nothing
End Sub
You can give better file naming, error handling/etc if needed.
The issue with your code is that you define sPath as a path containing wildcard characters:
sName = Dir(fPath & "*.xls*")
and replace only the extension portion (.xls*), but leave the wildcard character before the extension in place:
Replace(sName, ".xls*", ".txt")
This produces the following path:
C:\Users\A9993846\Desktop\*.txt
which causes the error you observed, because the SaveAs method tries to save the spreadsheet to a file with the literal name *.txt, but * is not a valid character for file names.
Replace this:
.SaveAs Replace(sName, ".xls*", ".txt"), 42
with this:
Set wb = sh.Parent
basename = Replace(wb.FullName, Mid(wb.Name, InStrRev(wb.Name, ".")), "")
.SaveAs basename & "_" & sh.Name & ".txt", xlUnicodeText