I found this code below to help combine multiple sheets of data into one, however, it won't take from multiple sheets. I have two sheets and it either grabs one or the other. I tried to add on to it to specify more than one sheet but that doesn't seem to work either. How can I make this pull from multiple sheets? I have a sheet "anaheim" and sheet "Woodridge."
Sub Step3()
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
Sub Step3()
Dim sh As Worksheet
Dim xRg As Range
Sheets.Add.Name = "MasterSheet"
For Each sh In Sheets
If sh.Name <> "MasterSheet" Then
sh.UsedRange.Copy Sheets("MasterSheet").Cells(Sheets("MasterSheet").Rows.Count, "A").End(xlUp).Offset(1)
End If
Next
End Sub
Backup Used Ranges
Option Explicit
Sub backupUsedRanges()
' Target Worksheet
Const tgtSheetName As String = "MasterSheet"
Const tgtFirstCell As String = "A1"
' Workbook
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
' Check if a sheet named 'tgtSheetName' already exists.
Dim Msg As Variant
If SheetExists(wb, tgtSheetName) Then
Msg = MsgBox("A sheet named '" & tgtSheetName _
& "' already exists. Do you want to delete it?", _
vbYesNo + vbExclamation, "Delete?")
If Msg = vbYes Then
Application.DisplayAlerts = False
wb.Worksheets(tgtSheetName).Delete
Application.DisplayAlerts = True
Else
MsgBox "Backup NOT created.", vbExclamation, "Fail"
Exit Sub
End If
End If
' Define (add) Target Worksheet ('tgt').
Dim tgt As Worksheet
Set tgt = wb.Worksheets.Add(Before:=wb.Sheets(1))
tgt.Name = tgtSheetName
' Define Next Target First Available Cell Range ('cel').
Dim cel As Range
Set cel = tgt.Range(tgtFirstCell)
' Write from Source Worksheets ('src') to Target Worksheet.
Dim src As Worksheet ' Current Source Worksheet
Dim rng As Range ' Current Source Used Range
For Each src In wb.Worksheets
If StrComp(src.Name, tgtSheetName, vbTextCompare) <> 0 Then
' Define Current Source Used Range ('rng').
Set rng = src.UsedRange
' Copy Current Source Used Range to Target Worksheet.
rng.Copy cel
' Define Next Target First Available Cell Range.
Set cel = cel.Offset(rng.Rows.Count)
End If
Next src
' Inform user
MsgBox "Backup created.", vbInformation, "Success"
End Sub
Function SheetExists(Book As Workbook, SheetName As String) As Boolean
Dim sh As Object
For Each sh In Book.Sheets
If StrComp(sh.Name, SheetName, vbTextCompare) = 0 Then
SheetExists = True
Exit Function
End If
Next sh
End Function
Related
Wondering why I can't do :
For i = 1 To ThisWorkbook.Sheets.Count
If ThisWorkbook.Sheets(i).Name <> "DO NOT SAVE" Then ThisWorkbook.Sheets(i).Select Replace:=False
Next i
Selection.Copy
what would be the best way to save all sheets which does not match DO NOT SAVE name in another wb ?
Try this:
Sub Tester()
Dim ws As Worksheet, arr(), i As Long
ReDim arr(0 To ThisWorkbook.Worksheets.Count - 2)
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "DO NOT SAVE" Then
arr(i) = ws.Name
i = i + 1
End If
Next ws
Worksheets(arr).Copy
End Sub
A Reflection on the Sheets' Visibility
To export a single sheet to a new workbook, the sheet has to be visible.
To export multiple sheets (using an array of sheet names) to a new workbook, at least one of the sheets has to be visible, while very hidden sheets will not get exported (no error though).
In a given workbook, the following procedure will copy all its sheets, except the ones whose names are in a given array (Exceptions), to a new workbook if at least one of the sheets is visible.
Before copying, it will 'convert' the very hidden sheets to hidden and after the copying, it will 'convert' the originals and copies to very hidden.
Option Explicit
Sub ExportSheets( _
ByVal wb As Workbook, _
ByVal Exceptions As Variant)
Dim shCount As Long: shCount = wb.Sheets.Count
Dim SheetNames() As String: ReDim SheetNames(1 To shCount)
Dim sh As Object
Dim coll As Object
Dim Item As Variant
Dim n As Long
Dim VisibleFound As Boolean
Dim VeryHiddenFound As Boolean
For Each sh In wb.Sheets
If IsError(Application.Match(sh.Name, Exceptions, 0)) Then
Select Case sh.Visible
Case xlSheetVisible
If Not VisibleFound Then VisibleFound = True
Case xlSheetHidden ' do nothing
Case xlSheetVeryHidden
If Not VeryHiddenFound Then
Set coll = New Collection
VeryHiddenFound = True
End If
coll.Add sh.Name
End Select
n = n + 1
SheetNames(n) = sh.Name
End If
Next sh
If n = 0 Then
MsgBox "No sheet found.", vbExclamation
Exit Sub
End If
If Not VisibleFound Then
MsgBox "No visible sheet found.", vbExclamation
Exit Sub
End If
If n < shCount Then ReDim Preserve SheetNames(1 To n) ' n - actual count
If VeryHiddenFound Then ' convert to hidden
For Each Item In coll
wb.Sheets(Item).Visible = xlSheetHidden
Next Item
End If
wb.Sheets(SheetNames).Copy ' copy to new workbook
If VeryHiddenFound Then ' revert to very hidden
Dim dwb As Workbook: Set dwb = Workbooks(Workbooks.Count)
For Each Item In coll
wb.Sheets(Item).Visible = xlSheetVeryHidden
dwb.Sheets(Item).Visible = xlSheetVeryHidden
Next Item
End If
MsgBox "Sheets exported: " & n, vbInformation
End Sub
Sub ExportSheetsTEST()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
ExportSheets wb, Array("DO NOT SAVE")
End Sub
Alternatively you could use the following snippet:
Sub CopyWorkbook()
Dim i As Integer
For i = 1 To ThisWorkbook.Sheets.Count
If ThisWorkbook.Sheets(i).Name <> "DO NOT SAVE" Then
Dim rng As Range
Windows("SOURCE WORKBOOK").Activate
rng = ThisWorkbook.Sheets(i).Cells
rng.Copy Before:=Workbooks("TARGET WORKBOOK").Sheets(i)
End If
Next i
End Sub
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
I am working with an EXCEL file with 11 worksheets, in this configuration:
VOL_CODE = The code that I look for. If present in a worksheet, the entire line containing VOL_CODE should be deleted.
Worksheets:
“NEW VOL DATA” –This is the worksheet that “stays on” (‘Active’ or ‘Selected’) during the whole process.
Also, here are in range K1:K10 the indications (“X”) if the destination worksheets are selected or not.
“DESTINATION1”, “DESTINATION2”, “DESTINATION3” ... “DESTINATION10”
“Target” worksheets where if VOL_CODE appears AND worksheet is indicated as ‘selected’ (in “NEW VOL DATA” worksheet), it’s line should be removed.
Code:
Private Sub CommandButton3_Click()
'--- Remove VOL_CODE line from all worksheets -----
Dim ws1, ws2 As Worksheet
Dim VOL_CODE As String
Dim PLA, LIN As Integer
Set ws1 = Worksheets("NEW VOL DATA") '--- This is the Working Worksheet -----
VOL_CODE = “RS_123456” ‘--- This is the code to search for -----
For PLA = 1 To 10
If UCase(Range("K" & PLA)) <> "X" Then GoTo JUMP_PLA:
Set ws2 = Worksheets("DESTINATION" & Trim(Str(PLA)))
Do While True
On Error GoTo JUMP_PLA:
LIN = Application.WorksheetFunction.Match(VOL_CODE, ws2.Range("B:B"), 0)
ws2.Cells(LIN, 1).EntireRow.Delete
Loop
JUMP_PLA:
Next PLA
End Sub
The problem is, when I execute the code, it goes fine in DESTINATION1 worksheet, containing or not VOL_CODE (if it does, it loops deleting VOL_CODE’s lines until there are no more), then, when finding no more entries for VOL_CODE, it goes to “JUMP_PLA:” and “Next PLA”... There it starts over, now going to next “DESTINATIONx” worksheet (the next selected)... And there’s an error (finding or not a valid entry) when the Application.WorksheetFunction.Match command executes :
Error in execution: 1004
Application definition or Object definition error
I know it must be a stupid error, but as I am a newbie, I cannot visualize it. And it is driving me crazy...
Can anyone give me a light? It would be very appreciated, and I thank you in advance.
Application.WorksheetFunction.Match to Delete Rows
The procedure doDest is best copied into a standard module (e.g. Module1) and then called in your button code:
Private Sub CommandButton3_Click()
doDest
End Sub
I left your code inside it, so you could see the mistakes and some options.
The rest of the code is just some toys a created to play with, since I've never seen Match used for deleting rows.
IF you wanna play, copy the complete code into a standard module in a new workbook and rename a worksheet to NEW VOL DATA. In range K1:K10 of it, enter an x in a few cells and you're good to go.
The Code
Option Explicit
Sub doDest()
'--- Remove VOL_CODE line from all worksheets -----
' Speed up the code (you won't see what the macro is doing).
Application.ScreenUpdating = False
Dim ws1 As Worksheet, ws2 As Worksheet 'Dim ws1, ws2 As Worksheet
Dim VOL_CODE As String
Dim PLA As Long, LIN As Long ' Dim PLA, LIN As Integer
Dim wb As Workbook: Set wb = ThisWorkbook ' The workbook with this code.
Set ws1 = wb.Worksheets("NEW VOL DATA") 'Set ws1 = Worksheets("NEW VOL DATA") '--- This is the Working Worksheet -----
VOL_CODE = "RS_123456" '--- This is the code to search for -----
For PLA = 1 To 10
'If StrComp(ws1.Range("K" & PLA).Value, "X", vbTextCompare) <> 0 _
Then GoTo JUMP_PLA
If UCase(ws1.Range("K" & PLA).Value) <> "X" Then GoTo JUMP_PLA ' If UCase(Range("K" & PLA)) <> "X" Then GoTo JUMP_PLA:
Set ws2 = wb.Worksheets("DESTINATION" & PLA) ' Set ws2 = Worksheets("DESTINATION" & Trim(Str(PLA)))
Do ' Do While True
' On Error GoTo JUMP_PLA:
' LIN = Application.WorksheetFunction.Match(VOL_CODE, ws2.Range("B:B"), 0)
' ws2.Cells(LIN, 1).EntireRow.Delete
On Error Resume Next ' Turn ON error trapping.
' "ws2.Columns("B")" is just an option, you can stick with
' "ws2.Range("B:B")".
LIN = Application.WorksheetFunction _
.Match(VOL_CODE, ws2.Columns("B"), 0)
If Err.Number <> 0 Then
On Error GoTo 0 ' Turn OFF error trapping.
'Debug.Print "Done with worksheet '" & ws2.Name & "'."
Exit Do ' or: GoTo JUMP_PLA
Else
On Error GoTo 0 ' Turn OFF error trapping.
ws2.Cells(LIN, 1).EntireRow.Delete
End If
Loop
JUMP_PLA:
Next PLA
Application.ScreenUpdating = True
MsgBox "Deleted rows containing '" & VOL_CODE & "'.", _
vbInformation, "Success"
End Sub
' Deletes all sheets named "DESTINATIONx", where x is from 1 to 10.
Sub deleteDest()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim i As Long
For i = 1 To 10
Application.DisplayAlerts = False ' To prevent Excel from 'complaining'.
On Error Resume Next ' If a sheet does not exist.
wb.Sheets("DESTINATION" & i).Delete
On Error GoTo 0
Application.DisplayAlerts = True
Next i
End Sub
' Adds worksheets named "DESTINATIONx", where x is from 1 to 10.
' In each of those worksheets, adds "RS_123456" to up to 100 cells
' in 'random' rows from 1 to 1000 in column 'B'.
Sub createDest()
' Speed up the code (you won't see what the macro is doing).
Application.ScreenUpdating = False
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet, i As Long, j As Long, CurrName As String
For i = 1 To 10
CurrName = "DESTINATION" & i
On Error Resume Next ' Turn ON error trapping.
Set ws = wb.Worksheets(CurrName)
If Err.Number <> 0 Then
' Sheet with current name does not exist.
Set ws = wb.Worksheets _
.Add(After:=wb.Worksheets(wb.Worksheets.Count))
ws.Name = CurrName
'Else ' Sheet with current name exists.
End If
On Error GoTo 0 ' Turn OFF error trapping.
ws.Columns("B").Clear ' Ensures new data if sheets already exist.
For j = 1 To 100
ws.Cells(Application.WorksheetFunction.RandBetween(1, 1000), "B") _
.Value = "RS_123456"
Next j
Next i
wb.Sheets(1).Select
Application.ScreenUpdating = True
End Sub
' Counts the number of cells in column 'B' containing a value.
Sub countDest()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim i As Long
For i = 1 To 10
On Error Resume Next
Debug.Print "DESTINATION" & i, wb.Worksheets("DESTINATION" & i) _
.Columns("B") _
.SpecialCells(xlCellTypeConstants) _
.Cells.Count
If Err.Number <> 0 Then
Debug.Print "DESTINATION" & i, "No cells found."
End If
Next i
End Sub
' Ultimate test
Sub testDest()
deleteDest ' Deletes the sheets.
createDest ' Creates the worksheets with random data.
countDest ' Counts the cells containing "RS_123456" (Debug.Print).
doDest ' Deletes the rows containing "RS_123456" in column 'B'.
countDest ' Counts the cells containing "RS_123456" (Debug.Print).
MsgBox "Ultimate: deleted, created, counted, done and counted again."
End Sub
' Initialize
Sub initCreateAndCount()
deleteDest ' Deletes the sheets.
createDest ' Creates the worksheets with random data.
countDest ' Counts the cells containing "RS_123456" (Debug.Print).
MsgBox "Initialized: Sheets deleted and created, and cells counted."
End Sub
' Shows how even when the 'dest' sheets exist, new values are generated.
Sub testCreateCount()
createDest ' Creates the worksheets with random data.
countDest ' Counts the cells containing "RS_123456" (Debug.Print).
MsgBox "Sheets created and cells counted."
End Sub
Here's a slightly re-worked version.
See comments for notes about changes
Private Sub CommandButton3_Click()
Dim ws1 As Worksheet, ws2 As Worksheet '<< need type for every variable,
' not just the last one...
Dim VOL_CODE As String
Dim PLA As Long, LIN As Long, m '<< use Long, not Integer
Set ws1 = Worksheets("NEW VOL DATA") 'Working Worksheet
VOL_CODE = "RS_123456" '<<< no smart quotes...
For PLA = 1 To 10
If UCase(ws1.Range("K" & PLA)) = "X" Then
Set ws2 = Worksheets("DESTINATION" & PLA)
m = Application.Match(VOL_CODE, ws2.Range("B:B"), 0)
Do While Not IsError(m) '<<< Test return value instead of
' trapping run-time error
ws2.Rows(m).Delete
m = Application.Match(VOL_CODE, ws2.Range("B:B"), 0)
Loop
End If
Next PLA
End Sub
I have a master workbook, which houses a group of 15 worksheets that house data for summary pivot tables and whatnot. Every week this master workbook gets updated with a daily report that has those 15 worksheets, but also around 20 other ones. I am just trying to get a script together to identify if they exist, and if so, to move that daily data to the master workbooks worksheet (only move data if daily wb worksheet exists in master workbook).
Here is a very general shell of what I'm trying to achieve, but I'm not well versed in determining the logic if a sheet exists, so my blnFound variable is obviously misplaced. I hope this shows a rough outline of what I'm trying to achieve. Any help is greatly appreciated!
Option Explicit
Sub Update_New_Data()
Const BasePath As String = "C:\\User\Data..."
Dim wbMaster As Workbook: Set wbMaster = ThisWorkbook
Dim wbNewData As Workbook: Set wbNewData = Workbooks.Open(BasePath & "\03.01.20.xlsx")
Dim wsMaster As Sheet
Dim blnFound As Boolean
'places all sheet names into array
With wbNewData
Dim varWsName As Variant
Dim i As Long
Dim ws As Worksheet
ReDim varWsName(1 To wbNewData.Worksheets.Count - 2)
For Each ws In wbNewData.Worksheets
Select Case ws.Name
Case "Inputs", "Data --->>>"
Case Else
i = i + 1
varWsName(i) = ws.Name
End Select
Next
End With
'if wbNewData sheet name is found in wbMaster
'then locate it and place wbNewData data into that sheet
With wbMaster
For Each wsMaster In wbMaster.Sheets
With wsMaster
If .Name = varWsName(i) Then
blnFound = True
wbNewData(Worksheets(i)).UsedRange.Copy Destination:=wbMaster(Worksheets(i)).Range("A1")
Else: blnFound = False
End If
End With
Next
End With
End Sub
To check if something exists you can use a Dictionary Object
Option Explicit
Sub Update_New_Data()
Const BasePath As String = "C:\\User\Data..."
Dim wbMaster As Workbook, wbNewData As Workbook
Set wbMaster = ThisWorkbook
Set wbNewData = Workbooks.Open(BasePath & "\03.01.20.xlsx", , False) ' read only
Dim ws As Worksheet, sKey As String, rng As Range, msg As String
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
'places all master sheet names into dictionary
For Each ws In wbMaster.Sheets
If ws.Name = "inputs" Or ws.Name = "Data --->>>" Then
' skip
Else
dict.Add CStr(ws.Name), ws.Index
Debug.Print "Added to dict", ws.Index, ws.Name
End If
Next
' if wbNewData sheet name is found in wbMaster
' then locate it and place wbNewData data into that sheet
For Each ws In wbNewData.Sheets
sKey = CStr(ws.Name)
If dict.exists(sKey) Then
' clear master
wbMaster.Sheets(dict(sKey)).cells.clear
Set rng = ws.UsedRange
rng.Copy wbMaster.Sheets(dict(sKey)).Range("A1")
msg = msg & vbCr & ws.Name
Else
Debug.Print "Not found in master", ws.Index, ws.Name
End If
Next
wbNewData.Close
' result
If Len(msg) > 0 Then
MsgBox "Sheets copied were " & msg, vbInformation
Else
MsgBox "No sheets copied", vbExclamation
End If
End Sub
[table - worksheet "output - flat"][1]
I have code below that checks to see if column "NamedRange" in the table attached appears as a named range in the (dstRng) template and if it does exist it returns the value to the right ("report balance"). How can I add a condition where when the user chooses a template it will only return values based on the Ted ID - in the table attached. I have 2 templates and it loops through the two templates however I want the first template to only return values for Ted ID 10004 and template 2 it will only return values for Ted ID 11372 and etc. etc. Hope that makes sense... let me know if u have any questions
Option Explicit
Sub Button4_Click()
Dim Desktop As Variant
Dim Files As Object
Dim Folder As Variant
Dim oShell As Object
Dim Tmplts As Variant ' Templates folder
Dim wsLocal As Worksheet
Dim wsGroup As Worksheet
Dim wb As Object
' Check Box 2 "Select All" must be checked to run the macro.
If ActiveSheet.Shapes("Check Box 2").ControlFormat.Value = xlOff Then Exit Sub
Application.ScreenUpdating = False
Application.EnableEvents = False
' Prompt user to locate the Templates folder.
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = True Then
Tmplts = .SelectedItems(1)
Else
Exit Sub
End If
End With
Set oShell = CreateObject("Shell.Application")
Set Desktop = oShell.Namespace(0)
' Create the Output folder on the User's Desktop if it does not exist.
Set Folder = Desktop.ParseName("Output")
If Folder Is Nothing Then
Desktop.NewFolder "Output"
Set Folder = Desktop.ParseName("Output")
End If
Set Files = oShell.Namespace(Tmplts).Items
Files.Filter 64, "*.xlsm"
For Each wb In Files
Set wb = Workbooks.Open(Filename:=wb.Path, UpdateLinks:=False)
Call BreakLinks(wb)
On Error Resume Next
Set wsLocal = wb.Worksheets("RVP Local GAAP")
Set wsGroup = wb.Worksheets("RVP Group GAAP")
'unprotect workbook
wsLocal.Unprotect Password:="KqtgH5rn9v"
wsGroup.Unprotect Password:="KqtgH5rn9v"
On Error GoTo 0
' Check that both worksheets exist before updating.
If Not wsLocal Is Nothing And Not wsGroup Is Nothing Then
Call ProcessNamedRanges(wb)
'lock the workbook
wsLocal.Protect Password:="KqtgH5rn9v"
wsGroup.Protect Password:="KqtgH5rn9v"
''MsgBox "Ranges have been updated sucessfully."
' Save the workbook to the folder and close.
On Error Resume Next
wb.SaveAs Filename:=Folder.Path & "\" & wb.Name
ActiveWorkbook.Close True
On Error GoTo 0
End If
Next wb
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Sub ProcessNamedRanges(ByRef wb As Workbook)
Dim dstRng As Range
Dim rng As Range
Dim rngName As Range
Dim rngNames As Range
Dim wks As Worksheet
Set wks = ThisWorkbook.Sheets("Output - Flat")
' Exit if there are no named ranges listed.
If wks.Range("D4") = "" Then Exit Sub
Set rngNames = wks.Range("D4").CurrentRegion
Set rngNames = Intersect(rngNames.Offset(1, 0), rngNames.Columns(2))
'Loop through all the values in NamedRange
For Each rngName In rngNames
' Verify the Named Range exists.
On Error Resume Next
Set dstRng = wb.Names(rngName.Text).RefersToRange
If Err = 0 Then
'Copy the report balance to the Template worksheet in column "G".
dstRng.Value = rngName.Offset(0, 1).Value
Else
'answer = MsgBox("The Named Range """ & rngName.Value & """ Does Not Exist" & vbLf & vbLf & "Continue?", vbYesNo + vbExclamation)
'If answer = vbNo Then Exit Sub
End If
On Error GoTo 0
Next rngName
End Sub
Sub BreakLinks(ByRef wb As Workbook)
Dim i As Long
Dim wbLinks As Variant
wbLinks = wb.LinkSources(xlExcelLinks)
If Not IsEmpty(wbLinks) Then
For i = 1 To UBound(wbLinks)
ActiveWorkbook.BreakLink wbLinks(i), xlLinkTypeExcelLinks
Next i
End If
End Sub