In this week’s edition of Q&A, learn how to move files on your computer, use AverageIf with filters and prevent users from closing their workbook with unprotected sheets.
Q1: How do I move a file from one folder to another using VBA?
To move a file from one folder to another, use the following code:
Sub MoveFile() Name "C:\test.txt" As "C:\Users\test.txt" End Sub
This example moves the file
Q2: I have hyperlinks to files in a spreadsheet. Is there a way to move these files to another location?
Absolutely! Here’s a simple version that assumes the cell containing the hyperlink is in “A1” of the active sheet. You can modify this to loop through an entire column of hyperlinks if you want. An example of a column loop is presented in my answer to Q3.
Sub MoveFile2() Dim strPath As String strPath = Range("A1").Hyperlinks.Item(1).Address Name strPath As "C:\Users\test.txt" End Sub
This macro reads the hyperlink address and moves the linked file to
Q3: I have a spreadsheet with file paths in Column A. I want to move the files to a specific folder and rename them with the name in Column B. Is that possible?
Anything is possible with VBA! This will do the trick for you. It copies the files mentioned in column “A” to the file names mentioned in column “B,” while preserving the same file extension the file originally held.
Sub CopyFile() Dim i As Integer, lastrow As Integer, iext As Integer lastrow = Range("a50000").End(xlUp).Row For i = 1 To lastrow iext = InStrRev(Range("a" & i), ".") FileCopy Range("a" & i), "C:\Users\Desktop\new data\" & Range("b" & i) & _ Mid(Range("a" & i), iext, Len(Range("a" & i))) Next i End Sub
Q4: I'm applying a filter but my AVERAGEIF() function averages all the values, including hidden values. How can I average only the visible values?
I recommend creating a custom function. Paste the following macro in your VBA editor:
Function AverageIfVisible(rng2check As Range, condition, rng2avg As Range) Dim i As Long Dim icount As Long For i = 1 To rng2avg.Count If rng2check(i) = condition And rng2avg(i).EntireRow.Hidden = False Then icount = icount + 1 AverageIfVisible = (AverageIfVisible + rng2avg(i)) End If Next i AverageIfVisible = AverageIfVisible / icount End Function
This function behaves like the AVERAGEIF() function. It accepts 3 arguments:
- The range to check
- The criteria to check against
- The range to actually average
If your original formula was
=AVERAGEIF($A$2:$A$100,B1,$C$2:$C$100), change it to
=AverageIfVisible($A$2:$A$100,B1,$C$2:$C$100) to only look at visible cells. Cells hidden by your filter will be ignored!
Q5: How do I prevent the user from closing the Excel workbook if his/her worksheet is unprotected?
Try placing the following VBA macro in the ThisWorkbook section of your VBA editor:
Private Sub Workbook_BeforeClose(Cancel As Boolean) Dim X As Boolean X = False If ActiveSheet.ProtectContents Then X = True If ActiveSheet.ProtectDrawingObjects Then X = True If ActiveSheet.ProtectScenarios Then X = True If ActiveSheet.ProtectionMode Then X = True If X = False Then MsgBox "The worksheet is not protected." Cancel = True Else MsgBox "The worksheet is protected." End If End Sub
Cancel = True line blocks the user from closing the file, so be kind! You can really frustrate people with this line of code by preventing them from ever closing their workbook:)
This is the first of what I hope to many Q&A posts. When you’re ready to take your VBA to the next level, subscribe using the form below.