注意事项:
1) 我不完全清楚您的数据等是如何布置的,因此我提供了一种实现您的目标的方法,其中涉及我清楚的元素。
2) 老实说,就个人而言,我会尽可能多地使用数组或字典,而不是在工作表中前后移动。
不过……
按照您的要求大纲和一点粗略和准备,我们有:
1) 使用您的宏 rename(重命名为 ListFiles 并进行一些小调整)将所选文件夹名称写入 Worksheets("Batch Rename of Files") 中的 Range("A1") 并将文件名写入 C 列。
2) 使用第二个宏RenameFiles 从Worksheets("Batch Rename of Files") 的 F 列获取重命名 shell 命令;将这些写到桌面上的批处理文件中;添加一个额外的第一行命令,将工作目录设置为Range("A1") 中给出的所选文件夹(要求 A)。 shell命令执行.bat文件,完成重命名(需求B)然后有一行删除.bat文件。
我猜这是实现目标的一种更有效的方法,而不是循环 F 列范围一次执行一个命令。
我没有尝试以任何进一步的方式优化代码(我添加了一些现有的类型化函数。)还有许多其他可以改进的地方,但这是为了帮助您实现您的要求。
告诉我进展如何!
Tab1 布局(包含新文件名的工作表):
文件布局的批量重命名(包含第一个宏和按钮输出的工作表):
工作表布局文件批量重命名
在一个名为ListFiles的标准模块中:
Option Explicit
Public Sub ListFilesInDirectory()
Dim xRow As Long
Dim xDirect$, xFname$, InitialFoldr$ 'type hints not really needed
Dim wb As Workbook
Dim wsTab2 As Worksheet
Set wb = ThisWorkbook
Set wsTab2 = wb.Worksheets("Batch Rename of Files")
InitialFoldr$ = "C:\"
Dim lastRow As Long
lastRow = wsTab2.Cells(wsTab2.Rows.Count, "C").End(xlUp).Row
wsTab2.Range("C4:C" & lastRow).ClearContents 'Get rid of any existing file names
wsTab2.Range("C4").Activate
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = Application.DefaultFilePath & "\"
.Title = "Please select a folder to list Files from"
.InitialFileName = InitialFoldr$
.Show
If .SelectedItems.Count <> 0 Then
xDirect$ = .SelectedItems(1) & "\"
xFname$ = Dir(xDirect$, 7)
wsTab2.Range("A1") = xDirect$
Do While xFname$ <> vbNullString
ActiveCell.Offset(xRow) = xFname$
xRow = xRow + 1
xFname$ = Dir
Loop
End If
End With
End Sub
在一个名为FileRenaming的标准模块中:
Option Explicit
Sub RenameFiles()
Dim fso As New FileSystemObject
Dim stream As TextStream
Dim strFile As String
Dim strPath As String
Dim strData As Range
Dim wb As Workbook
Dim wsTab2 As Worksheet
Dim currRow As Range
Set wb = ThisWorkbook
Set wsTab2 = wb.Worksheets("Batch Rename of Files")
strPath = wsTab2.Range("A1").Value2
If strPath = vbNullString Then
MsgBox "Please ensure that Worksheet Batch Rename of Files has a directory path in cell A1"
Else
If Right$(Trim$(strPath), 1) <> "\" Then strPath = strPath & "\"
strFile = "Rename.bat"
Dim testString As String
Dim deskTopPath As String
deskTopPath = Environ$("USERPROFILE") & "\Desktop" 'get desktop path as this is where .bat file will temporarily be saved
testString = fso.BuildPath(deskTopPath, strFile) 'Check if .bat already exists and delete
If Len(Dir(testString)) <> 0 Then
SetAttr testString, vbNormal
Kill testString
End If
Set stream = fso.CreateTextFile(deskTopPath & "\" & strFile, True) 'create the .bat file
Dim lastRow As Long
lastRow = wsTab2.Cells(wsTab2.Rows.Count, "C").End(xlUp).Row
Set strData = wsTab2.Range("F4:F" & lastRow) 'Only execute for as many new file names as present in Col C (in place of your until blank requirement)
stream.Write "CD /D " & strPath & vbCrLf
For Each currRow In strData.Rows 'populate the .dat file
stream.Write currRow.Value & vbCrLf
Next currRow
stream.Close
Call Shell(testString, vbNormalFocus)
Application.Wait (Now + TimeValue("0:00:01")) 'As sometime re-naming doesn't seem to happen without a pause before removing .bat file
Kill testString
MsgBox ("Renaming Complete")
End If
End Sub
工作表中的按钮代码批量重命名文件
Private Sub CommandButton1_Click()
ListFilesInDirectory
End Sub
Private Sub CommandButton2_Click()
RenameFiles
End Sub
.bat 文件内容示例:
第 2 版
这是一个不同的版本,它使用字典并将参数从一个子传递到另一个。因此,这将是一个仅与一个按钮按下操作相关联的宏,即不会有第二个按钮。单个按钮将调用ListFiles,后者又调用第二个宏。可能需要您进入工具 > 参考并添加 Microsoft Scripting Runtime 参考。
假设您在选项卡 1 的 Col D 中具有与文件夹中找到的文件数量相匹配的新文件名数量(根据您的脚本来获取文件夹中的文件)。我已删除过时的类型引用。请向 RubberDuck VBA 加载项工作人员大喊,让加载项拾取这些内容。
在一个标准模块中:
Option Explicit
Public Sub ListFiles()
Dim xDirect As String, xFname As String, InitialFoldr As String
Dim wb As Workbook
Dim ws As Worksheet
Dim dict As New Scripting.Dictionary
Dim counter As Long
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Tab1") 'Worksheet where new file names are
counter = 4 'row where new file names start
InitialFoldr = "C:\"
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = Application.DefaultFilePath & "\"
.Title = "Please select a folder to list Files from"
.InitialFileName = InitialFoldr
.Show
If .SelectedItems.Count <> 0 Then
xDirect = .SelectedItems(1) & "\"
xFname = Dir(xDirect, 7)
Do While xFname <> vbNullString
If Not dict.Exists(xFname) Then
dict.Add xFname, ws.Cells(counter, "D") 'Or which ever column holds new file names. This add to the dictionary the current name and new name
counter = counter + 1
xFname = Dir
End If
Loop
End If
End With
RenameFiles xDirect, dict 'pass directory path and dictionary to renaming sub
End Sub
在另一个标准模块中:
Public Sub RenameFiles(ByVal folderpath As String, ByRef dict As Dictionary)
Dim fso As New FileSystemObject
Dim stream As TextStream
Dim strFile As String
Dim testString As String
Dim deskTopPath As String
strFile = "Rename.bat"
deskTopPath = Environ$("USERPROFILE") & "\Desktop"
testString = fso.BuildPath(deskTopPath, strFile)
'See if .dat file of same name already on desktop and delete (you could overwrite!)
If Len(Dir(testString)) <> 0 Then
SetAttr testString, vbNormal
Kill testString
End If
Set stream = fso.CreateTextFile(testString, True)
stream.Write "CD /D " & folderpath & vbCrLf
Dim key As Variant
For Each key In dict.Keys
stream.Write "Rename " & folderpath & key & " " & dict(key) & vbCrLf 'write out the command instructions to the .dat file
Next key
stream.Close
Call Shell(testString, vbNormalFocus)
Application.Wait (Now + TimeValue("0:00:01")) 'As sometime re-naming doesn't seem to happen without a pause before removing .bat file
Kill testString
' MsgBox ("Renaming Complete")
End Sub
脚本运行时参考:
添加运行时引用
查找桌面路径的其他方法。取自Allen Wyatt:
在标准模块中添加以下内容:
Public Function GetDesktop() As String
Dim oWSHShell As Object
Set oWSHShell = CreateObject("WScript.Shell")
GetDesktop = oWSHShell.SpecialFolders("Desktop")
Set oWSHShell = Nothing
End Function
然后在其余代码中替换 deskTopPath =..... 的任何实例,例如:
deskTopPath = Environ$("USERPROFILE") & "\Desktop"
有
desktopPath = GetDesktop