Combine Worksheets Into New Workbook Based on Criteria and Save - vba

I have a workbook made up with 100+ worksheets. These worksheets have account number/names/days in the name of the worksheet.
The naming convention for the worksheets follows this pattern of AccountNumber/AccountName/Description:
11-Greg-Monday
11-Greg-Tuesday
11-Greg-Friday
38-Rachel-Sunday
38-Rachel-Tuesday
38-Rachel-Saturday
I would like Excel to loop through all the worksheets, and extract all of the 11-Greg worksheets and save into a new workbook named 11-Greg, and then do the same for 38-Rachel, etc. I have a list of the account numbers/names on a worksheet named "Accounts" in the workbook.
Would it be possible to maintain the formulas after the extract of the worksheets, and formatting like column widths?
I found this code that might work to start, but I don't know how to reference the list on the "Accounts" tab to loop through for the account names?
Dim wb as Workbook, sht as WorkSheet
Dim strFileName As String
'Copy sheet as a new workbook
ActiveWorkbook.Sheets("Sheet1").Copy
Set wb = ActiveWorkbook
Set sht = wb.Sheets(1)
'SaveAs
strFileName = Application.GetSaveAsFilename(wb.Name) & "xlsx"
If strFileName = "False" Then Exit Sub 'User Canceled
wb.SaveAs Filename:=strFileName

The easiest way would be to create a list of the names you want to stack on a separate list. set that list as a range and then loop through each cell checking to see if the x letters of the sheet name match. something like this
Sub stacksheets()
Dim rng As Range, cCell As Range
Dim ws As Worksheet
Dim wb As Workbook, wb2 As Workbook
Dim shName As String
Set rng = ActiveWorkbook.Sheets("list").Range("a1:a2") ''this would be the list of names
Set wb2 = ActiveWorkbook ''remembering activeworkbook so can return
For Each cCell In rng
shName = Left(cCell.Value, 5) ''this needs to be the minimum letters from each name that is unique
Set wb = Workbooks.Add
For Each ws In wb2.Sheets
If InStr(ws.Name, shName) > 0 Then ''checks for name in sheet name
ws.Copy after:=wb.Sheets(1)
wb2.Activate
End If
Next ws
wb.SaveAs (wb2.Path & "\" & cCell.Value) '' saves workbook as list name
Next cCell
End Sub

Related

Match columns in 2 worksheets and paste to a third worksheet

I have numbers in no specific order on 2 worksheets (wb1 and wb2). If there is a match, I need the email address in column b on wb2 to paste to the worksheet wb3 in column A. The code I have below only matches the numbers if they are in the same cells on both worksheets. Any help is greatly appreciated.
Private Sub CommandButton2_Click()
'Merge Report button
Dim foundCell As Range
Dim strFind As String
Dim fRow, fCol As Integer
Dim wb1 As Worksheet
Dim wb2 As Worksheet
Dim wb3 As Worksheet
'Set sheets - wb1 is email list and wb2 is missed punch report, and wb3 is home page
Set wb1 = Sheets("Sheet1")
Set wb2 = Sheets("Sheet1 (2)")
Set wb3 = Sheets("Home")
'Get find string
strFind = wb1.Range("A1").Value
'Find string in column C of Sheet2
Set foundCell = wb2.Range("A1").Find(strFind, LookIn:=xlValues)
'If match cell is found
If Not foundCell Is Nothing Then
'Get the row and column
fRow = foundCell.Row
fCol = foundCell.Column
'copy email from column b
wb1.Range("B1").Copy
'paste in column a on home page
wb3.Range("A1").PasteSpecial xlPasteValues
'Clear cache
Application.CutCopyMode = False
'If not found, show message.
Else
Call MsgBox("No match was found. Clear form and start over with step 1.")
End If
End Sub

Copy cell range between workbooks from same folder

I currently have:
Sub Ranger()
Dim rng As Range
Dim WB1 As Workbook, WB2 As Workbook, ActiveWB As Workbook
Dim WS1 As Worksheet, WS2 As Worksheet
Dim FName As String
FName = "General Text"
Set WB1 = ThisWorkbook
Set WS1 = WB1.Sheets("Sheet1")
Set WB2 = Workbooks.Open(FileName:=FName)
Set WS2 = WB2.Sheets(1)
With WS2
Set rng = .Range(Range("A1"), Range("A5"))
End With
With WS1
rng.Copy .Cells(1, 1)
End With
WB2.Close
End Sub
Which aims to copy the range A1:A5 in the newly opened workbook into the original workbook (ThisWorkbook). It currently opens the second workbook but does not copy anything into the first workbook. There are also no errors and I would like to avoid using specific names in setting WB1/WB2 as WB2 could be either .xls or .xlsx
Try this, it works for me:
Sub Ranger()
Dim rng As Range
Dim WB2 As Workbook
Dim FName As String
FName = "D:\Tuchanka\Temp\pelda.xlsx"
Set WB2 = Workbooks.Open(Filename:=FName)
ThisWorkbook.Worksheets(1).Range("A1:A5").Value = WB2.Worksheets(1).Range("A1:A5").Value
WB2.Close
End Sub
Using variables and with statements is pointless in your situation, as instead of making your code simpler and easier to read, they just add a lot of gibberish and make your code seem way too complex. Only use these if you need them.

VBA Copy data from one sheet to another

I'm pretty new to VBA and need some help with a project. I need to write a macro that reads the Sheet Name in Column C, and pastes the values from a source workbook to a range in a target workbook, which is specified in Column D.
So for example, it needs to copy the data in Sheet2 of Myworkbook book, and paste it into range of Theirworkbook Sheet2. The place where the range and sheet number information is stored in a separate workbook.
Edit: I've added a picture of what wbOpen looks like. This is it here.
Option Explicit
Sub PasteToTargetRange()
Dim arrVar As Variant 'stores all the sheets to get the copied
Dim arrVarTarget As Variant 'stores names of sheets in target workbook
Dim rngRange As Range 'each sheet name in the given range
Dim rngLoop As Range 'Range that rngRange is based in
Dim wsSource As Worksheet 'source worksheet where ranges are found
Dim wbSource As Workbook 'workbook with the information to paste
Dim wbTarget As Workbook 'workbook that will receive information
Dim strSourceFile As String 'location of source workbook
Dim strTargetFile As String 'location of source workbook
Dim wbOpen As Workbook 'Current open workbook(one with inputs)
Dim wsRange As Range 'get information from source workbook
Dim varRange As Range 'Range where values should be pasted
Dim i As Integer 'counter for For Loop
Dim wbkNewSheet As Worksheet 'create new worksheet if target workbook doesn't have
Dim wsTarget As Worksheet 'target workbook worksheet
Dim varNumber As String 'range to post
Set wbOpen = Workbooks.Open("WorkbookWithRanges.xlsx")
'Open source file
MsgBox ("Open the source file")
strSourceFile = Application.GetOpenFilename
If strSourceFile = "" Then Exit Sub
Set wbSource = Workbooks.Open(strSourceFile)
'Open target file
MsgBox ("Open the target file")
strTargetFile = Application.GetOpenFilename
If strTargetFile = "" Then Exit Sub
Set wbTarget = Workbooks.Open(strTargetFile)
'Activate transfer Workbook
wbOpen.Activate
Set wsRange = ActiveSheet.Range("C9:C20")
Set arrVarTarget = wbTarget.Worksheets
For Each varRange In wsRange
If varRange.Value = 'Target workbook worksheets
varNumber = varRange.Offset(0, -1).Value
Set wsTarget = X.Offset(0, 1)
wsSouce.Range(wsTarget).Value = varNumber
Else
wbkNewSheet = Worksheets.Add
wbkNewSheet.Name = varRange.Value
End If
Next
End Sub
Something like this (untested but should give you an idea)
Sub PasteToTargetRange()
'....omitted
Set wsRange = wbOpen.Sheets(1).Range("C9:C20")
For Each c In wsRange
shtName = c.Offset(0, -1).Value
Set wsTarget = GetSheet(wbTarget, shtName) 'get the target sheet
wbSource.Sheets(shtName).Range(c.Value).Copy wsTarget.Range(c.Value)
Next
End Sub
'Get a reference to a named sheet in a specific workbook
' By default will create the sheet if not found
Function GetSheet(wb As Workbook, ws As String, Optional CreateIfMissing As Boolean = True)
Dim rv As Worksheet
On Error Resume Next 'ignore eroror if no match
Set rv = wb.Worksheets(ws)
On Error GoTo 0 'stop ignoring errors
'sheet wasn't found, and should create if missing
If rv Is Nothing And CreateIfMissing Then
Set rv = wb.Worksheets.Add(after:=wb.Worksheets(wb.Worksheets.Count))
rv.Name = ws
End If
Set GetSheet = rv
End Function

Excel Macro to name ranges according to the name of the worksheet Tab name

I have the following code which I am trying to get to name the entire A and B columns range according to the worksheet tab name. I want each A:B range of cells in each worksheet to be named RoomCode_ + the name of the excel sheet tab.
So for example if I had 3 sheets called XYZ, ABC and DEF, then my cell range names for those 3 sheets respectively should be:
RoomCode_XYZ
RoomCode_ABC
RoomCode_DEF
I would typically do this manually by highlighting the cell range and just typing the range name I wanted, however I have over 150 tabs and would like to be able to do them all automatically through this process.
Sub nameRanges()
Set wbook = ActiveWorkbook
For Each sht In wbook.Worksheets
sht.Activate
RangeName = "RoomCode_" + ActiveSheet.Name
CellName = "A:B"
Set cell = ActiveWorksheets.Range(CellName)
ActiveWorksheets.Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub
Just a bit of refactoring to get what you need. Biggest this to work directly with objects and eliminate the Active... stuff.
Also ActiveWorksheets is not proper syntax in any way.
Sub nameRanges()
Dim wbook As Workbook
Set wbook = ThisWorkbook
Dim sht As Worksheet
For Each sht In wbook.Worksheets
Dim RangeName As String, CellName As String
RangeName = "RoomCode_" + sht.Name
CellName = "A:B"
Dim cell As Range
Set cell = sht.Range(CellName)
sht.Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub
Here's another way:
Option Explicit
Sub nameRanges()
Dim sht As Worksheet
Dim RangeName As String
Dim cell As String
For Each sht In ActiveWorkbook.Worksheets
RangeName = "RoomCode_" + sht.Name
cell = "=" & sht.Name & "!" & "A:B"
Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub
I think that you would want to add the names to the workbook names collection. The way it is now you'll still have to reference the individual worksheet before you can access the name.
WorkSheets("RoomCode").Range("RoomCode_XYZ")
By adding the names to the workbook you'll be able to access no matter the ActiveSheet.
Range("RoomCode_XYZ")
Sub nameRanges()
Dim wbook As Workbook
Set wbook = ThisWorkbook
Dim sht As Worksheet
For Each sht In wbook.Worksheets
Dim RangeName As String, CellName As String
RangeName = "RoomCode_" + sht.Name
CellName = "A:B"
Dim cell As Range
Set cell = sht.Range(CellName)
ThisWorkBook.Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub

Copy Data from one open Workbook into another open workbook

Following code:
Sub CopyData()
Dim Wb1 As Workbook, wb2 As Workbook
For Each wB In Application.Workbooks
If Left(wB.Name, 21) = "Open Order Monitoring" Then
Set Wb1 = wB
Exit For
End If
Next
Set wb2 = ThisWorkbook
Wb1.Sheets(1).Range("A2").Range(.Cells(1, 1), .End(xlDown).Cells(1, 39)).Copy wb2.Sheets(2).Range("B5")
End Sub
The macro should copy data from a open workbook with variable name (open order monitoring[...]) and paste into the second sheet of the workbook I run the macro from.
But the line:
Wb1.Sheets(1).Range("A2").Range(.Cells(1, 1), .End(xlDown).Cells(1, 39)).Copy wb2.Sheets(2).Range("B5")
gives me an error. can someone solve this problem?
since:
it's always safer to use fully qualified range references (down to workbook and worksheet ones). especially when you're dealing with multiple workbooks and/or worksheets
should you only be interested in pasting values, it's faster (and safer, too) use Range1.value = Range2.Value instead of .Copy() method of Range object.
then, here follows a possible code:
Option Explicit
Sub CopyData()
Dim Wb1 As Workbook, wb2 As Workbook, wB As Workbook
Dim rngToCopy As Range
For Each wB In Application.Workbooks
If Left(wB.Name, 21) = "Open Order Monitoring" Then
Set Wb1 = wB
Exit For
End If
Next
If Not Wb1 Is Nothing Then '<~~ check if you actually found the needed workbook
Set wb2 = ThisWorkbook
With Wb1.Sheets(1)
Set rngToCopy = .Range("A2:AM2", .Cells(.Rows.Count, "A").End(xlUp))
End With
wb2.Sheets(2).Range("B5:AN5").Resize(rngToCopy.Rows.Count).Value = rngToCopy.Value
End If
End Sub
Pls try with below code
Sub CopyData()
Dim Wb1 As Workbook, wb2 As Workbook, wb As Workbook
Set wb2 = ThisWorkbook
For Each wb In Workbooks
If Left(wb.Name, 21) = "Open Order Monitoring" Then
Set Wb1 = wb
Exit For
End If
Next
Wb1.Sheets(1).Range("A2:AM2").Copy wb2.Sheets(2).Range("B5") 'Edited here
End Sub