How do I rename multiple folder/subfolder contents with automator without affecting the folders themselves? - rename

I'm trying to rename a bunch of files with automator so they are sequential. All the files are already in the correct order.
I tried:
Get Selected Finder Items
Get Folder Contents (checked repeat for each subfolder found)
Rename Finder Items: Make Sequential
I'm giving each item a new name so it appears with 3 digits (001.xxx) and continues from there.
I'm only wanting to rename the folder contents. For example. I have a folder with 10 subfolders. In each subfolder are 20 images with names like image001, image002, etc. I want to rename the images as 001, 002, 003. But I want this to start over for each subfolder.
When I run the automator script above, It will rename the first subfolder 001, then it will name the first image (image001) inside the first subfolder 002. The last image (image020) will be 021, then the 2nd subfolder would be renamed 022, the first image of it (image001) will be renamed 023, and so on.
How can I get it to leave the names of the subfolders alone and just rename the contents (image001 = 001, etc) but once it finishes with the 20 images in the first subfolder, it goes to the 2nd subfolder and names those images 001 to 020 as well?
Thanks for your time.

This is too much for Automator; it is not able to perform repeats of this nature. However, it is a simple job for AppleScript:
set f to choose folder -- Select Master Folder
tell application "Finder"
set subF to every folder of folder f
repeat with eachFolder in subF
set counter to 1
set allFiles to (every file of eachFolder)
repeat with oneFile in allFiles
set newFileName to my pad(counter, 3)
set correctExtension to oneFile's name extension
set oneFile's name to (newFileName & "." & correctExtension)
set counter to counter + 1
end repeat
end repeat
end tell
on pad(num, howLong)
set thisNum to num as text
set c to count thisNum
repeat howLong - c times
set thisNum to "0" & thisNum
end repeat
return thisNum as text
end pad
This should work; it is a modification of a script that I have used in the past. However, before running it on your real files, make a copy somewhere first to try it out, and reply here if there are any problems.

Related

Traverse file system of Excel WORKBOOK, and manipulate each WORKSHEET using Apple Script! (MacOS)

I am working on Excel. We have a little over 25,000 excel WORKBOOKS that need 2 columns deleted from each of their sheets within. (Meaning if all 25k had 1 sheet, we should be deleting 50k columns.) But most of them have multiple sheets in them.
So far this is what I have...
set sourcefilepath to (choose folder) as alias
tell application "Finder" to set sourcefiles to ¬
(every file in the folder sourcefilepath whose ¬
name ends with ".xlsx") as alias list
tell application "Finder"
set filecount to count files in the entire contents of sourcefilepath
tell application "Microsoft Excel" to open the sourcefiles
repeat filecount times
set myValues to "Prod Alpha, Warehouse No"
tell application "Microsoft Excel"
activate
set mysheets to every sheet of active workbook
repeat with asheet in mysheets
tell asheet
set columnCount to (((count of columns of used range of active sheet)) + 1)
repeat with i from columnCount to 1 by -1
set cellValue to value of row 1 of column i
if cellValue is in myValues then
delete column i
end if
end repeat
end tell
end repeat
close active workbook
end tell
end repeat
end tell
This is now working. It opens all the files (Very slow for obvious reasons). Deletes the two columns I need gone in one, closes it and moves to the next. Problem is... about 30% of the way done, it will just stop. Leaving a ton of files open, and thus a very unresponsive computer. I have to force quit excel.
I know I could break them up into smaller folders and do it that way, but I want to learn how to make this solution better so in the future, I can work towards a solution in a better manner.
My thoughts are that I need to not open all the files at once. Open them separately. Fix it, Save it, Close it, then move to the next.
If programming in any other language, I would accomplish this using a for loop and traversing an array, but for the life of me cannot figure out how to do it with apple script. (Im super new to this apple script stuff).
Any help would be appreciated!
Thanks,
K
Generally speaking, don't script the Finder unless you absolutely have to; In particular, don't ever use the entire contents property. Use System Events and iteration instead. The Finder is an old and very busy app. It tends to freeze up if it gets overworked by a script, and entire contents almost always overworks it.
I've reworked your script with that in mind:
Used System Events for the file system tasks
Used Excel's built-in find function find the correct cells, not a repeat loop
Used iterative function calls to drill down through the folders
I doubt this will be all that fast (for the obvious reasons, but I don't see any way to speed the process up at the moment. I'll think on it...
set sourcefilepath to (choose folder) as alias
my iterateFolder(POSIX path of sourcefilepath)
on iterateFolder(aFolderPath)
tell application "System Events"
set fileList to every file of folder aFolderPath whose name extension is "xlsx"
repeat with anExcelFile in fileList
my processFile(POSIX path of anExcelFile)
end repeat
set folderList to every folder of folder aFolderPath
repeat with aFolder in folderList
my iterateFolder(POSIX path of aFolder)
end repeat
end tell
end iterateFolder
on processFile(aFilePath)
set myValues to {"Prod Alpha", "Warehouse No"}
tell application "Microsoft Excel"
-- you don't actually need to activate the workbook, not unless you want to watch it work
activate
open aFilePath
tell workbook 1
set sheetList to its sheets
repeat with aSheet in sheetList
repeat with aColumnName in myValues
set deletableHeaderRange to find (first row of used range of aSheet) what aColumnName look at whole
set deletableColumnRange to entire column of deletableHeaderRange
delete deletableColumnRange
end repeat
end repeat
end tell
close active workbook
end tell
end processFile
This is what I ended up with. I thank you #Ted Wrigley for your response. I don't understand the POSIX thing yet!. I added it to my list of stuff to study this week.
I am going to look into the built in excel functions, such as the find one you mentioned. I will post again if I am able to update it!
tell application "Finder" to set sourcefiles to ¬
(every file of (choose folder) whose ¬
name extension is "xlsx") as alias list
set filecount to count sourcefiles
repeat with each_file from 1 to filecount
tell application "Microsoft Excel"
activate
open item each_file of sourcefiles
set myValues to {"Prod Alpha", "Warehouse No"}
set mysheets to every sheet of active workbook
repeat with asheet in mysheets
tell asheet
set columnCount to (((count of columns of used range of active sheet)) + 1)
set delete_count to 0
repeat with i from columnCount to 1 by -1
set cellValue to value of row 1 of column i
if cellValue is in myValues then
delete column i
set delete_count to delete_count + 1
end if
if delete_count = 2 then
set delete_count to 0
exit repeat
end if
end repeat
end tell
end repeat
close active workbook with saving
end tell
end repeat

Rename duplicated file with applescript based on excel/txt list

I am having some issues with making a duplicating and renaming a list of files based on an excel file.
In the excel file in column 1 there is the original name. In column 2 I put in the new name.
There is a base folder with a lot of images, only the images in the excel file should be duplicated and renamed.
It is important that the duplicating and the renaming is done at once, because it is possible that the same base file is needed more than once in the destination file.
Tried a lot with renaming, but I only get the copying working.
set listFile to POSIX path of (choose file)
set dataList to paragraphs of (read listFile as «class utf8»)
tell application "Finder"
set ImageFile to "Macintosh HD:Users:joostjenneskens:Pictures:Base"
set theFolder to "Macintosh HD:Users:joostjenneskens:Pictures:Destination"
repeat with thisFileName in dataList
with timeout of 1200 seconds
duplicate (files of folder ImageFile whose name starts with (thisFileName as text)) to theFolder with replacing and exact copy
end timeout
end repeat
end tell
Thanks in advance for your help.
rename the duplicate values in excel or txt file format.
In your script, there is nothing about the destination file names. I assume every line in tour table contains a pair of tab-separated filenames
You should extract every items's columns with something like this :
set AppleScript's text item delimiters to {tab} -- or ";" for CSV
copy (every text item of thisFileName) to {sourceFileName, destinationFileName}
set AppleScript's text item delimiters to {} -- dirty reset (you should save/restore the previous settings)
then you can use the two variables sourceFileName and destinationFileName
and compute the full paths sourceFullPathName and destFullPathName
I would try this for the copy action
log "Copying" & space & sourceFileName & " to " & destinationFileName
do shell script "cp" & space & quoted form of posix path of sourceFullPathName & space & quoted form of posix path of destFullPathName
type "man cp" in your terminal to select suitable options (with "cp -v")
BTW it could be possible to create links or aliases with "ln" instead of "cp"
the terms
(files of folder ImageFile whose name starts with (thisFileName as text))
should return a list of source files…
With the "cp" mode you should add a nested loop to copy them, but how to figure out what's the destination name ?
hope this could help…

Save workbook generated from an Excel Template in different locations

I have an Excel xltm template which is used to produce workbooks that must be saved in one of two folders depending on the value the user enters into a specific cell in the workbook. I know how to determine the content of the cell and therefore make a decision as to which folder to save the workbook in and the destination folders will always be in the same location relative to the folder where the template is stored. However, different users may have the template folder and destination folders on different drives so I cannot use a hard coded path for the destination folders in the macro. I know I could open a file dialog and get the user to select the folder but would prefer to have the macro perform the save directly. I've tried using ThisWorkbook.Path but this doesn't work as there is no path associated with the workbook when it is created from the template. Any ideas would be appreciated.
If the amount of available (or varying) drives is reasonably limited, you can hard code the expected drives into an Array and run a loop checking if each drive/file path combination is available.
When the file path is available, the book will save and the loop will end.
Maybe something like this:
Sub SaveMe()
Dim FilePath As String: FilePath = "\Users\urdearboy\Documents\"
Dim Drive, i As Long
Drive = Array("D:", "Z:", "C:")
For i = LBound(Drive) To UBound(Drive)
If PathExists(Drive(i) & FilePath) Then
ThisWorkbook.SaveAs (Drive(i) & FilePath & "Book Name Here" & ".xlsx")
Exit For
End If
Next i
End Sub
Function to test if folder path exists
Function PathExists(path As String) As Boolean
If Dir(path) <> vbNullString Then
PathExists = True
End If
End Function
If you do decide to use this, I would just keep this procedure separate from your other code and call this sub when it is time to save a new book. Of course you will need to pass your variable Folder path (and probably a book name) into the above macro. Then, this should be able to save with dynamic drive & folder locations
Update - not quite the solution unfortunately! I assumed Environ("OneDriveCommercial") would return the path of the users Sharepoint folder but it doesn't - it returns the path to the users personal OneDrive folder, the same as Environ("OneDrive"). There appears to be no environment variable for finding the location of the Sharepoint folder. Instead, I used filepath = Left(Environ("OneDrive"), Len(Environ("OneDrive")) -24) & "xxxx" This gets a string equal to the path of where the user's personal OneDrive folder is, removes the characters (24 in my case) equal to the OneDrive folder name (and thus at the start of the sharepoint folder) and then appends the string (shown as xxxx) which is the remainder of the path to the required folder within the sharepoint folder.
So, for example, for User1 in company named Company Name1:
If their Personal One Drive folder is at C:\Users\User1\OneDrive - Company Name1 and their Sharepoint folder is at C:\Users\User1\Company Name1, Environ("OneDrive") returns C:\Users\User1\OneDrive - Company Name1 and filepath = Left(Environ("OneDrive"), Len(Environ("OneDrive")) -24) & "xxxx" removes the characters OneDrive - Company Name1 and the appends the characters xxxx set to equate to the path to the required folder in the sharepoint folder. This starts with Company Name1 followed by the rest of the path.

Kill path file not found

I am trying to delete all files in the below folder. However error comes up as
run time error 75: path/file not found
However a couple of things to note:
It does delete some files, but the same ones it never deletes
The path does exist
Code:
Sub deleteprevfixing()
'First delete file contents
Dim aFile As String
aFile = "R:\samsfiles\sam\!test\*.*"
If Len(Dir$(aFile)) > 0 Then
Kill aFile
End If
End Sub
If you want to delete all files in the folder (as your question suggests you want to), you need to keep looping and calling dir(). Otherwise, you will only delete the first file returned by dir().
Option Explicit
Sub DeleteAllFilesInFolder()
Dim folderPath As String
folderPath = "R:\samsfiles\sam\!test\"
Dim Filename As String
Filename = VBA.FileSystem.Dir$(folderPath & "*.*", vbNormal) ' The "*.*" here isn't really necessary, but I'll leave it as is.
Do Until Len(Filename) = 0
Kill folderPath & Filename
Filename = VBA.FileSystem.Dir$()
Loop
End Sub
All sorted - thanks to all. It was because I had to turn off the "Are you sure you want to permanently delete this file?" dialog when deleting from a network share or mapped drive.
Here is a solution how to do it (copied from source below)
Map a network drive to the network share you want to use. Make sure
that the drive is re-connected on logon.
Browse to C:\users\<username>.
Right-click on one of the folders in this location (any
folder such as "links") and click properties.
Select the Location tab.
Click Move, browse to root of the drive you mapped in step 1,
and click Select Folder.
Click Ok and click yes in the dialogue box
that appears.
Please see attached for original thread

How do I search for a folder and hyperlink its path?

I am working on a spreadsheet in which I will keep track of everything that my department 3D prints. I have 3 folders full of one thing each for every part I print: a CAD file, an STL file, and a job folder; all of these contain the same part name which is entered into a cell in the spreadsheet and used for finding all of the files/folders. I like to have my spreadsheet hyperlinked so that I can easily open up any of the three by simply navigating to that part in my spreadsheet.
Now I have the following section of code which takes the name of the printed part from column D, and finds the matching STL in my STL folder, and then hyperlinks it into column U.
For i = 4 To Range("D" & Rows.Count).End(xlUp).Row
'follow through all entries in column D
'--STL------------------------------------------------------------------------------------------------------
If (Len(Cells(i, 4)) > 1) Then
If (Len(Cells(i, 21)) = 0) Then
strFile = Dir$(path5w & Cells(i, 4) & "*.stl")
If (Len(strFile) > 1) Then
Cells(i, 21).Hyperlinks.Add Cells(i, 21), path5 & strFile, TextToDisplay:="STL"
Else
'No file was found that matches so do nothing
End If
Else
'Already hyperlinked, skip this cell
End If
Else
'Not a valid Name, do nothing
End If
Next
End Sub
I simply copied this chunk of code again and switched the path and switched .STL the extension for my CAD files, and it works great for both of those, but I am getting stuck on the job folders... I have no idea how to get my code to find a folder instead of a file.
I have tried playing around with FileSystemObjects, but I don't fully understand how to use them, and all I can find is an example of how to list every folder inside a folder, and not how to actually search for a specific folder.
I also looked at this example: VBA to find multiple files but, again, I run into the problem of not understanding how to use this to search for a folder, rather than listing all folders.
So to help be more clear I will give an example. Lets say I process Part123.stl, when I want to save this, it will create a folder ssys_Part123 and I will save that in my folder named Job Folders. Now I want my program to check cell D4 which says Part123, then navigate to Job Folders, find the folder named ssys_Part123 and hyperlink that folder into V4.
I still don't have a very firm grasp of coding, so any help is always greatly appreciated.
If the folder name is always going to be ssys_[PartName] then you should be able to just concact the strings to link to the folder instead of trying to look up the folder name.

Resources