Reorder selection of files - vba

I have created an Excel Macro at work to be used for assembling consolidated reports in Excel. The macro allows you to select a number of files, it then goes through those files and renames the first tab in each file (which with the way it is used is the only tab) to match the file name (so you can rename the files without having to open all and rename tabs), and then merges all these tabs into your current workbook, creating a large consolidated report.
However, I am running into the problem that the macro defaults to do this to the selected files in the alphabetical order of the file names, which then requires us to sort the tabs after we have run the macro.
What I am looking for is an adjustment to the macro that will sort the files by creation date&time, oldest to newest, because the order the files are created generally matches the desired result in our final reports.
I figure I will need to make a separate for i = 1 to etc loop that re-orders the selected files, store the new order, and use that order for the current loop, but I am not sure how to do that. I did to some searches, but while I found some similar items, anything similar seems to use a folder selection rather than individual file selection, and there were other differences I couldn't quite translate to my macro either. Here is the current macro:
Sub Reports()
Dim numberOfFilesChosen, i As Integer, Workbookname As String, tempFileDialog As FileDialog, mainWorkbook, sourceWorkbook As Workbook
Dim tempWorkSheet As Worksheet
Set mainWorkbook = Application.ActiveWorkbook
Set tempFileDialog = Application.FileDialog(msoFileDialogFilePicker)
tempFileDialog.AllowMultiSelect = True
numberOfFilesChosen = tempFileDialog.Show
Application.ScreenUpdating = False
For i = 1 To tempFileDialog.SelectedItems.Count
Workbooks.Open tempFileDialog.SelectedItems(i)
Set sourceWorkbook = ActiveWorkbook
With sourceWorkbook
Workbookname = Left(.Name, InStr(.Name, ".") - 1)
.Sheets(1).Name = Workbookname
End With
For Each tempWorkSheet In sourceWorkbook.Worksheets
tempWorkSheet.Copy after:=mainWorkbook.Sheets(mainWorkbook.Worksheets.Count)
Next tempWorkSheet
sourceWorkbook.Close savechanges:=False
Next i
Application.ScreenUpdating = True
End Sub
I hope you can help me, thank you!

Related

Merging multiple different worksheets into master template with weird formatting

This might seem a bit complicated, so let me know if I need to be more clear.
I receive ~20 reports from one department and I am in charge of consolidating data from a specific worksheet in each report into one master file. All the reports are the exact same and the data ranges are pretty much set. I am relatively new to VBA, but I was able to piece together a code through research to copy and paste all the data into a new workbook using a loop. It would, however, be ideal if I could put this data directly into the report template. This is where I need help. The formatting of the template is not ideal - my headers don't start until A25 and there's a totals tab and instructions on the bottom so I can't just put the values in the last empty row.
I would like to figure out how to ensure that the data from the first worksheet I pull from gets put in A26 and the data from the following worksheets get put in the next available cell.
Below is the code I currently have. I understand generally what things mean, but just keep in mind I'm a VBA noob... so be nice :)
Sub MergeData()
Dim FileName As String, FilePath As String, FolderPath As String
Dim LastCell As Range
With ThisWorkbook.Worksheets("Sheet1")
Set LastCell = .Cells(.Rows.Count, 1)
End With
FolderPath = "C:\Desktop" 'changed for privacy
FilePath = FolderPath & "*.xls*"
FileName = Dir(FilePath)
Do While FileName <> ""
With Workbooks.Open(FolderPath & FileName)
Worksheets("SBP WIP").Range("A26:AK336").Copy
LastCell.End(xlUp).Offset(1).PasteSpecial xlPasteValues
ActiveCell.Copy
.Close False
End With
FileName = Dir
Loop
End Sub
Thanks!
In your first With-End With block just add one line
With ThisWorkbook.Worksheets("Sheet1")
.Range("A25").Value = "X" ‘ make sure to hit row 25 in subsequent “xlUps”
Set LastCell = .Cells(.Rows.Count, 1)
End With
And before macro ending add:
ThisWorkbook.Worksheets("Sheet1").Range("A25").ClearContents

Comparing columns in different excel 2013 files and deleting the duplicates from one of the workbooks (need macro)

This is my first question on this site and I'm not a programmer, so please bear with me.
I am trying to create an Excel 2013 macro that will compare values in column A on one workbook ("active workbook") to column A's of other Excel files in a particular directory. Duplicate values (rows) would then be deleted from the active workbook.
I have been working piece by piece trying to figure this out as I am not a programmer. So far I have been able to use conditional formatting to highlight unique values when the two columns are side by side (same worksheet). I used =ISNA(MATCH($A2,$B$2:$B$12,0)).
Then I used a macro to print out the duplicate values to another column (instead of highlighting them.. I am still at this stage comparing two columns within the same worksheet). I did this by using the following macro:
Sub Find_Matches()
Dim CompareRange As Variant, x As Variant, y As Variant
' Set CompareRange equal to the range to which you will
' compare the selection.
Set CompareRange = Range("C1:C12")
' NOTE: If the compare range is located on another workbook
' or worksheet, use the following syntax.
' Set CompareRange = Workbooks("Book2"). _
' Worksheets("Sheet2").Range("C1:C5")
'
' Loop through each cell in the selection and compare it to
' each cell in CompareRange.
For Each x In Selection
For Each y In CompareRange
If x = y Then x.Offset(0, 1) = x
Next y
Next x
End Sub
Then I tried removing duplicate values from two different worksheets but that didn't work:
Sub ProcessFiles()
Dim Filename, Pathname As String
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim Sheet As Worksheet
Dim PasteStart As Range
Dim Counter As Integer
Set wb1 = ActiveWorkbook
Set PasteStart = [RRimport!A1]
Pathname = ActiveWorkbook.Path & "\For Macro to run\"
Filename = Dir(Pathname & "*.xls")
Do While Filename <> ""
Set wb2 = Workbooks.Open(Pathname & Filename)
For Each Sheet In wb2.Sheets
With Sheet.UsedRange
.Copy PasteStart
Set PasteStart = PasteStart.Offset(.Rows.Count)
End With
Next Sheet
wb2.Close
Filename = Dir()
Loop
End Sub
I've been reading this site for couple of days and also searched through YouTube. I haven't had much success after the first two basic things I did.
Background of the project: Everyday we have a list called "Pending List" which essentially is all of the projects we need to get done. Everyday this list grows. Each project is given a unique identifier (numeric value) that is listed in column A of the active workbook. Every day I create my own files of the projects that are being completed. Instead of manually checking off each project one by one by comparing several files every day, I would like Excel to be able to delete the duplicates (meaning the projects that are both on my pending list and in the other files, and only leave the unique projects that still need to be done. Hope I didn't confuse anyone but if I did, please let me know.
The question here:
I am trying to create an Excel 2013 macro that will compare values in
column A on one workbook ("active workbook") to column A's of other
Excel files in a particular directory. Duplicate values (rows) would
then be deleted from the active workbook.
So, let's break this down:
There is a directory from which workbooks need to be opened.
When one of the workbooks is open, you want to check column A (I assume this is on the first worksheet for the sake of the example below) for values you have in column A in your active workbook (the one that will run the macro).
If there's a match, delete the row from the active workbook in which the value was stored.
When done, continue with the next workbook in the directory.
Point 1 and 4: Open some files from a specific directory:
We will need some function to open and close the files. This question has been asked many times on SO, for example here
Also, we're going to need the workbooks to be stored in some variable that we will pass to the comparison in the next step.
Public Sub LoopOverFiles()
'Our variables:
Dim wb1 As Workbook 'To hold the active workbook / the macro workbook
Dim wb2 As Workbook 'To hold the workbook we'll be comparing to later on
Dim scanFolder As String 'To set the folder in which the files will be located
Dim fileNameToOpen As String 'To get the filenames that we will open
Set wb1 = ThisWorkbook
scanFolder = "C:\temp\"
fileNameToOpen = Dir(scanFolder & "*.xlsx")
'And loop over the files:
Do While Len(fileNameToOpen) > 0 'To exit the loop when there's no more xlsx files
Set wb2 = Workbooks.Open(scanFolder & fileNameToOpen)
'To do the actual comparison of the 2 workbooks, we call our compare routine.
DoTheComparison wb1, wb2 'Note we'll be passing the two workbooks as parameters to the compare function
wb2.Close SaveChanges:=False 'We don't want to leave it open after we're done with it.
fileNameToOpen = Dir 'To continue with the next file.
Loop
End Sub
Point 2 and 3: Do the comparison and delete some rows
As you can see, the actual comparison will be done by a routine that's called DoTheComparison and that takes 2 workbooks as parameters. Based on the first routine, we know that the workbooks that will be passed are the correct ones (wb1 being the active one, wb2 being the variable one that gets opened during the loop).
In this example we'll stick to the first worksheet in wb2.
Public Sub DoTheComparison(wb1 as Workbook, wb2 as Workbook)
'Dim compareFrom as Range - Not needed.
Dim compareTo as Range
Dim compareFromCell as Range
Dim compareToCell as Range
Dim i as Integer
'EDIT: Since we delete, we need a backwards loop. This can't be done with "for each" so we'll use "for" with step -1.
'That is why we also don't need the "CompareFrom" range variable anymore.
Set compareTo = wb2.Worksheets(1).Range("A2:A20")
For i = 20 to 2 step -1
Set compareFromCell = wb1.Worksheets("RemoveValsFromHere").Range("A" & i) 'We get the cells based on the index.
For Each compareToCell in compareTo
If compareFromCell.Value = compareToCell.Value Then 'Point 3:
compareFromCell.EntireRow.Delete shift:=xlUp
Exit For
'Note that we need to exit the inner loop:
'After a match was found, the "compareFromCell" is deleted after all.
'Therefore we have to continue with the next compareFromCell, otherwise we'll get an error.
End If
Next compareToCell
Next i
End Sub
Note that especially DoTheComparison is written for maximum clarity, not for optimal speed (far from it!). I see in your question you've been looking into comparing variants / arrays, which is indeed a lot faster.
EDIT: I altered the code above since you're facing the "skipping cells" issue due to cell deletion. In short: The index changes, so when moving to the next cell after deletion the index is wrong. The fix is an easy backwards for loop. Also see this question and answer

Excel macro to open a folder of excel workbooks and copy 1 cell

I have a folder of .xlsx files, each identical in layout.
I need to write a macro in excel to open each file in turn (100+ files)
then get the data (a name) from a single cell, and drop it in a new excel worksheet, move on to the next and insert that below the last one etc.
Giving me basically a list of names from data not file names)
Here is (pretty much) exactly what you're trying to do. Next time do a little bit of googling before you ask! :)
http://www.excel-easy.com/vba/examples/files-in-a-directory.html
ROUGH CODE UNSURE IF IT WILL WORK: But here is the basic idea of what you need to modify in the example I sent you. If you look at the example again, it does everything you need and then some. Since you weren't interested in all worksheets, you don't have to loop through all worksheets in a workbook. You can just open it up, read your cell of interest, and then close it. The Do While loop will do this for every Excel file in your directory. AGAIN! Please modify this example accordingly before you use it.
Dim directory As String, fileName As String, sheet As Worksheet, i As Integer, j As Integer
Application.ScreenUpdating = False
directory = "c:\test\"
fileName = Dir(directory & "*.xl??")
Do While fileName <> ""
i = i + 1
Workbooks.Open (directory & fileName)
Workbooks("files-in-a-directory.xls").Worksheets(1).Cells(i, 1).Value = Workbooks(fileName).Worksheets(1).Cells(x, y) <-- whatever your cell of interest is
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True

Combine multiple Excel workbooks into a single workbook

I am a novice at Visual Basic. I can use either Excel 2010 or Excel 2013 for this task.
I have dozens of workbooks with data on the first worksheet of each. For example One.xlsx, Two.xlsx, Three.xlsx, Four.xlsx each contain information on their respective Sheet1.
I need the information on Sheet1 from each workbook to be combined into a single workbook with sheets that are named from the file name of the original workbook. So for example combined.xlsx would have 4 sheets named One, Two, Three, Four. In every case all information on the underlying worksheets should be copied and combined in the new Workbook as shown below.
The Format I need
I found this Macro / Add-In online that gets me close to what I need using the open files add in choice.
http://www.excelbee.com/merge-excel-sheets-2010-2007-2013#close
The Open Files Add-In successfully allows me to aggregate the various Workbook's worksheets into a single workbook. However the tabs are not named from the name of the original file.
Correct aggregation of sheets, but incorrect worksheet names.
For now all the underlying Workbooks will be in the same folder. The ability to browse and select the files would be nice if this ever changes but if that is too difficult, just indicating the directory path in the Visual Basic code would work. As far as the resultant combined output probably ought to be a new workbook, the filename of the new workbook isn't that important. It could be called combined.xlsx for example.
The following accomplishes the task.
Option Explicit
Private Sub CommandButton1_Click()
Dim directory As String, fileName As String, sheet As Worksheet, total As Integer
Dim WrdArray() As String
Application.ScreenUpdating = False
Application.DisplayAlerts = False
directory = "c:\test\"
fileName = Dir(directory & "*.xl??")
Do While fileName <> ""
Workbooks.Open (directory & fileName)
WrdArray() = Split(fileName, ".")
For Each sheet In Workbooks(fileName).Worksheets
Workbooks(fileName).ActiveSheet.Name = WrdArray(0)
total = Workbooks("import-sheets.xlsm").Worksheets.Count
Workbooks(fileName).Worksheets(sheet.Name).Copy after:=Workbooks("import-sheets.xlsm").Worksheets(total)
GoTo exitFor:
Next sheet
exitFor:
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
In Excel press Alt+F11, this will open the Excel VBA editor.
Article http://www.excel-spreadsheet.com/vba/debugging.htm explains some basics how to use it.
In Module1 there are 2 short subroutines opensheets and merge containing ~50 lines of code.
Use F1 with cursor within words you don't understand, to learn what it means.
Once you understand what the code does, you can tailor it to your needs.

Create a new workbook and paste data 3 different workbooks one after the other

I have a question (incidentally I have multiple questions, which will be posted later) regarding Creating a new workbook and paste data 3 different workbooks one after the other.
This is a part of daily routine, where concerned people will be posting 3 different sets of data in 3 different folders. File names will be given based on date. Example: My book 01 22, NT book 01 21 etc.
Instead of manually taking each file and copying data into one single sheet, I want to use a Macro to create a new workbook, save it as per the date and copy data from the 3 different workbooks stored in different folders, one after the other in one single sheet.
Below is the code I am using:
Sub Main()
Dim fd As FileDialog
Dim SelectedItem As Variant
Set NewBook = Workbooks.Add
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = True
If .Show = -1 Then
For Each SelectedItem In .SelectedItems
Workbooks.Open (SelectedItem)
'Workbooks.Application.Worksheets("Sheet1").Copy
Workbooks("NewBook").Activate
LastRow = ActiveSheet.UsedRange.Rows.Count
MsgBox (LastRow)
NewBook.Worksheets("Sheet1").Cells(LastRow + 1, 1).PasteSpecial (xlPasteValues)
LastRow = ActiveSheet.UsedRange.Rows.Count
MsgBox (LastRow)
Next SelectedItem
End If
End With
Set fd = Nothing
End Sub
You could use the macro recorder (http://m.dummies.com/how-to/content/how-to-record-a-macro-to-automate-tasks-in-excel-2.html). It simply reproduces the steps you do manually in Excel as VBA-Code. You can use that as a first step if you dont know much about VBA. Look at the code and try to alter it. I often use it if I dont know the VBA Commands for standard Excel Features.