I need this macro to automatically grab the data from column A, find the data into the path given and replace it with column B. It is working but I need it to work just for once and goes on forward automatically..
Can anyone help me in this..
Sub UnkownFunctionName()
Dim myfolder
Dim Fnd As String, Rplc As String
Fnd = Application.InputBox(prompt:="Find string:", Title:="Rename files and folders", Type:=2)
Rplc = Application.InputBox(prompt:="Replace with:", Title:="Rename files and folders", Type:=2)
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
myfolder = .SelectedItems(1) & "\"
End With
Call Recursive(myfolder, Fnd, Rplc)
End Sub
Sub Recursive(FolderPath As Variant, Fnd As String, Rplc As String)
Dim Value As String, Folders() As String, Fname As String, Fext As String, Mtxt As String
Dim x As Integer
Dim Folder As Variant, a As Long
ReDim Folders(0)
If Right(FolderPath, 2) = "\\" Then Exit Sub
Value = Dir(FolderPath, &H1F)
Do Until Value = ""
If Value = "." Or Value = ".." Then
Else
If GetAttr(FolderPath & Value) = 16 Or GetAttr(FolderPath & Value) = 48 Then
On Error Resume Next
Mtxt = "Rename folder " & Value & " to " & WorksheetFunction.Substitute(Value, Fnd, Rplc) & "?"
x = MsgBox(Mtxt, vbYesNoCancel)
If x = vbCancel Then Exit Sub
If x = vbYes Then
Name FolderPath & Value As FolderPath & WorksheetFunction.Substitute(Value, Fnd, Rplc)
End If
Value = WorksheetFunction.Substitute(Value, Fnd, Rplc)
If Err <> 0 Then
MsgBox "Error"
Exit Sub
End If
On Error GoTo 0
Folders(UBound(Folders)) = Value
ReDim Preserve Folders(UBound(Folders) + 1)
Else
On Error Resume Next
Fext = Split(Value, ".")(UBound(Split(Value, ".")))
Fname = Left(Value, Len(Value) - Len(Split(Value, ".")(UBound(Split(Value, ".")))) - 1)
Fname = WorksheetFunction.Substitute(Fname, Fnd, Rplc)
If Value <> (Fname & "." & Fext) Then
Mtxt = "Rename file " & Value & " to " & Fname & "." & Fext & "?"
x = MsgBox(Mtxt, vbYesNoCancel)
If x = vbCancel Then Exit Sub
If x = vbYes Then
Name FolderPath & Value As FolderPath & Fname & "."& Fext
End If
End If
If Err <> 0 Then
MsgBox "Error"
Exit Sub
End If
On Error GoTo 0
End If
End If
Value = Dir
Loop
For Each Folder In Folders
Call Recursive(FolderPath & Folder & "\", Fnd, Rplc)
Next
End Sub
If this accomplishes what you want, why not put a pause of some kind after the loop that accomplishes your goal completes. For instance-
...
End If
If MsgBox("Continue?", vbYesNo, "Confirm") = vbNo Then Exit Sub
...
I'm having a hard time linking what the code does to what your question suggests. It seems that the code renames files and folders. Can you explain a bit more about your goal?
Related
I'm trying to use Excel VBA to find a string in a folder, but it seems the FINDSTR command line is not working.
I'm wondering if it could be a change in Windows (I'm using Win10), or if I don't have a have the correct "Reference" selected (I do have the Microsoft Scripting Runtime selected).
Sub ListFilesContainingString()
Dim myfile As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
wrd = InputBox("Word:", "Insert search word")
If wrd = "" Then
MsgBox "???"
Exit Sub
End If
myfile = FindFiles(GetFolder, wrd)
If (myfile <> "") Then MsgBox file
End Sub
Function FindFiles(ByVal path As String, ByVal target As String) As String
' Run The Shell Command And Get Output
Dim files As String
files = CreateObject("Wscript.Shell").Exec("FINDSTR /M """ & target & """ """ & path & "\*.*""").StdOut.ReadAll
FindFiles = ""
If (files <> "") Then
Dim idx As Integer
idx = InStr(files, vbCrLf)
FindFiles = Left(files, idx - 1)
End If
I fixed the typo but FINDSTR is still not working correctly. My current code is below. Note that there are several instances of FINDSTR and FIND so I can see what is being returned (the "If, Then x=x" code is only to place a breakpoint). FINDSTR returns "", FIND returns a file but it isn't a correct file.
FINDSTR does work using a dos/powershell window.
Sub ListFilesContainingString()
'this macro finds vendor information on the chosen file for each part in the origin file
Dim myfile As String
Dim fldr As FileDialog
Dim sItem As String
Dim wrd As String
''''''''''''''''''''''''''''''''''''''
Dim objFSO As Object
Dim objFolders As Object
Dim objFolder As Object
Dim DirFolderRename As String
Dim arrFolders() As String
Dim FolderCount As Long
Dim FolderIndex As Long
''''''''''''''''''''''''''''''''''''''
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
''''''''''''''''''''''''''''''''''''''
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolders = objFSO.GetFolder(sItem).SubFolders
FolderCount = objFolders.Count
If FolderCount > 0 Then
ReDim arrFolders(1 To FolderCount)
FolderIndex = 0
For Each objFolder In objFolders
FolderIndex = FolderIndex + 1
arrFolders(FolderIndex) = objFolder.Name
Next objFolder
Else
MsgBox "No folders found!", vbExclamation
End If
Set objFSO = Nothing
Set objFolders = Nothing
Set objFolder = Nothing
''''''''''''''''''''''''''''''''''''''
Set wrdAddr = Application.InputBox("Select First Word to Search For", "Obtain Range Object", Type:=8)
wrdCol = wrdAddr.Column
wrdRow = wrdAddr.Row
StartCell = Cells(wrdRow, wrdCol).Address
Range(StartCell).Activate
wrd = ActiveCell.Value
While (wrd <> "")
'wrd = InputBox("Word:", "Insert search word")
If wrd = "" Then
MsgBox "???"
Exit Sub
End If
For i = 1 To FolderCount
TheFolder = GetFolder & "\" & arrFolders(i)
myfile = FindFiles(TheFolder, wrd)
If (myfile <> "") Then
ActiveCell.Offset(0, 17).Value = ActiveCell.Offset(0, 17).Value & arrFolders(i) & ","
End If
Next i
ActiveCell.Offset(1, 0).Select
wrd = ActiveCell.Value
Wend
End Sub
Function FindFiles(ByVal path As String, ByVal target As String) As String
' Run The Shell Command And Get Output
Dim files1, files2, files3, files4 As String
Dim lines
'''' This works in the dos window
' findstr /M /S /I L298P C:\Users\Wm" "Boyd\Documents\Boyd" "Manufacturing\Customers\Inactive\*.xls?
''''
exec ("FINDSTR /M L298P C:\Users\Wm""Boyd\Documents\Boyd""Manufacturing\Customers\Inactive\*.xls?")
files1 = CreateObject("WScript.Shell").exec("FINDSTR /M """ & target & """ """ & path & "\*.xls?""").StdOut.Read
files2 = CreateObject("Wscript.Shell").exec("FINDSTR /M L298P C:\Users\Wm""Boyd\Documents\Boyd""Manufacturing\Customers\Inactive\*.xlsx").StdOut.ReadAll
If files1 <> "" Then
x = x
End If
files3 = CreateObject("Wscript.Shell").exec("FIND """ & target & """ """ & path & "\*.xls?""").StdOut.ReadAll
files4 = CreateObject("Wscript.Shell").exec("FIND """ & target & """ """ & path & "\*.*""").StdOut.ReadAll
lines = Split(files1, vbCrLf)
Dim curFile As String
Dim line
For Each line In lines
If (Left(line, 11) = "---------- ") Then
curFile = Mid(line, 12)
End If
If (curFile <> "") Then
FindFiles = curFile
Exit Function
End If
Next
'files = CreateObject("Wscript.Shell").Exec("FINDSTR """ & target & """ """ & path & "\*.*""").StdOut.ReadAll
'If (files <> "") Then
'Dim idx As Integer
'idx = InStr(files, vbCrLf)
'FindFiles = Left(files, idx - 1)
'End If
FindFiles = ""
End Function
I have created a log file to record the command executed and the response. This is a first step, if it works the next step would be to parse the response for the information you want.
Option Explicit
Sub ListFilesContainingString()
Const qq = """"
' get first word from sheet
Dim wrdCell As Range
Set wrdCell = Application.InputBox("Select First Word to Search For", _
"Obtain Range Object", Type:=8)
If Len(wrdCell.Value2) = 0 Then
MsgBox "No word selected", vbCritical
Exit Sub
End If
' start logging
Dim Folder As String, FSO As Object, tsLog As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim logfile As String, cmd As String, n As Long
Dim msg As String, W As Object, s As String
logfile = ThisWorkbook.path & "\" & "Log_" _
& Format(Now(), "yyyymmdd_hhmmss") & ".txt"
Set tsLog = FSO.CreateTextFile(logfile)
Set W = CreateObject("Wscript.Shell")
' get folders
Folder = GetFolder("C:\") 'start in c:\
If Len(Folder) = 0 Then Exit Sub
' scan for each words
Do While Not IsEmpty(wrdCell)
' message box
msg = msg & vbLf & wrdCell.Address & " " & wrdCell
' build command
s = qq & wrdCell & qq & " " & qq & Folder
cmd = "FINDSTR /M /S " & s & "\*.*" & qq
tsLog.writeLine "Command" & vbCrLf & cmd & vbCrLf
' execute
s = W.exec(cmd).StdOut.ReadAll
tsLog.writeLine "Result" & vbCrLf & ">" & s & "<" & vbLf
' next
n = n + 1
Set wrdCell = wrdCell.Offset(1)
Loop
tsLog.Close
MsgBox "Words searched for " & msg, vbInformation, "See " & logfile
Shell "notepad.exe " & logfile
End Sub
Function GetFolder(strPath) As String
Dim fldr As FileDialog
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then
MsgBox "Cancelled", vbExclamation
Exit Function
End If
GetFolder = .SelectedItems(1)
End With
End Function
I have managed convert a list of images onto pdf, then gathered them in a single file and then print them as multiple pages 10 columns x 14 rows so I can print in a single sheet 140 original images.
All of these with sendkeys method which was absolutely madness and frustrating but at the end it works pretty fine, the only handicap is that I have to do this almost everyday and once I run the sendkeys macro I can't do nothing with my computer until it ends which could probably be hours
I'm trying to do this in a less "messy" way
I have managed to convert the images in pdf easely with this code I modified from a search on internet (just in case someone find it usefull for him/her)
Sub png_to_pdf()
Dim Acroapp As New Acrobat.Acroapp
Dim pddoc As New Acrobat.AcroPDDoc
Set Acroapp = CreateObject("AcroExch.App")
Set pddoc = CreateObject("AcroExch.pddoc")
aux_pngtopdf "F:\ES-VAL\PURCH-U\CARLOS\qr", pddoc
End Sub
Private Sub aux_pngtopdf(ByVal xFolderName As String, ByVal pddoc As Object)
Dim xFileSystemObject As Object
Dim xFolder As Object
Dim xSubFolder As Object
Dim xFile As Object
Dim xfilepdf As String
Set xFileSystemObject = CreateObject("Scripting.FileSystemObject")
Set xFolder = xFileSystemObject.GetFolder(xFolderName)
For Each xFile In xFolder.Files
If Right(xFile, 3) = "png" And Application.CountIf(Columns(10), Mid(xFolderName, 29, 9)) = 0 And Application.CountIf(Columns(11), Mid(xFolderName, 29, 9)) = 0 Then
pddoc.Open xFile
xfilepdf = Left(xFile, Len(xFile) - 3) & "pdf"
pddoc.Save PDSaveFull, xfilepdf
End If
Next xFile
For Each xSubFolder In xFolder.subfolders
If Len(xSubFolder) < 250 Then
aux_pngtopdf xSubFolder.Path, pddoc
End If
Next xSubFolder
Set xFile = Nothing
Set xFolder = Nothing
Set xFileSystemObject = Nothing
End Sub
I'm changing the code I found (I don't really remember if here or if in any other site) to merge all the pdf into a single one and it seems it would be fine
Sub merge_pdf()
Const DestFile As String = "MergedFile.pdf" ' <-- change to suit
Dim MyPath As String, MyFiles As String
Dim a() As String, i As Long, f As String
Dim j As Integer
j = 4
' Choose the folder or just replace that part by: MyPath = Range("E3")
With Application.FileDialog(msoFileDialogFolderPicker)
'.InitialFileName = "C:\Temp\"
.AllowMultiSelect = False
If .Show = False Then Exit Sub
MyPath = .SelectedItems(1) & "\" & Cells(j, 3).Value
DoEvents
End With
' Populate the array a() by PDF file names
If Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
ReDim a(1 To 2 ^ 14)
f = Dir(MyPath & "*.pdf")
While Len(f)
If StrComp(f, DestFile, vbTextCompare) Then
i = i + 1
a(i) = f
End If
f = Dir()
Wend
' Merge PDFs
If i Then
ReDim Preserve a(1 To i)
MyFiles = Join(a, ",")
Application.StatusBar = "Merging, please wait ..."
Call aux_MergePDFs(MyPath, MyFiles, DestFile)
Application.StatusBar = False
Else
MsgBox "No PDF files found in" & vbLf & MyPath, vbExclamation, "Canceled"
End If
End Sub
Private Sub aux_MergePDFs(MyPath As String, MyFiles As String, Optional DestFile As String = "MergedFile.pdf")
Dim a As Variant, i As Long, n As Long, ni As Long, p As String
Dim Acroapp As New Acrobat.Acroapp, PartDocs() As Acrobat.CAcroPDDoc
If Right(MyPath, 1) = "\" Then p = MyPath Else p = MyPath & "\"
a = Split(MyFiles, ",")
ReDim PartDocs(0 To UBound(a))
On Error GoTo exit_
If Len(Dir(p & DestFile)) Then Kill p & DestFile
For i = 0 To UBound(a)
' Check PDF file presence
If Dir(p & Trim(a(i))) = "" Then
MsgBox "File not found" & vbLf & p & a(i), vbExclamation, "Canceled"
Exit For
End If
' Open PDF document
Set PartDocs(i) = CreateObject("AcroExch.PDDoc")
PartDocs(i).Open p & Trim(a(i))
If i Then
' Merge PDF to PartDocs(0) document
ni = PartDocs(i).GetNumPages()
If Not PartDocs(0).InsertPages(n - 1, PartDocs(i), 0, ni, True) Then
MsgBox "Cannot insert pages of" & vbLf & p & a(i), vbExclamation, "Canceled"
End If
' Calc the number of pages in the merged document
n = n + ni
' Release the memory
PartDocs(i).Close
Set PartDocs(i) = Nothing
Else
' Calc the number of pages in PartDocs(0) document
n = PartDocs(0).GetNumPages()
End If
Next
If i > UBound(a) Then
' Save the merged document to DestFile
If Not PartDocs(0).Save(PDSaveFull, p & DestFile) Then
MsgBox "Cannot save the resulting document" & vbLf & p & DestFile, vbExclamation, "Canceled"
End If
End If
exit_:
' Inform about error/success
If Err Then
MsgBox Err.Description, vbCritical, "Error #" & Err.Number
ElseIf i > UBound(a) Then
MsgBox "The resulting file is created:" & vbLf & p & DestFile, vbInformation, "Done"
End If
' Quit Acrobat application
Acroapp.Exit
Set Acroapp = Nothing
End Sub
But I don't have any clue on how to print several pages of the pdf into a single one. Not interested in only 16 pages per sheet (since the images I try to print are QR codes 12mmx12mm so it fits pretty fine 140 of them in a single sheet) which could be more or less easy if you set adobe pdf as your default printer and setup it to print 16 pages per sheet (I also found part of a code that could fit to this purpose)
Any clue will be apreciated
Thanks
I am trying to automatically save my active workbook into another folder on my computer and if there is already a file with the name of my workbook in that folder, then it should be saved with "_v1"/"_v2" and so on at the end of its name.
I have found this code but it works just for the current folder, where the workbook is saved.
Sub SaveNewVersion_Excel()
Dim FolderPath As String
Dim myPath As String
Dim SaveName As String
Dim SaveExt As String
Dim VersionExt As String
Dim Saved As Boolean
Dim x As Long
TestStr = ""
Saved = False
x = 2
VersionExt = "_v"
On Error GoTo NotSavedYet
myPath = "O:\Operations\Department\Data Bank Coordinator\_PROJECTS_\QC BeadRegion Check\Multi Ref Archiv"
myFileName = Mid(myPath, InStrRev(myPath, "\") + 1, InStrRev(myPath, ".") - InStrRev(myPath, "\") - 1)
FolderPath = Left(myPath, InStrRev(myPath, "\"))
SaveExt = "." & Right(myPath, Len(myPath) - InStrRev(myPath, "."))
On Error GoTo 0
If InStr(1, myFileName, VersionExt) > 1 Then
myArray = Split(myFileName, VersionExt)
SaveName = myArray(0)
Else
SaveName = myFileName
End If
If FileExist(FolderPath & SaveName & SaveExt) = False Then
ActiveWorkbook.saveAs FolderPath & SaveName & SaveExt
Exit Sub
End If
Do While Saved = False
If FileExist(FolderPath & SaveName & VersionExt & x & SaveExt) = False Then
ActiveWorkbook.saveAs FolderPath & SaveName & VersionExt & x & SaveExt
Saved = True
Else
x = x + 1
End If
Loop
Exit Sub
NotSavedYet:
MsgBox "This file has not been initially saved. " & _
"Cannot save a new version!", vbCritical, "Not Saved To Computer"
End Sub
Function FileExist(FilePath As String) As Boolean
Dim TestStr As String
On Error Resume Next
TestStr = Dir(FilePath)
On Error GoTo 0
If TestStr = "" Then
FileExist = False
Else
FileExist = True
End If
End Function
It works for the current folder but when I change the folder path it doesn't work.
I would very much appreciate it if you could help me.
Thanks!
Sergiu
I've assumed the new folder is "D:_PROJECTS_\Multi Ref Archiv" and that if the existing file is zzzz_v07.xlsm then you want this saved as zzzz_v08.xlsm even when there are no previous versions in the folder. I added the leading zero so they sort nicely!
Sub SaveNewVersion_Excel2()
Const FOLDER = "D:\_PROJECTS_\Multi Ref Archiv" ' new location
Const MAX_FILES = 99
Dim oFSO As Object, oFolder As Object, bOK As Boolean, res As Variant
Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim sFilename As String, sFilename_v As String
' filename only
sFilename = ThisWorkbook.Name
' check folder exists
If Not oFSO.folderexists(FOLDER) Then
bOK = MsgBox(FOLDER & " does not exist. Do you want to create ?", vbYesNo, "Confirm")
If bOK Then
oFSO.createFolder FOLDER
MsgBox "OK created " & FOLDER, vbInformation
Else
Exit Sub
End If
End If
' get next name
sFilename_v = Next_v(sFilename)
' check if exists
Dim i As Integer: i = 1
Do While oFSO.fileexists(FOLDER & "\" & sFilename_v) = True And i <= MAX_FILES
i = i + 1
sFilename_v = Next_v(sFilename_v)
Loop
' check loop ok
If i > MAX_FILES Then
MsgBox "More than " & MAX_FILES & " files already exist", vbExclamation
Exit Sub
End If
sFilename_v = FOLDER & "\" & sFilename_v
' confirm save
res = MsgBox("Do you want to save to " & sFilename_v, vbYesNo, "Confirm")
If res = vbYes Then
ActiveWorkbook.SaveAs sFilename_v
MsgBox "Done", vbInformation
End If
End Sub
Function Next_v(s As String)
Const ver = "_v"
Dim i As Integer, j As Integer, ext As String, rev As Integer
i = InStrRev(s, ".")
j = InStrRev(s, ver)
ext = Mid(s, i)
' increment existing _v if exists
If j > 0 Then
rev = Mid(s, j + 2, i - j - 2)
s = Left(s, j - 1)
Else
rev = 0
s = Left(s, i - 1)
End If
Next_v = s & ver & Format(rev + 1, "00") & ext
End Function
You can move all of the logic out to a separate function, then you only need to call that to get the "correct" name to save as.
'Pass in the full path and filename
' Append "_Vx" while the passed filename is found in the folder
' Returns empty string if the path is not valid
Function NextFileName(fPath As String)
Const V As String = "_V"
Dim fso, i, p, base, ext
Set fso = CreateObject("scripting.filesystemobject")
'valid parent folder?
If fso.folderexists(fso.GetParentFolderName(fPath)) Then
p = fPath
ext = fso.getextensionname(p)
base = Left(p, Len(p) - (1 + Len(ext))) 'base name without extension
i = 1
Do While fso.fileexists(p)
i = i + 1
p = base & (V & i) & "." & ext
Loop
End If
NextFileName = p
End Function
I keep getting an error in the below code and its likely incorrect syntax.
I have tried replacing this line
IsInArray(pdfname, arNames(i)) = True
with this
Application.worksheetfunction.match(pdfname, arNames(i)) = True
but its not working.
Sub OpenPdf()
On Error GoTo OpenPdf_Error
Dim pdfname As String
Dim pdf
Const sPath = "S:\RA QUOTES 2019"
Dim FName As String
Dim arNames() As String
Dim myCount As Integer
Dim i As Integer
FName = Dir("S:\RA QUOTES 2019\*.pdf*")
Do Until FName = ""
myCount = myCount + 1
ReDim Preserve arNames(1 To myCount)
arNames(myCount) = FName
FName = Dir
Loop
pdfname = Application.InputBox("Enter the pdf you are looking for")
pdfname = "PLQ" & pdfname
For i = 1 To UBound(arNames)
If IsInArray(pdfname, arNames(i)) = True Then
ThisWorkbook.FollowHyperlink sPath & arNames(i)
End If
Next i
On Error GoTo 0
Exit Sub
OpenPdf_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure OpenPdf"
End Sub
This will work for an exact match using a dictionary (a collection data type which has the .Exists property which allows you to check if a key within the dictionary exists without looping through everytime).
Option Explicit
Sub OpenPdf()
Dim pdfname As String
Dim DictPDF As New Scripting.Dictionary 'Needs Microsoft Scripting Runtime
Const sPath = "S:\RA QUOTES 2019\"
Dim FName As String
Dim i As Integer
FName = Dir(sPath & "*.pdf*")
Do While FName <> vbNullString
'add the name into the dictionary
DictPDF.Add Left(LCase(pdfname), 7), 1 'Left will get the first 7 characters from the left to the name
FName = Dir
Loop
pdfname = Application.InputBox("Enter the pdf you are looking for")
pdfname = LCase("PLQ" & pdfname)
'Check if the name is in the dictionary I used LCase because dictionaries are case sensitive,
'so everything in low case to avoid problems.
If DictPDF.Exists(pdfname) Then
ThisWorkbook.FollowHyperlink sPath & DictPDF(pdfname)
Else
MsgBox pdfname & " was not found."
End If
End Sub
Sub OpenPdf()
On Error GoTo OpenPdf_Error
Dim pdfname As String
Dim pdf
Const sPath = "S:\RA QUOTES 2019\"
Dim FName As String
Dim arNames() As String
Dim myCount As Integer
Dim i As Integer
FName = Dir("S:\RA QUOTES 2019\*.pdf*")
Do Until FName = ""
myCount = myCount + 1
ReDim Preserve arNames(1 To myCount)
arNames(myCount) = FName
FName = Dir
Loop
pdfname = Application.InputBox("Enter the pdf you are looking for")
pdfname = "PLQ" & pdfname
For i = 1 To UBound(arNames)
If InStr(1, arNames(i), pdfname, vbTextCompare) Then
MsgBox (arNames(i))
ThisWorkbook.FollowHyperlink sPath & arNames(i)
End If
Next i
On Error GoTo 0
Exit Sub
OpenPdf_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure
OpenPdf"
End Sub
I am using this code to list out all the files in Folder and Sub Folder in Excel. This code is working fine. I want to leave one blank row for each sub folder. currently its list out continuously in all the rows. Please help.
Sub HyperlinkDirectory()
Dim fPath As String
Dim fType As String
Dim fname As String
Dim NR As Long
Dim AddLinks As Boolean
'Select folder
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.InitialFileName = "C:\2009\"
.Show
If .SelectedItems.Count > 0 Then
fPath = .SelectedItems(1) & "\"
Else
Exit Sub
End If
End With
'Types of files
fType = Application.InputBox("What kind of files? Type the file extension to collect" _
& vbLf & vbLf & "(Example: pdf, doc, txt, xls, *)", "File Type", "pdf", Type:=2)
If fType = "False" Then Exit Sub
'Option to create hyperlinks
AddLinks = MsgBox("Add hyperlinks to the file listing?", vbYesNo) = vbYes
'Create report
Application.ScreenUpdating = False
NR = 5
With Sheets("Sheet1")
.Range("A:C").Clear
.[A1] = "Directory"
.[B1] = fPath
.[A2] = "File type"
.[B2] = fType
.[A4] = "File"
.[B4] = "Modified"
Call FindFilesAndAddLinks(fPath, fType, NR, AddLinks)
.Range("A:B").Columns.AutoFit
End With
Application.ScreenUpdating = True
End Sub
Private Sub FindFilesAndAddLinks(fPath As String, fType As String, ByRef NR As Long, AddLinks As Boolean)
Dim fname As String
Dim oFS As New FileSystemObject
Dim oDir
'Files under current dir
fname = Dir(fPath & "*." & fType)
With Sheets("Sheet1")
Do While Len(fname) > 0
'filename
.Range("A" & NR) = fname
'modified
.Range("B" & NR) = FileDateTime(fPath & fname)
'hyperlink
.Range("A" & NR).Select
If AddLinks Then .Hyperlinks.Add Anchor:=Selection, _
Address:=fPath & fname, _
TextToDisplay:=fPath & fname
'set for next entry
NR = NR + 1
fname = Dir
Loop
'Files under sub dir
Set oDir = oFS.GetFolder(fPath)
For Each oSub In oDir.SubFolders
Call FindFilesAndAddLinks(oSub.Path & "\", fType, NR, AddLinks)
Next oSub
End With
End Sub
The changed FindFilesAndAddLinks below will create the following format:
FolderRoot\Folder1\Subfolder1
FolderRoot\Folder1\Subfolder1\FirstFileFound
FolderRoot\Folder1\Subfolder1\SecondFileFound
FolderRoot\Folder2\Subfolder2
FolderRoot\Folder2\Subfolder2\FirstFileFound
FolderRoot\Folder2\Subfolder2\SecondFileFound
...
New macro:
Private Sub FindFilesAndAddLinks(fPath As String, fType As String, ByRef NR As Long, AddLinks As Boolean)
Dim fname As String
Dim oFS As New FileSystemObject
Dim oDir
'Files under current dir
fname = Dir(fPath & "*." & fType)
With Sheets("Sheet1")
'Write folder name
.Range("A" & NR) = fPath
NR = NR + 1
Do While Len(fname) > 0
'filename
If .Range("A" & NR) <> "" Then Debug.Print "Overwriting " & NR
.Range("A" & NR) = fname
'modified
.Range("B" & NR) = FileDateTime(fPath & fname)
'hyperlink
.Range("A" & NR).Select
If AddLinks Then .Hyperlinks.Add Anchor:=Selection, _
Address:=fPath & fname, _
TextToDisplay:=fPath & fname
'set for next entry
NR = NR + 1
fname = Dir
Loop
'Files under sub dir
Set oDir = oFS.GetFolder(fPath)
For Each oSub In oDir.SubFolders
NR = NR + 1
Call FindFilesAndAddLinks(oSub.Path & "\", fType, NR, AddLinks)
Next oSub
End With
End Sub
Hi i'm not sure what do you mean with Blank Row for a subfolder. But i think if you add NR = NR+1 in the Subfolder Loop, it should wor fine.
'Files under sub dir
Set oDir = oFS.GetFolder(fPath)
For Each oSub In oDir.SubFolders
NR = NR + 1
Call FindFilesAndAddLinks(oSub.Path & "\", fType, NR, AddLinks)
Next oSub