Creating New Excel Sheets for Each Row in a Worksheet - excel

I am working on an Excel workbook in which I would like the workbook to create a new sheet for each new row of data. The code below does do this, but the problem is that Excel uses the text in the first column of each row as the name for the new sheets. I would like to change this and make another column the source for the new sheet name. Please advise on which line(s) I would need to change to accomplish this. Thanks for the help!
Sub Parse_data()
Dim xRCount As Long
Dim xSht As Worksheet, xNSht As Worksheet
Dim I As Long
Dim xTRrow As Integer
Dim xCol As New Collection
Dim xTitle As String
Dim xSUpdate As Boolean
Set xSht = ActiveSheet
xRCount = xSht.Cells(xSht.Rows.Count, 1).End(xlUp).Row
'xTitle = "C1:C1"
'xTRrow = xSht.Range(xTitle).Cells(1).Row
For I = 2 To xRCount
On Error Resume Next
Call xCol.Add(xSht.Cells(I, 1), xSht.Cells(I, 1))
Next
On Error Resume Next
xSUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To xCol.Count
Call xSht.Range(xTitle).AutoFilter(1, CStr(xCol.Item(I)))
Set xNSht = Nothing
Set xNSht = Worksheets(CStr(xCol.Item(I)))
If xNSht Is Nothing Then
Set xNSht = Worksheets.Add(, Sheets(Sheets.Count))
xNSht.Name = CStr(xCol.Item(I))
Else
xNSht.Move , Sheets(Sheets.Count)
End If
xSht.Range("A" & xTRrow & ":A" & xRCount).EntireRow.Copy xNSht.Range("A1")
xNSht.Columns.AutoFit
Next
xSht.AutoFilterMode = False
xSht.Activate
Application.ScreenUpdating = xSUpdate
End Sub

Try this. I added another collection, yCol, which contains data from a different column but which uses the same key as xCol.
Sub Parse_data()
Dim xRCount As Long
Dim xSht As Worksheet, xNSht As Worksheet
Dim I As Long
Dim xTRrow As Integer
Dim xCol As New Collection
Dim yCol as New Collection
Dim xTitle As String
Dim xSUpdate As Boolean
Set xSht = ActiveSheet
xRCount = xSht.Cells(xSht.Rows.Count, 1).End(xlUp).Row
'xTitle = "C1:C1"
'xTRrow = xSht.Range(xTitle).Cells(1).Row
For I = 2 To xRCount
On Error Resume Next
Call xCol.Add(xSht.Cells(I, 1), xSht.Cells(I, 1))
Call yCol.Add(xSht.Cells(I, 2), xSht.Cells(I, 1)) 'change 2 to whatever column you want as the name
Next
On Error Resume Next
xSUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To xCol.Count
Call xSht.Range(xTitle).AutoFilter(1, CStr(xCol.Item(I)))
Set xNSht = Nothing
Set xNSht = Worksheets(CStr(xCol.Item(I)))
If xNSht Is Nothing Then
Set xNSht = Worksheets.Add(, Sheets(Sheets.Count))
xNSht.Name = CStr(yCol.Item(I)) 'here's my magic switcheroo
Else
xNSht.Move , Sheets(Sheets.Count)
End If
xSht.Range("A" & xTRrow & ":A" & xRCount).EntireRow.Copy xNSht.Range("A1")
xNSht.Columns.AutoFit
Next
xSht.AutoFilterMode = False
xSht.Activate
Application.ScreenUpdating = xSUpdate
End Sub

Related

Setting a Column Value Using 'Range' is Giving An Error

The below code copies data from multiple worksheets and consolidates into database (database worksheet). I am trying to add a new column at the last unused column of database worksheet that gives the name of the sheets in each row, the data is copied from with the column header as "Sheet Name". The problem is, I am trying to start with adding the header by using wsData.Range(1, wsData.Cells(1, Columns.Count).End(xlToLeft).Offset(0, 1)).Value = "SheetName", but unfortunately, it is giving an error.
The program is currently taking 6 minutes to process around 25,000 rows, so is there a way to make it faster?
I am not very well-versed with VBA and I received the below code from another stack overflow question. Below is my code. Any help will be appreciated.
Sub ProcessWorkbooks()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Dim f, wsData As Worksheet, wbSrc As Workbook, map As Object
Set wsData = ThisWorkbook.Sheets("Database")
wsData.UsedRange.ClearContents 'clear any existing data
Dim fldr1 As FileDialog
Dim iFile As String
Set fldr1 = Application.FileDialog(msoFileDialogFolderPicker)
With fldr1
.Title = "Select InputFile Folder... "
.ButtonName = "Select"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show = -1 Then
iFile = .SelectedItems(1)
Else
Exit Sub
End If
End With
Dim strPath As String
strPath = iFile
Dim oFSO As Object
Dim oFolder As Object
Dim oFile As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(strPath)
Dim abc As Boolean
abc = False
For Each oFile In oFolder.Files
If oFile.Name Like "*xls*" Then
Set wbSrc = Workbooks.Open(oFolder & "\" & oFile.Name)
ImportData wbSrc, wsData, abc
wbSrc.Close False
End If
Next oFile
With wsData.Range("A1").CurrentRegion
.Font.Size = 9
.Font.Name = "Calibri"
.Borders.LineStyle = xlLineStyleNone
.EntireColumn.AutoFit
End With
Application.ScreenUpdating = True
MsgBox Title:="Task Box", Prompt:="Database Created!"
End Sub
Sub ImportData(wbIn As Workbook, wsData As Worksheet, abc as Boolean)
Dim lrData As Long, lrSrc As Long, ws As Worksheet, c As Range
Dim Process, hdr, m, n
Process = Array("Manila", "Cebu", "Davao", "CDO", "Bacolod")
Application.ScreenUpdating = False
For Each ws In wbIn.Worksheets
Call KillFilter
n = ws.Name
lrData = wsData.Cells(Rows.Count, "A").End(xlUp).Row + 1
'lrData = SheetLastRow(wsData) + 1
If lrData = 1 Then lrData = 2 'in case no headers yet...
lrSrc = SheetLastRow(ws)
For Each c In ws.Range("A1", ws.Cells(1, Columns.Count).End(xlToLeft)).Cells
hdr = c.Value
m = Application.Match(hdr, wsData.Rows(1), 0) 'existing column match?
If IsError(m) Then
m = Application.CountA(wsData.Rows(1))
m = IIf(m = 0, 1, m + 1)
wsData.Cells(1, m).Value = hdr 'add as new column header
End If
ws.Range(c.Offset(1), ws.Cells(lrSrc, c.Column)).Copy _
wsData.Cells(lrData, m)
Next c
If abc = False Then
wsData.Range(1, wsData.Cells(1, Columns.Count).End(xlToLeft).Offset(0, 1)).Value = "SheetName"
abc = True
End If
Next ws
End Sub
'return the last used row in a worksheet
Function SheetLastRow(ws As Worksheet) As Long
Dim f As Range
Set f = ws.Cells.Find("*", ws.Range("A1"), xlFormulas, xlPart, xlByRows, xlPrevious)
If Not f Is Nothing Then SheetLastRow = f.Row 'otherwise 0
End Function
See below for how to add the sheet name, and some other suggestions:
Option Explicit
Sub ProcessWorkbooks()
Dim f, wsData As Worksheet, wbSrc As Workbook, map As Object, strPath As String
Dim oFSO As Object, oFile As Object, nextRow As Long
On Error GoTo haveError 'ensures event/calc settings are restored
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
strPath = ChooseFolder("Select InputFile Folder... ") 'made this a new Function
If Len(strPath) = 0 Then Exit Sub
Set wsData = ThisWorkbook.Sheets("Database")
With wsData
.UsedRange.ClearContents 'clear any existing data
.Range("A1").value = "Sheet Name" 'add the sheet name header
End With
Set oFSO = CreateObject("Scripting.FileSystemObject")
For Each oFile In oFSO.getfolder(strPath).Files
If oFile.name Like "*.xls*" Then
Set wbSrc = Workbooks.Open(oFile.Path)
ImportData wbSrc, wsData
wbSrc.Close False
End If
Next oFile
With wsData.Range("A1").CurrentRegion
.Font.Size = 9
.Font.name = "Calibri"
.Borders.LineStyle = xlLineStyleNone
.EntireColumn.AutoFit
End With
haveError:
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
MsgBox Title:="Task Box", Prompt:="Database Created!"
End Sub
'assumes there's always a "sheet Name" header in A1 of wsData
Sub ImportData(wbIn As Workbook, wsData As Worksheet)
Dim lrData As Long, lrSrc As Long, ws As Worksheet, c As Range
Dim Process, hdr, m
Process = Array("Manila", "Cebu", "Davao", "CDO", "Bacolod") '????
For Each ws In wbIn.Worksheets
If ws.FilterMode Then ws.ShowAllData 'remove any filtering
lrData = wsData.Cells(Rows.Count, "A").End(xlUp).Row + 1 'paste row
lrSrc = SheetLastRow(ws)
wsData.Cells(lrData, "A").Resize(lrSrc - 1).value = ws.name '<<< add the sheet name....
For Each c In ws.Range("A1", ws.Cells(1, ws.Columns.Count).End(xlToLeft)).Cells
hdr = c.value
m = Application.Match(hdr, wsData.Rows(1), 0) 'existing column match?
If IsError(m) Then 'need to add this header?
m = wsData.Cells(1, Columns.Count).End(xlToLeft).Column + 1
wsData.Cells(1, m).value = hdr
End If
ws.Range(c.Offset(1), ws.Cells(lrSrc, c.Column)).Copy _
wsData.Cells(lrData, m)
Next c
Next ws
End Sub
'Ask user to select a folder. Returns empty string if none selected
Function ChooseFolder(prmpt As String) As String
Dim fldr1 As FileDialog, fldr As String
Dim iFile As String
Set fldr1 = Application.FileDialog(msoFileDialogFolderPicker)
With fldr1
.Title = prmpt
.ButtonName = "Select"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show = -1 Then ChooseFolder = .SelectedItems(1)
End With
End Function
'return the last used row in a worksheet
Function SheetLastRow(ws As Worksheet) As Long
Dim f As Range
Set f = ws.Cells.Find("*", ws.Range("A1"), xlFormulas, xlPart, xlByRows, xlPrevious)
If Not f Is Nothing Then SheetLastRow = f.Row 'otherwise 0
End Function

Split Data into Multiple Sheets with VBA

The goal is to split my Raw Data into new sheets based on unique values found in 1 column. I found the following VBA code that does what I need however the customer I will be utilizing this for has a locked excel "workbook" that I cannot change the order of the Raw Data columns on. With that being the case, this VBA code utilizes column A however my target column is C.
The new sheets also seem to name after whatever the target data is but I would like to know how to change this so I can specify a cell for the sheet name.
Question 1: What part of this code can I change to make the target column C instead of A.
Question 2: How can I change the .name portion to be the value in AF2 on each sheet?
Sub parse_data()
Dim xRCount As Long
Dim xSht As Worksheet
Dim xNSht As Worksheet
Dim I As Long
Dim xTRrow As Integer
Dim xCol As New Collection
Dim xTitle As String
Dim xSUpdate As Boolean
Set xSht = ActiveSheet
On Error Resume Next
xRCount = xSht.Cells(xSht.Rows.Count, 1).End(xlUp).Row
xTitle = "A1:AD1"
xTRrow = xSht.Range(xTitle).Cells(1).Row
For I = 2 To xRCount
Call xCol.Add(xSht.Cells(I, 1).Text, xSht.Cells(I, 1).Text)
Next
xSUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To xCol.Count
Call xSht.Range(xTitle).AutoFilter(1, CStr(xCol.Item(I)))
Set xNSht = Nothing
Set xNSht = Worksheets(CStr(xCol.Item(I)))
If xNSht Is Nothing Then
Set xNSht = Worksheets.Add(, Sheets(Sheets.Count))
xNSht.Name = CStr(xCol.Item(I))
Else
xNSht.Move , Sheets(Sheets.Count)
End If
xSht.Range("A" & xTRrow & ":A" & xRCount).EntireRow.Copy xNSht.Range("A1")
xNSht.Columns.AutoFit
Next
xSht.AutoFilterMode = False
xSht.Activate
Application.ScreenUpdating = xSUpdate
End Sub
EDIT TO INCLUDE CUSTOMER TEMPLATE I AM REQUIRED TO USE
https://www.dropbox.com/scl/fi/qb9484lmdyeo1aieqlb4m/HDTemplate.xlsx?dl=0&rlkey=6dlt1nlo8lehmnpl8cdipwbkp
UPDATED
I'm pretty sure my first answer should work in a normal setting which makes me think there's something else going on. However, if resorting the columns is all you need, consider this macro which just makes a new worksheet. For the record this is pretty inefficient to begin with. You could use pivot tables the Filter function or probably lots of other options to do whatever you need. But anyway....
Sub fixYourData()
Dim tempWS As Worksheet, pullWs As Worksheet, rNum As Long
pullWs = ActiveSheet
rNum = pullWs.Cells(Rows.Count, 1).End(xlUp).Row
Set tempWS = Worksheets.Add
With tempWS
.Range("A1:A" & rNum).Value = xSht.Range("C1:C" & rNum).Value
.Range("B1:B" & rNum).Value = xSht.Range("B1:B" & rNum).Value
.Range("C1:C" & rNum).Value = xSht.Range("A1:A" & rNum).Value
.Range("D1:AD" & rNum).Value = xSht.Range("D1:AD" & rNum).Value
End With
Call parse_data '<--- will run your original macro
End Sub
First Answer
See below code changes and comments to your questions.
Sub parse_data()
Dim xRCount As Long
Dim xSht As Worksheet
Dim xNSht As Worksheet
Dim I As Long
Dim xTRrow As Integer
Dim xCol As New Collection
Dim xTitle As String
Dim xSUpdate As Boolean
Set xSht = ActiveSheet
On Error Resume Next
xRCount = xSht.Cells(xSht.Rows.Count, 1).End(xlUp).Row
xTitle = "A1:AD1"
xTRrow = xSht.Range(xTitle).Cells(1).Row
For I = 2 To xRCount
Call xCol.Add(xSht.Cells(I, 3).Text, xSht.Cells(I, 3).Text) '<---Q1 here
Next
xSUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To xCol.Count
Call xSht.Range(xTitle).AutoFilter(3, CStr(xCol.Item(I))) '<---Q1 here
Set xNSht = Nothing
Set xNSht = Worksheets(CStr(xCol.Item(I)))
If xNSht Is Nothing Then
Set xNSht = Worksheets.Add(, Sheets(Sheets.Count))
Else
xNSht.Move , Sheets(Sheets.Count)
End If
xSht.Range("A" & xTRrow & ":A" & xRCount).EntireRow.Copy xNSht.Range("A1")
xNSht.Columns.AutoFit
xNSht.Name = xNSht.Range("AF2").Value ' <-- Q2 here
Next
xSht.AutoFilterMode = False
xSht.Activate
Application.ScreenUpdating = xSUpdate
End Sub

Application-defined or object-defined error on AdvancedFilter macro

I've put together this macro using bits of code from online, and managed to get it to work on a test workbook, but it since transferring it to PERSONAL it keeps coming up with different errors. I've managed to fix a few but am now stuck on getting a "1004 - application-defined or object-defined error" on this line:
Sheets.Add(After:=Sheets(Sheets.Count)).Name = x.Value
The macro seems to run ok up to this point, generating two new worksheets with the filtered data, but then it stops at Sheet3, which it leaves blank and doesn't give a name.
If anyone could explain where I'm going wrong here that would be much appreciated, as I'm still learning!
Thanks :)
Sub NAVExportStarter()
Dim NAVExport As Workbook
Set NAVExport = ActiveWorkbook
'Filter and Copy to New Sheets
Application.ScreenUpdating = False
Dim x As Range
Dim rng As Range
Dim last As Long
Dim sht As Worksheet
'specify sheet name in which the data is stored
Set sht = NAVExport.Sheets("249")
'change filter column in the following code
last = sht.Cells(Rows.Count, "C").End(xlUp).Row
Set rng = sht.Range("A1:O" & last)
sht.Range("C1:C" & last).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("AA1"), Unique:=True
For Each x In Range([AA2], Cells(Rows.Count, "AA").End(xlUp))
With rng
.AutoFilter
.AutoFilter Field:=3, Criteria1:=x.Value
.SpecialCells(xlCellTypeVisible).Copy
Sheets.Add(After:=Sheets(Sheets.Count)).Name = x.Value
ActiveSheet.Paste
End With
Next x
' Turn off filter
sht.AutoFilterMode = False
With Application
.CutCopyMode = False
.ScreenUpdating = True
End With
' Roman Imperial
Dim NAVImperial As Worksheet
Dim LIVEImperial As Workbook
Dim LIVEImperialSheet As Worksheet
Dim UniqueIDs As Range
Dim Descriptions As Range
Dim LastRow As Long
Application.ScreenUpdating = False
Set NAVExport = ThisWorkbook
Set LIVEImperial = Workbooks.Open("\\WDMYCLOUDEX2\Public\Sortcoding\Roman Imperial.xlsm")
Set NAVImperial = NAVExport.Sheets("ROMAN IMPERIAL")
Set LIVEImperialSheet = LIVEImperial.Sheets("LIVE Data")
With NAVImperial
LastRow = .Cells(Rows.Count, "A").End(xlUp).Row
End With
Set UniqueIDs = NAVImperial.Range("B2:B" & LastRow)
Set Descriptions = NAVImperial.Range("F2:F" & LastRow)
UniqueIDs.Copy
LIVEImperialSheet.Range("A2").PasteSpecial xlPasteValues
Descriptions.Copy
LIVEImperialSheet.Range("B2").PasteSpecial xlPasteValues
Application.CutCopyMode = False
LIVEImperialSheet.Range("C2:O" & LastRow).FillDown
LIVEImperial.Close True
Application.ScreenUpdating = True
'Greek
Dim NAVGreek As Worksheet
Dim LIVEGreek As Workbook
Dim LIVEGreekSheet As Worksheet
Dim UniqueIDG As Range
Dim DescriptionsG As Range
Dim LastRowG As Long
Application.ScreenUpdating = False
Set LIVEGreek = Workbooks.Open("\\WDMYCLOUDEX2\Public\Sortcoding\Greek.xlsx")
Set NAVGreek = NAVExport.Sheets("GREEK")
Set LIVEGreekSheet = LIVEGreek.Sheets("LIVE Data")
With NAVGreek
LastRowG = .Cells(Rows.Count, "A").End(xlUp).Row
End With
Set UniqueIDG = NAVGreek.Range("B2:B" & LastRowG)
Set DescriptionsG = NAVGreek.Range("F2:F" & LastRowG)
UniqueIDG.Copy
LIVEGreekSheet.Range("A2").PasteSpecial xlPasteValues
DescriptionsG.Copy
LIVEGreekSheet.Range("B2").PasteSpecial xlPasteValues
Application.CutCopyMode = False
LIVEGreekSheet.Range("C2:R" & LastRowG).FillDown
LIVEGreek.Close True
Application.ScreenUpdating = True
'Roman Provincial
Dim NAVProvincial As Worksheet
Dim LIVEProvincial As Workbook
Dim LIVEProvincialSheet As Worksheet
Dim UniqueIDP As Range
Dim DescriptionsP As Range
Dim LastRowP As Long
Application.ScreenUpdating = False
Set LIVEProvincial = Workbooks.Open("\\WDMYCLOUDEX2\Public\Sortcoding\Roman Provincial.xlsx")
Set NAVProvincial = NAVExport.Sheets("ROMAN PROVINCIAL")
Set LIVEProvincialSheet = LIVEProvincial.Sheets("LIVE Data")
With NAVProvincial
LastRowP = .Cells(Rows.Count, "A").End(xlUp).Row
End With
Set UniqueIDP = NAVProvincial.Range("B2:B" & LastRowP)
Set DescriptionsP = NAVProvincial.Range("F2:F" & LastRowP)
UniqueIDP.Copy
LIVEProvincialSheet.Range("A2").PasteSpecial xlPasteValues
DescriptionsP.Copy
LIVEProvincialSheet.Range("B2").PasteSpecial xlPasteValues
Application.CutCopyMode = False
LIVEProvincialSheet.Range("C2:G" & LastRowP).FillDown
LIVEProvincial.Close True
Application.ScreenUpdating = True
'Republican
Dim NAVRepublican As Worksheet
Dim LIVERepublican As Workbook
Dim LIVERepublicanSheet As Worksheet
Dim UniqueIDR As Range
Dim DescriptionsR As Range
Dim LastRowR As Long
Application.ScreenUpdating = False
Set LIVERepublican = Workbooks.Open("\\WDMYCLOUDEX2\Public\Sortcoding\Roman Republican.xlsx")
Set NAVRepublican = NAVExport.Sheets("ROMAN REPUBLIC")
Set LIVERepublicanSheet = LIVERepublican.Sheets("LIVE Data")
With NAVRepublican
LastRowR = .Cells(Rows.Count, "A").End(xlUp).Row
End With
Set UniqueIDR = NAVRepublican.Range("B2:B" & LastRowR)
Set DescriptionsR = NAVRepublican.Range("F2:F" & LastRowR)
UniqueIDR.Copy
LIVERepublicanSheet.Range("A2").PasteSpecial xlPasteValues
DescriptionsR.Copy
LIVERepublicanSheet.Range("B2").PasteSpecial xlPasteValues
Application.CutCopyMode = False
LIVERepublicanSheet.Range("C" & LastRowR).FillDown
LIVERepublican.Close True
Application.ScreenUpdating = True
'Imperatorial
Dim NAVImperatorial As Worksheet
Dim LIVEImperatorial As Workbook
Dim LIVEImperatorialSheet As Worksheet
Dim UniqueIDI As Range
Dim DescriptionsI As Range
Dim LastRowI As Long
Application.ScreenUpdating = False
Set LIVEImperatorial = Workbooks.Open("\\WDMYCLOUDEX2\Public\Sortcoding\Roman Imperatorial.xlsx")
Set NAVImperatorial = NAVExport.Sheets("ROMAN IMPERATORIAL")
Set LIVEImperatorialSheet = LIVEImperatorial.Sheets("LIVE Data")
With NAVImperatorial
LastRowI = .Cells(Rows.Count, "A").End(xlUp).Row
End With
Set UniqueIDI = NAVImperatorial.Range("B2:B" & LastRowI)
Set DescriptionsI = NAVImperatorial.Range("F2:F" & LastRowI)
UniqueIDI.Copy
LIVEImperatorialSheet.Range("A2").PasteSpecial xlPasteValues
DescriptionsI.Copy
LIVEImperatorialSheet.Range("B2").PasteSpecial xlPasteValues
Application.CutCopyMode = False
LIVEImperatorialSheet.Range("C" & LastRowI).FillDown
LIVEImperatorial.Close True
Application.ScreenUpdating = True
'Byzantine
Dim NAVByzantine As Worksheet
Dim LIVEByzantine As Workbook
Dim LIVEByzantineSheet As Worksheet
Dim UniqueIDB As Range
Dim DescriptionsB As Range
Dim LastRowB As Long
Application.ScreenUpdating = False
Set LIVEByzantine = Workbooks.Open("\\WDMYCLOUDEX2\Public\Sortcoding\Byzantine.xlsx")
Set NAVByzantine = NAVExport.Sheets("BYZANTINE")
Set LIVEByzantineSheet = LIVEByzantine.Sheets("LIVE Data")
With NAVByzantine
LastRowB = .Cells(Rows.Count, "A").End(xlUp).Row
End With
Set UniqueIDB = NAVByzantine.Range("B2:B" & LastRowB)
Set DescriptionsB = NAVByzantine.Range("F2:F" & LastRowB)
UniqueIDB.Copy
LIVEByzantineSheet.Range("A2").PasteSpecial xlPasteValues
DescriptionsB.Copy
LIVEByzantineSheet.Range("B2").PasteSpecial xlPasteValues
Application.CutCopyMode = False
LIVEByzantineSheet.Range("C2:E" & LastRowB).FillDown
LIVEByzantine.Close True
Application.ScreenUpdating = True
'World
Dim NAVWorld As Worksheet
Dim LIVEWorld As Workbook
Dim LIVEWorldSheet As Worksheet
Dim UniqueIDW As Range
Dim DescriptionsW As Range
Dim LastRowW As Long
Application.ScreenUpdating = False
Set LIVEWorld = Workbooks.Open("\\WDMYCLOUDEX2\Public\Sortcoding\World.xlsx")
Set NAVWorld = NAVExport.Sheets("WORLD")
Set LIVEWorldSheet = LIVEWorld.Sheets("LIVE Data")
With NAVWorld
LastRowW = .Cells(Rows.Count, "A").End(xlUp).Row
End With
Set UniqueIDW = NAVWorld.Range("B2:B" & LastRowW)
Set DescriptionsW = NAVWorld.Range("F2:F" & LastRowW)
UniqueIDW.Copy
LIVEWorldSheet.Range("A2").PasteSpecial xlPasteValues
DescriptionsW.Copy
LIVEWorldSheet.Range("B2").PasteSpecial xlPasteValues
Application.CutCopyMode = False
LIVEWorldSheet.Range("C2:E" & LastRowW).FillDown
LIVEWorld.Close True
Application.ScreenUpdating = True
End Sub

Excel macro to merge multiple sheets to mastersheets based on the sheet name

So, I have one excel workbook containing around 80 sheets, the sheets are named as Input, Input(1), input, INPUT, INPUT(2) and Output, Output(1), Output(2), output, OUTPUT and so on, you get the idea... I want to create a macro which creates two mastersheets in the Workbook named "MASTERSHEET INPUT" and "MASTERSHEET Output". The macro should copy all the data from any sheet having any variation of input in its sheet name and paste it one into the MASTERSHEET INPUT and the same goes for the sheets named output which will be pasted into MASTERSHEET OUTPUT. I'm relatively new to VBA and I'd really appreciate it if someone could help me out.
Thanks in advance!
This is the code I was using previously
Sub CombineData()
Dim I As Long
Dim xRg As Range
On Error Resume Next
Worksheets.Add Sheets(1)
ActiveSheet.Name = "MasterSheet"
For I = 2 To Sheets.Count
Set xRg = Sheets(1).UsedRange
If I > 2 Then
Set xRg = Sheets(1).Cells(xRg.Rows.Count + 1, 1)
End If
Sheets(I).Activate
ActiveSheet.UsedRange.Copy xRg
Next
End Sub
But this merges all the sheets in the workbook into one without checking the sheet name.
I tried using this one next but this just pastes the first Output sheet into both mastersheets and then ends:
Sub CombineData()
Dim I As Long
Dim xRg As Range
Dim xWs As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next
Worksheets.Add Sheets(1)
ActiveSheet.Name = "MasterSheet Output"
For I = 2 To Sheets.Count
Set xRg = Sheets(1).UsedRange
If I > 2 Then
Set xRg = Sheets(1).Cells(xRg.Rows.Count + 1, 1)
End If
For Each xWs In Application.ActiveWorkbook.Worksheets
If xWs.Name = "OUTPUT*" Or xWs.Name = "output*" Or xWs.Name = "Output*" Then
Sheets(I).Activate
ActiveSheet.UsedRange.Copy xRg
End If
Next
Next
On Error Resume Next
Worksheets.Add Sheets(1)
ActiveSheet.Name = "MasterSheet Input"
For I = 3 To Sheets.Count
Set xRg = Sheets(1).UsedRange
If I > 2 Then
Set xRg = Sheets(1).Cells(xRg.Rows.Count + 1, 1)
End If
For Each xWs In Application.ActiveWorkbook.Worksheets
If xWs.Name = "INPUT*" Or xWs.Name = "input*" Or xWs.Name = "Input*" Then
Sheets(I).Activate
ActiveSheet.UsedRange.Copy xRg
End If
Next
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Call DeleteAllSheetsExceptMaster
End Sub
I also tried using this but this does absolutely nothing:
Sub CombineData()
Dim I As Long
Dim xrg As Range
Dim counter As Long
Dim xWs1 As Worksheet
Dim xWs2 As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next
For counter = 1 To 2
Worksheets.Add Sheets(1)
If counter = 1 Then
ActiveSheet.Name = "MasterSheet Input"
Set xWs1 = ActiveSheet
End If
If counter = 2 Then
ActiveSheet.Name = "MasterSheet Output"
Set xWs2 = ActiveSheet
End If
Next counter
For I = 2 To Sheets.count
Set xrg = Sheets(1).UsedRange
If I > 2 Then
Set xrg = Sheets(1).Cells(xrg.Rows.count + 1, 1)
End If
Sheets(I).Activate
If Sheets(I).Name = "OUTPUT*" Or Sheets(I).Name = "output*" Or Sheets(I).Name = "Output*" Then
ActiveSheet.UsedRange.Copy xWs2
End If
If Sheets(I).Name = "INPUT*" Or Sheets(I).Name = "input*" Or Sheets(I).Name = "Input*" Then
ActiveSheet.UsedRange.Copy xWs1
End If
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Create Master Sheets
The following will delete each of the master worksheets if they exist and then create new ones. Then it will copy the data from the current region starting in A1 of the defined source worksheets to the appropriate master worksheets (read OP's requirements).
The Code
Option Explicit
Sub createMasterSheets()
' Define constants incl. the Names Arrays and the workbook.
Const srcFirst As String = "A1"
Const tgtFirst As String = "A1"
Dim srcNames As Variant
srcNames = Array("iNpUt", "oUtPuT") ' Case does not matter.
Dim tgtNames As Variant
tgtNames = Array("MasterIn", "MasterOut")
Dim wb As Workbook
Set wb = ThisWorkbook
' Define lower and upper subscripts of the 1D arrays:
' srcNames, tgtNames, Dicts
Dim sFirst As Long
sFirst = LBound(srcNames)
Dim sLast As Long
sLast = UBound(srcNames)
' Turn off screen updating.
Application.ScreenUpdating = False
' Add Target Worksheets.
Dim ws As Worksheet
Dim n As Long
For n = sLast To sFirst Step -1
On Error Resume Next
Set ws = wb.Sheets(tgtNames(n))
On Error GoTo 0
If Not ws Is Nothing Then
Application.DisplayAlerts = False
wb.Sheets(tgtNames(n)).Delete
Application.DisplayAlerts = True
End If
wb.Worksheets.Add Before:=wb.Sheets(1)
ActiveSheet.Name = tgtNames(n)
Next n
' Define Dictionaries Array and populate it with Dictionaries.
' The Dictionaries will hold the Data Arrays.
Dim Dicts As Variant
ReDim Dicts(sFirst To sLast)
Dim dict As Object
For n = sFirst To sLast
Set dict = CreateObject("Scripting.Dictionary")
Set Dicts(n) = dict
Next n
' Declare variables.
Dim wsName As String ' Current Worksheet Name
Dim rng As Range ' Current Source Range, Current Target Cell Range
Dim m As Long ' Subscript of Current Data Array in Current Dictionary
' of Dictionaries Array
' Write values from Source Ranges to Data Arrays.
For Each ws In wb.Worksheets
wsName = ws.Name
For n = sFirst To sLast
If InStr(1, wsName, srcNames(n), vbTextCompare) = 1 Then
' Define Source Range. You might need to do this in another way.
Set rng = ws.Range(srcFirst).CurrentRegion
m = m + 1
Dicts(n)(m) = rng.Value ' This will fail later if one cell only.
Exit For
End If
Next n
Next ws
' Declare variables
Dim Key As Variant ' Current Key in Current Dictionary
' of Dictionaries Array.
' Write values from Data Arrays to Target Ranges.
For n = sFirst To sLast
Set rng = wb.Worksheets(tgtNames(n)).Range(tgtFirst)
Set ws = wb.Worksheets(tgtNames(n))
For Each Key In Dicts(n).Keys
rng.Resize(UBound(Dicts(n)(Key), 1), _
UBound(Dicts(n)(Key), 2)).Value = Dicts(n)(Key)
Set rng = rng.Offset(UBound(Dicts(n)(Key), 1))
Next Key
Next n
' Turn on screen updating.
Application.ScreenUpdating = True
' Inform user.
MsgBox "Sheets created, data transferred.", vbInformation, "Success"
End Sub
See if this works for you.
Edit: fixed case sensitivity.
Sub CopyFromWorksheets()
Dim wrk As Workbook 'Workbook object - Always good to work with object variables
Dim sht As Worksheet 'Object for handling worksheets in loop
Dim trg As Worksheet 'Input Master
Dim trg2 As Worksheet 'Output Master
Dim rng As Range 'Range object
Set wrk = ActiveWorkbook 'Working in active workbook
'Add new worksheet as the last worksheet
Set trg = wrk.Worksheets.Add(After:=wrk.Worksheets(wrk.Worksheets.Count))
'Rename the new worksheet
trg.Name = "Input Master"
'Add new worksheet as the last worksheet
Set trg2 = wrk.Worksheets.Add(After:=wrk.Worksheets(wrk.Worksheets.Count))
'Rename the new worksheet
trg2.Name = "Output Master"
'We can start loop
For Each sht In wrk.Worksheets
'If worksheet in loop is the last one, stop execution (it is Master worksheet)
If sht.Index = wrk.Worksheets.Count - 1 Then
Exit For
ElseIf LCase(sht.Name) Like "*" & "input" & "*" Then
Set rng = sht.Range(sht.Cells(1, 1), sht.Cells(65536, 1).End(xlUp))
'Put data into the Master worksheet
trg.Cells(65536, 1).End(xlUp).Offset(1).Resize(rng.Rows.Count, rng.Columns.Count).Value = rng.Value
ElseIf LCase(sht.Name) Like "*" & "output" & "*" Then
Set rng = sht.Range(sht.Cells(1, 1), sht.Cells(65536, 1).End(xlUp))
'Put data into the Master worksheet
trg2.Cells(65536, 1).End(xlUp).Offset(1).Resize(rng.Rows.Count, rng.Columns.Count).Value = rng.Value
End If
Next sht
'Fit the columns in Master worksheet
trg.Columns.AutoFit
trg.Rows(1).Delete
trg.Columns.AutoFit
trg2.Rows(1).Delete
End Sub

How to fix compile error: Invalid use of property

I'm trying to drag all the formulas from a workbook from column AQ2 to BF, but when I'm assisgning the count for the lastrow variable, it keeps giving me an error
Already tried just doing it without the variable lastrow, but it's giving me the same error
Option Explicit
Dim mt_roster As String
Dim roster As String
Dim wkb_1 As Workbook
Dim wkb_2 As Workbook
Dim ws_1 As Worksheet
Dim ws_2 As Worksheet
Dim rng_1 As Range
Dim rng_2 As Range
Dim lastrow As Range
Sub mtm_roster()
' mtm_roster Macro
Application.ScreenUpdating = False
Application.DisplayAlerts = False
open_rosters
With wkb_1
wkb_1.Activate
Set ws_1 = Worksheets("Sheet1")
Set rng_1 = ws_1.Columns("A:AQ")
rng_1.EntireColumn.Hidden = False
End With
With wkb_2
wkb_2.Activate
Set ws_2 = Worksheets("Sheet1")
Set rng_2 = ws_2.Range("A1").CurrentRegion
rng_2.Select
End With
rng_2.Copy
rng_1.PasteSpecial xlPasteValues
wkb_2.Close SaveChanges:=False
With wkb_1
wkb_1.Activate
ws_1.Activate
Set lastrow = Range("A1")
lastrow.CurrentRegion.Rows.Count
Range("AQ2:BF" & lastrow).FillDown
End With
I'm trying to drag the formulas from AQ:BF all the way down but I'm still missing that part.
With wkb_1
Set ws_1 = .Worksheets("Sheet1")
Set rng_1 = ws_1.Columns("A:AQ")
rng_1.EntireColumn.Hidden = False
End With
With wkb_2
Set ws_2 = .Worksheets("Sheet1")
Set rng_2 = ws_2.Range("A1").CurrentRegion
End With
rng_2.Copy
rng_1.PasteSpecial xlPasteValues
wkb_2.Close SaveChanges:=False
Dim LastRow As Long
With ws_1
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("AQ2:BF" & LastRow).FillDown
End With

Resources