I have an action log where users can select meeting name, user name, etc through a userform with comboboxes. I have also created a button where users can add a new meeting to the combo box list.
Currently I have a vba code that will check the value of a cell on sheet173 (data entered from userform), create a new sheet named with the cell value and copy the data from sheet173 into the new sheet. The problem I have is that if an action is added and there is already a sheet created for this, I need the data to be added to the next row of that sheet.
I have got the code working up until the point where the sheet is already created but additional rows need to be added. I know the exit sub needs to come out but i'm not sure what to replace it with.
Sub copy_newsheet()
Dim pname
Dim ws As Worksheet
pname = Sheets("Sheet173").Range("A1").Value
For Each ws In ActiveWorkbook.Sheets
If ws.Name = pname Then
Exit Sub
End If
Next ws
Sheets("Sheet173").Range("A1:E1").Copy
Sheets.Add After:=ActiveSheet
ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlPasteValues
ActiveSheet.Name = pname
End Sub
This should do it:
Option Explicit
Sub Test()
Dim pname As String
'full quallify your ranges, include the workbook
pname = ThisWorkbook.Sheets("Sheet173").Range("A1").Value 'thisworkbook means the workbook which contains the code
'with this variable we can know if the worksheet exists or not
Dim SheetExists As Boolean
SheetExists = False
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name = pname Then SheetExists = True
Next ws
'check if it doesn't exist
If Not SheetExists Then
'if it doesn't exist, then create the worksheet and give it the name from pname
With ThisWorkbook
.Sheets.Add After:=.Sheets(.Sheets.Count)
.Sheets(.Sheets.Count).Name = pname
End With
End If
'with this variable we can find the last row
Dim LastRow As Long
With ThisWorkbook.Sheets(pname)
'calculate the last row on the pname sheet
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
'equal the value from the pname sheet Range A:E to the sheet173 range A1:E1
.Range(.Cells(LastRow, "A"), .Cells(LastRow, "E")).Value = ThisWorkbook.Sheets("Sheet173").Range("A1:E1").Value
End With
End Sub
You are already pretty close, try this code:
Sub smth()
Dim pname As String
Dim ws As Worksheet, sh As Worksheet
pname = Sheets("Sheet173").Range("A1").Value
For Each sh In ActiveWorkbook.Sheets
If sh.Name = pname Then
Set ws = sh
GoTo Found
End If
Next sh
Set ws = Sheets.Add(After:=ActiveSheet)
ws.Name = pname
Found:
Sheets("Sheet173").Range("A1:E1").Copy
ws.Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlPasteValues
End Sub
To explain: If the For loop finds a sheet with the specified namen it will set ws as that sheet and jump to Found:, where the actual copying and pasting happens. If the For loop doesn't find anything it will set ws as a new sheet.
Please note that ActiveWorkbook and ActiveSheet can be prone to causing unwanted errors.
Related
So, say for instance I have 2 sheets in my workbook... Page1 and OldName.
On sheet Page1 in cell A1 there is the value OldName (where "OldName" happens to be sheet name of the sheet I would like to rename).
Also on Page1 in cell A2, there is the value NewName (where "NewName" is the name I would like to change the sheet specified in cell A1 to).
I am Trying to come up with code that uses the the cell A1 to identify which sheet I would like to rename and then use the cell A2 as the source for the rename value.
Any suggestions?
You may try something along these lines:
Sub Test()
Dim sht As Worksheet
With ThisWorkbook
For Each sht In .Worksheets
If sht.Name = .Worksheets("Page1").Cells(1, 1).Value Then
sht.Name = .Worksheets("Page1").Cells(2, 1).Value
Exit For
End If
Next
End With
End Sub
try this simple loop
Sub ChangeNameLoop()
Dim wb As Workbook
Dim ws As Worksheet
Dim OldName As String, NewName As string
Set wb = ThisWorkbook
OldName = ActiveSheet.Range("A1") ' location of names
NewName = ActiveSheet.Range("A2")
For Each ws In wb.Worksheets
If ws.Name = OldName Then
ws.Name = NewName
End If
Next ws
End Sub
No need to loop. This will do what you want. This code will replace the sheet name if found else will do nothing.
Option Explicit
Sub Sample()
On Error Resume Next
With ThisWorkbook
.Sheets(.Sheets("Page1").Cells(1, 1).Value2).Name = _
.Sheets("Page1").Cells(2, 1).Value2
End With
On Error GoTo 0
End Sub
Or something like this
Option Explicit
Sub Sample()
Dim ws As Worksheet
With ThisWorkbook
On Error Resume Next
Set ws = .Sheets(.Sheets("Page1").Cells(1, 1).Value2)
On Error GoTo 0
If Not ws Is Nothing Then ws.Name = _
.Sheets("Page1").Cells(2, 1).Value2
End With
End Sub
I am trying to write a macro that will look through all sheets in the workbook, and if a sheet name contains "blank", to rename that sheet with the value in cell C1.
Here is what I have so far:
Sub Rename()
Dim ws As Worksheet
Dim sheetBlank As Worksheet
Set sheetBlank = ActiveWorkbook.ActiveSheet
Dim nameCell As Range
Set nameCell = ActiveSheet.Range("C1")
For Each ws In Sheets
If sheetBlank.Name Like "*blank*" Then
sheetBlank.Name = nameCell.Value
End If
Next ws
End Sub
Now, this does rename the first active sheet, but it is not making any changes to the rest of them. What am I doing wrong?
You're referring to the wrong worksheet:
Sub Rename()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Name Like "*blank*" Then
ws.Name = ws.Range("C1").Value
End If
Next ws
End Sub
You set your objects outside the loop and never touch them again.
If you're going to use "ActiveSheet" you need to .Activate each sheet in order to work, but that's not a good approach since your iterator (ws) represents the sheet object.
Public Sub Rename()
Dim Ws As Worksheet
For Each Ws In Worksheets
If InStr(1, Ws.Name, "blank", vbTextCompare) > 0 Then _
Ws.Name = Ws.Range("C1").Value2
Next Ws
End Sub
I need help with one aspect of my VBA code. I have a Master worksheet that houses data on all of my customers. I currently have code that looks at Column B (Customer Name Column) and creates new worksheets/tabs for each unique customer. I then want to cut and paste every row from my Master worksheet into individual respective worksheets based on the customer name. I've included a picture of my Master worksheet. I've also included the code I'm currently working with is below, it creates the new tabs but won't copy and paste.
Sub CreateWSandCopyPaste()
Application.ScreenUpdating = False
Dim cell As Range
Dim thisSheetName As String
AWS = ActiveSheet.Name
'Creates new worksheet/tab for every unique value in Column B (Customer Code Column)
For Each cell In Range(Range("B2"), Range("B" & Rows.Count).End(xlUp))
If (cell.Value <> "") Then
If (IsSheetExist(cell.Value) = False) Then
Worksheets.Add after:=Worksheets(Worksheets.Count)
ActiveSheet.Name = cell.Value
End If
End If
Next
'Copy and paste value A:U if the value in column B matches the tab name
Dim ws As Worksheet
For Each ws In Sheets
If ActiveSheet.Range("B2").Value = ws.Name Then
ActiveSheet.Range("A:U").CurrentRegion.Copy Destination:=ws.Range("A:U" & Rows.Count).End(x1Up)
End If
Next
Application.ScreenUpdating = True
End Sub
Private Function IsSheetExist(ByVal newSheetName As String)
Dim ws As Worksheet
For Each ws In Worksheets
If (ws.Name = newSheetName) Then
IsSheetExist = True
Exit Function
End If
Next
' ---
IsSheetExist = False
End Function
Master Worksheet - Customer Column
You can do it like this:
Sub CreateWSandCopyPaste()
Dim cell As Range, v
Dim thisSheetName As String, wb As Workbook, ws As Worksheet
Application.ScreenUpdating = False
Set ws = ActiveSheet
Set wb = ws.Parent
'Creates new worksheet/tab for every unique value in Column B (Customer Code Column)
For Each cell In ws.Range(ws.Range("B2"), ws.Range("B" & Rows.Count).End(xlUp)).Cells
v = cell.Value
If Len(v) > 0 Then cell.EntireRow.Range("A1:U1").Copy _
GetSheet(v, wb).Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Next
Application.ScreenUpdating = True
End Sub
'Return a named sheet in wb (or create if doesn't exist)
Private Function GetSheet(ByVal SheetName As String, wb As Workbook)
Dim ws As Worksheet
On Error Resume Next
Set ws = wb.Worksheets(SheetName)
On Error GoTo 0
If ws Is Nothing Then
Set ws = wb.Worksheets.Add(after:=wb.Sheets(wb.Sheets.Count))
ws.Name = SheetName
End If
Set GetSheet = ws
End Function
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
I must jump between different excel sheets to grab data for my VBA to output what I want. I've been using the Sheets("name").Select function to jump between the sheets. Sometimes it works and lets me run the program, but other times I get a runtime error. I want this to work 100% of the time every time, and always get disheartened whenever it fails due to the select function. If anyone has any tips or recommendations I would love for you to share them! Any help would be greatly appreciated.
Sheets("Test").Select
Run-time Error '1004': Select Method of Worksheet Class Failed
Don't use Select (or Activate for that matter), it's bad practise and leads to errors rather quickly.
This thread is a great help as to why and how you should avoid using it.
There is no need to select a sheet before getting data from it. For example:
Sub test()
'''
'Bad practise:
'''
Sheets("Sheet1").Select
i = Range("A1")
'''
'Good practise
'''
i = Workbooks("Book1").Sheets("Sheet1").Range("A1").Value
'''
'Better practise
'''
Dim wb As Workbook
Dim sht As Worksheet
Dim i As String
Set wb = Workbooks("Book1")
Set sht = wb.Sheets("Sheet1")
With sht
i = .Range("A1").Value
End With
End Sub
With Statement:
Option Explicit
Sub test()
'Create a witrh statement with the Sheet name you want
With ThisWorkbook.Worksheets("Sheet1")
'Refer to cell A1 (don t forget the "." before Range)
.Range("A1").Value = ""
'Refer to cell A1 (don t forget the "." before Cells)
.Cells(1, 1).Value = ""
End With
End Sub
Loop Worksheets:
Option Explicit
Sub test()
Dim ws As Worksheet
'Loop Sheets
For Each ws In ThisWorkbook.Worksheets
With ws
'If sheet name is Sheet1 or Sheet3
If .Name = "Sheet1" Or .Name = "Sheet3" Then
'Refer to cell A1 (don t forget the "." before Range)
.Range("A1").Value = 2
'Refer to cell A1 (don t forget the "." before Cells)
.Cells(1, 1).Value = 10
ElseIf .Name = "Sheet2" Then
'Refer to cell A1 (don t forget the "." before Range)
.Range("A1").Value = 5
'Refer to cell A1 (don t forget the "." before Cells)
.Cells(1, 1).Value = 20
End If
End With
Next ws
End Sub
Set Worksheet To Variable
Option Explicit
Sub test()
Dim ws1 As Worksheet, ws2 As Worksheet
With ThisWorkbook
Set ws1 = .Worksheets("Sheet1")
Set ws2 = .Worksheets("Sheet2")
End With
End Sub