I'm trying to rename all sheets and then put them in alphabetical order.
I'm getting the error Method 'Name' of object'_Worksheet' failed.
Any guidance is greatly appreciated
Sub Rename()
Dim ws As Worksheet, str As String
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "Summary" Then
Range("S4").Select
ActiveCell.Formula = "=SUBSTITUTE(TRIM(RIGHT($A$4,LEN($A$4)-16)),"","","""")"
str = ws.Range("S4").Value
ws.Name = str
End If
Next ws
End Sub
Sub Rename()
Dim ws As Worksheet, str As String
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "Summary" Then
ws.Range("S4") = "=SUBSTITUTE(TRIM(RIGHT($A$4,LEN($A$4)-16)),"","","""")"
str = ws.Range("S4").Value
ws.Name = str
End If
Next ws
End Sub
I think the code could be like this. Note that there are restrictions for naming sheets and sheet names cannot be repeated. So I recommend using Debug.Print when debugging code (included in the code).
Option Explicit
Sub Rename()
Dim ws As Worksheet, txt As String, a As Variant, i As Long, j As Long
ReDim a(1 To ActiveWorkbook.Worksheets.Count) As String
i = 0
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "Summary" Then
txt = ws.Range("A4").Text
txt = Replace(Trim(Right(txt, Len(txt) - 16)), ",", "") 'we don't know what is in A4, so you need to tweak it
Debug.Print "Trying to rename sheet '" & ws.Name & "' to '" & txt & "'..."
On Error Resume Next
ws.Name = txt
If Err.Number <> 0 Then
Debug.Print vbTab & "FAILED to rename the sheet '" & ws.Name & "' to '" & txt & "'"
Else
i = i + 1
a(i) = txt
End If
On Error GoTo 0
End If
Next ws
If i > 0 Then
ReDim Preserve a(1 To i)
' bubble sort sheets names
For i = LBound(a) To UBound(a)
For j = LBound(a) To UBound(a)
If a(i) < a(j) Then
txt = a(i): a(i) = a(j): a(j) = txt
End If
Next j
Next i
' rearrange the sheets
For i = UBound(a) To LBound(a) Step -1
ActiveWorkbook.Worksheets(a(i)).Move Before:=ActiveWorkbook.Worksheets(1)
Next i
Else
MsgBox "No sheets renamed", vbCritical
End If
End Sub
Related
I am trying to do the macro which can do autofilter and copy the visible row , then paste them into the new sheet by using VBA. my code as below:
Option Explicit
Sub lab()
Dim ws As Worksheet
Dim sh1 As Worksheet
Dim mycoll As Collection
Set mycoll = New Collection
Set sh1 = ThisWorkbook.Sheets(1)
Dim rng As Range
Dim c As Range
Dim lastrow As Long
lastrow = Range("C" & Rows.Count).End(xlUp).Row
On Error Resume Next
Set rng = sh1.Range("B4:F" & lastrow)
With rng
.AutoFilter field:=2, Criteria1:=sh1.Range("I1"), Criteria2:=sh1.Range("I2"), Operator:=xlOr
.AutoFilter field:=3, Criteria1:=sh1.Range("K1"), Criteria2:=sh1.Range("K2"), Operator:=xlOr
.AutoFilter field:=4, Criteria1:=sh1.Range("M1"), Criteria2:=sh1.Range("M2"), Operator:=xlOr
End With
Set ws = Worksheets.Add
ws.Name = sh1.Range("I1").Value & "-" & sh1.Range("I2").Value
rng.SpecialCells(xlCellTypeVisible).Copy ws.Range("A1")
rng.AutoFilter
sh1.Activate
End Sub
my problem is the code only work correctly for the first new sheet. then it always create the sheet with the same content. I tried to find the root issue , could you please help assist on this ?
When there is a problem with your code, you never use On Error Resume Next! It only does not let VBA 'telling' you what problem the code has...
If your code names the newly created sheet using:
ws.Name = sh1.Range("I1").Value & "-" & sh1.Range("I2").Value
second time, if the concatenation of the two cells value is the same, VBA cannot name a sheet with the same name like an existing one. The raised error should have a clear description but your code jumps over it, because of On error Resume Next.
If you really need/want to use a similar sheet name, try placing a sufix. For doing that, you can use the next function:
Function shName(strName As String) As String
Dim ws As Worksheet, arrSh, arrN, maxN As Long, k As Long, El
ReDim arrSh(ActiveWorkbook.Sheets.count - 1)
For Each ws In ActiveWorkbook.Sheets
If ws.Name = strName Then
shName = strName & "_" & 1
Exit Function
End If
If InStr(ws.Name, strName & "_") > 0 Then arrSh(k) = ws.Name: k = k + 1
Next
If k = 0 Then shName = strName: Exit Function 'if no such a name exists
ReDim Preserve arrSh(k - 1)
'determine the bigger suffix:
For Each El In arrSh
arrN = Split(El, "_")
If CLng(arrN(UBound(arrN))) > maxN Then maxN = CLng(arrN(UBound(arrN)))
Next
shName = strName & "_" & maxN + 1
End Function
It should be called from your existing code replacing the line
ws.Name = sh1.Range("I1").Value & "-" & sh1.Range("I2").Value
with
ws.Name = shName(sh1.Range("I1").Value & "-" & sh1.Range("I2").Value)
I've tried changing everywhere there was a cell to a range and other things but I can't figure it out. I'd like for the code to search the entire sheet, instead of one cell, for these names and paste the information of the cell to the right of it to the other sheet.
Option Explicit
Private Sub CommandButton1_Click()
Dim ws As Worksheet, myCounter As Long
Dim erow As Long, myValue As Long
Dim nextValue As Long
For Each ws In ThisWorkbook.Sheets
With ws
Select Case .Range("C3").Value
Case "David", "Andrea", "Caroline"
myCounter = 1 ' raise flag >> found in at least 1 sheet
' get first empty row in "Report" sheet
erow = Worksheets("Report").Cells(Worksheets("Report").Rows.Count, 1).End(xlUp).Offset(1, 0).Row
Worksheets("Report").Cells(erow, 1) = .Range("C3").Value
End Select ' Select Case .Range("C3").Value
End With
Next ws
If myCounter = 0 Then
MsgBox "None of the sheets contains the names " & Chr(10) & " 'David', 'Andrea', 'Caroline' in cell C3 ", vbInformation, "Not Found"
End If
End Sub
You can use Application.Match with array version. Substitute this for your loop:
Dim ar, r
For Each ws In ThisWorkbook.Sheets
ar = Application.match(Array("David", "Andrea", "Caroline"), ws.Columns("C"), 0)
For Each r In ar
If Not IsError(r) Then
myCounter = 1 ' raise flag >> found in at least 1 sheet
erow = Worksheets("Report").Cells(Worksheets("Report").Rows.Count, 1).End(xlUp).Offset(1, 0).row
Worksheets("Report").Cells(erow, 1) = ws.Range("C" & r).value
Worksheets("Report").Cells(erow, 2) = ws.Range("D" & r).value
End If
Next r
Next ws
Notice though, that this will find you only one match for each word, the first one. If each word can be repeated many times and you want to find all matches, it will need some modification.
Multiple rows and multiple columns would be better served by the Find command.
Option Explicit
Private Sub CommandButton1_Click()
Dim ws As Worksheet, bFound As Boolean, rFound As Range
Dim a As Long, aNames As Variant
aNames = Array("David", "Andrea", "Caroline")
For Each ws In ThisWorkbook.Worksheets
'If ws.Name <> Worksheets("Report").Name Then
If ws.Name = "Sheet7" Then
With ws.Range("A1:E30").Cells
For a = LBound(aNames) To UBound(aNames)
Set rFound = .Find(What:=aNames(a), MatchCase:=False, LookAt:=xlWhole, SearchFormat:=False)
If Not rFound Is Nothing Then
bFound = True
With Worksheets("Report")
.Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0) = rFound.Value
End With
End If
Next a
End With
End If
Next ws
If Not bFound Then
MsgBox "None of the sheets contains the names " & Chr(10) & _
"'" & Join(aNames, "', '") & "' in cells A1:E30.", vbInformation, "Not Found"
End If
End Sub
following my post If cell value matches a UserForm ComboBox column, then copy to sheet.
I have managed to get the code to work to move the check the names and move then to the correct sheets.
The problem i am having is checking if the sheets exists. If it finds a match in the sheet and column 2 in the combobox but there is no sheet for the value then it crashes the code.
Once all the information has been copied to the relevant sheets, i would like it to display a msgbox telling the user how many rows of data have been copied to the respective sheets.
Dim i As Long, j As Long, lastG As Long, strWS As String, rngCPY As Range
With Application
.ScreenUpdating = False
.EnableEvents = False
.CutCopyMode = False
End With
On Error GoTo bm_Close_Out
' find last row
lastG = sheets("Global").Cells(Rows.Count, "Q").End(xlUp).row
For i = 3 To lastG
lookupVal = sheets("Global").Cells(i, "Q") ' value to find
' loop over values in "details"
For j = 0 To Me.ComboBox2.ListCount - 1
currVal = Me.ComboBox2.List(j, 2) ' value to match
If lookupVal = currVal Then
Set rngCPY = sheets("Global").Cells(i, "Q").EntireRow
strWS = Me.ComboBox2.List(j, 1)
On Error GoTo bm_Need_Worksheet '<~~ if the worksheet in the next line does not exist, go make one
With Worksheets(strWS)
rngCPY.Copy
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Insert shift:=xlDown
End With
End If
Next j
Next i
GoTo bm_Close_Out
bm_Need_Worksheet:
On Error GoTo 0
With Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsTemplate As Worksheet: Set wsTemplate = wb.sheets("Template")
Dim wsPayment As Worksheet: Set wsPayment = wb.sheets("Payment Form")
Dim wsNew As Worksheet
Dim lastRow2 As Long
Dim Contract As String: Contract = sheets("Payment Form").Range("C9").value
Dim SpacePos As Integer: SpacePos = InStr(Contract, "- ")
Dim Name As String: Name = Left(Contract, SpacePos)
Dim Name2 As String: Name2 = Right(Contract, Len(Contract) - Len(Name))
Dim NewName As String: NewName = strWS
Dim CCName As Variant: CCName = Me.ComboBox2.List(j, 0)
Dim lastRow As Long: lastRow = wsPayment.Range("U36:U53").End(xlDown).row
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
lastRow2 = wsPayment.Range("A23:A39").End(xlDown).row
Else
lastRow2 = wsPayment.Range("A18:A34").End(xlDown).row
End If
wsTemplate.Visible = True
wsTemplate.Copy before:=sheets("Details"): Set wsNew = ActiveSheet
wsTemplate.Visible = False
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
With wsPayment
For Each cell In .Range("A23:A39")
If Len(cell) = 0 Then
If sheets("Payment Form").Range("A20").value = "Network" Then
cell.value = NewName & " - " & Name2 & ": " & CCName
Else
cell.value = NewName & " - " & Name2 & ": " & CCName
End If
Exit For
End If
Next cell
End With
Else
With wsPayment
For Each cell In .Range("A18:A34")
If Len(cell) = 0 Then
If sheets("Payment Form").Range("A20").value = "Network" Then
cell.value = NewName & " - " & Name2 & ": " & CCName
Else
cell.value = NewName & " - " & Name2 & ": " & CCName
End If
Exit For
End If
Next cell
End With
End If
If InStr(1, sheets("Payment Form").Range("A20").value, "THE VAT SHOWN IS YOUR OUTPUT TAX DUE TO CUSTOMS AND EXCISE") > 0 Then
With wsNew
.Name = NewName
.Range("D4").value = wsPayment.Range("A23:A39").End(xlDown).value
.Range("D6").value = wsPayment.Range("L11").value
.Range("D8").value = wsPayment.Range("C9").value
.Range("D10").value = wsPayment.Range("C11").value
End With
Else
With wsNew
.Name = NewName
.Range("D4").value = wsPayment.Range("A18:A34").End(xlDown).value
.Range("D6").value = wsPayment.Range("L11").value
.Range("D8").value = wsPayment.Range("C9").value
.Range("D10").value = wsPayment.Range("C11").value
End With
End If
wsPayment.Activate
With wsPayment
.Range("J" & lastRow2 + 1).value = 0
.Range("L" & lastRow2 + 1).Formula = "=N" & lastRow2 + 1 & "-J" & lastRow2 + 1 & ""
.Range("N" & lastRow2 + 1).Formula = "='" & NewName & "'!L20"
.Range("U" & lastRow + 1).value = NewName & ": "
.Range("V" & lastRow + 1).Formula = "='" & NewName & "'!I21"
.Range("W" & lastRow + 1).Formula = "='" & NewName & "'!I23"
.Range("X" & lastRow + 1).Formula = "='" & NewName & "'!K21"
End With
End With
On Error GoTo bm_Close_Out
Resume
bm_Close_Out:
With Application
.ScreenUpdating = True
.EnableEvents = True
.CutCopyMode = True
End With
With help from Jeeped I have manage to get the code for copying the rows to the relevant sheets, and if the sheet doesn't exists then it create it. I just need help with problem two above.
Attempting to use a Worksheet Object that does not exist throws an error. If you catch that error and create a worksheet with the name that you are looking for, you can Resume back to the point where the error was thrown and continue your processing.
Private Sub CommandButton7_Click()
Dim i As Long, j As Long, lastG As Long, strWS As String, strMSG As String
dim rngHDR as range, rngCPY aS range
With Application
.ScreenUpdating = False
.EnableEvents = False
.CutCopyMode = False
End With
On Error GoTo bm_Close_Out
' find last row
lastG = Sheets("Global").Cells(Rows.Count, "Q").End(xlUp).Row
For i = 3 To lastG
lookupVal = Sheets("Global").Cells(i, "Q") ' value to find
' loop over values in "details"
For j = 0 To Me.ComboBox2.ListCount - 1
currVal = Me.ComboBox2.List(j, 2) ' value to match
If lookupVal = currVal Then
set rngHDR = Sheets("Global").Cells(1, "Q").EntireRow
set rngCPY = Sheets("Global").Cells(i, "Q").EntireRow
strWS = Me.ComboBox2.List(j, 1)
On Error GoTo bm_Need_Worksheet '<~~ if the worksheet in the next line does not exist, go make one
With WorkSheets(strWS)
rngCPY .copy
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Insert shift:=xlDown
End With
exit for
End If
Next j
if j >= Me.ComboBox2.ListCount then _
strMSG = strMSG & "Not found: " & lookupVal & chr(10)
Next i
GoTo bm_Close_Out
bm_Need_Worksheet:
On Error GoTo 0
With Worksheets.Add(after:=Sheets(Sheets.Count))
.Name = strWS
'maybe make a header row here; watch out you do not lose your copy
rngHDR.copy destination:=.cells(1, 1)
End With
On Error GoTo bm_Close_Out
Resume
bm_Close_Out:
With Application
.ScreenUpdating = True
.EnableEvents = True
.CutCopyMode = False
End With
debug.print strMSG
'the next is NOT recommended as strMSG could possibly be VERY long
'if cbool(len(strMSG)) then msgbox strMSG
End Sub
There is a question about whether the new worksheet needs a column header label row but that should be fairly easily rectified.
You could use a function like this :
Sub test_atame()
Dim Ws As Worksheet
Set Ws = Sheet_Exists(ThisWorkbook, "Sheet1")
Set Ws = Sheet_Exists(ActiveWorkbook, "Sheet1")
End Sub
Here is the function :
Public Function Sheet_Exists(aWorkBook As Workbook, Sheet_Name As String) As Worksheet
Dim Ws As Worksheet, _
SExistS As Boolean
SExistS = False
For Each Ws In aWorkBook.Sheets
If Ws.Name <> Sheet_Name Then
Else
SExistS = True
Exit For
End If
Next Ws
If SExistS Then
Set Sheet_Exists = aWorkBook.Sheets(Sheet_Name)
Else
Set Sheet_Exists = Nothing
MsgBox "The sheet " & Sheet_Name & " wasn't found in " & aWorkBook.Name & vbCrLf & _
"Break code to check and correct.", vbCritical + vbOKOnly
End If
End Function
Maybe a check like:
Public Function SheetExists(ByVal Book As Workbook, ByVal SheetName As String) As Boolean
On Error Resume Next
Dim wsTest As Worksheet
Set wsTest = Book.Worksheets(SheetName)
If Not wsTest Is Nothing Then SheetExists = True
End Function
I am using the code below, to copy a hidden worksheet and copy it, rename is and fill in certain fields on two sheets.
I have done it like this, as i need to copy the layout and formatting of the hidden sheet.
The problem I am having, is that when i click the create button, if the sheet already exits, it completely crashes Excel, I have tried to add error handling but everything i have tried to check if the sheet exists doesn't work and still crashes Excel.
Have have separated the code that is un-hides the template sheet, copys it, renames the new sheet, and then re-hides the template.
What I would like it to do, is check the entered sheet name from TextBox5, and check is the sheet exists, if it does the display a message box, saying sheet already exists, if the sheet does not exist them carry on with the code as normal.
If really appreciate all the help and support i have already received, and thank all of you for the help you can provide with this.
Private Sub CommandButton3_Click()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets("Template")
Dim newws As Worksheet, sh As Worksheet, newname
Dim query As Long, xst As Boolean, info As String
Dim NextRow As Long, myCCName As Variant, lastRow2 As Long, lastRow As Long
'Contract Name
Dim Contact As String, name As String, name2 As String, SpacePos As Integer
Dim answer As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
.CutCopyMode = False
End With
lastRow2 = Sheets("Payment Form").Range("A18:A34").End(xlDown).Row
lastRow = Sheets("Payment Form").Range("U36:U53").End(xlDown).Row
'Contract Name
Set contract = Sheets("Payment Form").Range("C9")
SpacePos = InStr(contract, "- ")
name = Left(contract, SpacePos)
name2 = Right(contract, Len(contract) - Len(name))
'
retry:
xst = False
newname = Me.TextBox5.Value
myCCName = Me.TextBox4.Value
If newname = "" Then
MsgBox "You have not entered a CC Code Number. Please enter CC Code Number!", vbExclamation, "An Error Occured"
Exit Sub
End If
If myCCName = "" Then
MsgBox "You have not entered a CC Code Name. Please enter CC Code Name!", vbExclamation, "An Error Occured"
Exit Sub
End If
For Each sh In wb.Sheets
If sh.name = newname Then
xst = True: Exit For
End If
Next
If Len(newname) = 0 Or xst = True Then
info = "Sheet name is invalid. Please retry."
GoTo retry
End If
Sheets("Template").Visible = True
ws.Copy before:=Sheets("Details"): Set newws = ActiveSheet: newws.name = newname
Sheets("Template").Visible = False
With ActiveWorkbook.Sheets("Payment Form").Activate
For Each cell In Columns(1).Range("A18:A34").Cells
If Len(cell) = 0 Then cell.Select: Exit For
Next cell
ActiveCell.Value = newname & " " & "-" & name2 & ":" & " " & myCCName
End With
With ActiveWorkbook.Sheets(newname).Activate
ActiveWorkbook.Sheets(newname).Range("D4") = Sheets("Payment Form").Range("a18:a34").End(xlDown).Value
ActiveWorkbook.Sheets(newname).Range("D6") = Sheets("Payment Form").Range("L11").Value
ActiveWorkbook.Sheets(newname).Range("D8") = Sheets("Payment Form").Range("C9").Value
ActiveWorkbook.Sheets(newname).Range("D10") = Sheets("Payment Form").Range("C11").Value
End With
ActiveWorkbook.Sheets("Payment Form").Activate
With ActiveWorkbook.Sheets("Payment Form")
Range("J" & lastRow2 + 1) = 0
Range("L" & lastRow2 + 1).Formula = "=N" & lastRow2 + 1 & "-J" & lastRow2 + 1 & ""
Range("N" & lastRow2 + 1).Formula = "='" & newname & "'!L20"
Range("U" & lastRow + 1) = newname & ":" & " "
Range("V" & lastRow + 1).Formula = "='" & newname & "'!I21"
Range("W" & lastRow + 1).Formula = "='" & newname & "'!L23"
Range("X" & lastRow + 1).Formula = "='" & newname & "'!K21"
End With
answer = MsgBox("Would you like to create another sheet?", vbYesNo + vbQuestion, "New Sheet")
If answer = vbYes Then
Else
Unload Me
End If
With Application
.ScreenUpdating = True
.EnableEvents = True
.CutCopyMode = True
End With
Me.TextBox4.Value = ""
Me.TextBox5.Value = ""
End Sub
There appear to be a few general typos and a few errors with your 'With' statements throughout the code.
I have hopefully tidied up and recoded the function to work, but as it is untested I can't guarantee it will work off the bat.
I have also included the worksheet check function as a separate function
Private Sub CommandButton3_Click()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsTemplate As Worksheet: Set wsTemplate = wb.Sheets("Template")
Dim wsPayment As Worksheet: Set wsPayment = wb.Sheets("Payment Form")
Dim wsNew As Worksheet
Dim NewName As String: NewName = Me.TextBox5.Value
Dim CCName As Variant: CCName = Me.TextBox4.Value
If NewName = "" Or CCName = "" Then
MsgBox "CC Code Name or Number missing. Please check details!", vbExclamation, "An Error Occured"
Exit Sub
End If
If WorksheetExists(NewName) Then
MsgBox "Sheet name already exists. Please retry!", vbExclamation, "An Error Occured"
Exit Sub
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
.CutCopyMode = False
End With
Dim lastRow As Long: lastRow = wsPayment.Range("U36:U53").End(xlDown).Row
Dim lastRow2 As Long: lastRow2 = wsPayment.Range("A18:A34").End(xlDown).Row
'Contract Name
Dim Contract As String: Contract = Sheets("Payment Form").Range("C9").Value
Dim SpacePos As Integer: SpacePos = InStr(Contract, "- ")
Dim Name As String: Name = Left(Contract, SpacePos)
Dim Name2 As String: Name2 = Right(Contract, Len(Contract) - Len(Name))
wsTemplate.Visible = True
wsTemplate.Copy before:=Sheets("Details"): Set wsNew = ActiveSheet
wsTemplate.Visible = False
With wsPayment
For Each Cell In .Range("A18:A34")
If Len(Cell) = 0 Then
Cell.Value = NewName & " -" & Name2 & ": " & CCName
Exit For
End If
Next Cell
End With
With wsNew
.Name = NewName
.Range("D4").Value = wsPayment.Range("A18:A34").End(xlDown).Value
.Range("D6").Value = wsPayment.Range("L11").Value
.Range("D8").Value = wsPayment.Range("C9").Value
.Range("D10").Value = wsPayment.Range("C11").Value
End With
With wsPayment
.Range("J" & lastRow2 + 1).Value = 0
.Range("L" & lastRow2 + 1).Formula = "=N" & lastRow2 + 1 & "-J" & lastRow2 + 1 & ""
.Range("N" & lastRow2 + 1).Formula = "='" & NewName & "'!L20"
.Range("U" & lastRow + 1).Value = NewName & ": "
.Range("V" & lastRow + 1).Formula = "='" & NewName & "'!I21"
.Range("W" & lastRow + 1).Formula = "='" & NewName & "'!L23"
.Range("X" & lastRow + 1).Formula = "='" & NewName & "'!K21"
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
.CutCopyMode = True
End With
Dim Answer As Integer: Answer = MsgBox("Would you like to create another sheet?", _
vbYesNo + vbQuestion, "New Sheet")
If Answer = vbNo Then Unload Me
Me.TextBox4.Value = ""
Me.TextBox5.Value = ""
End Sub
Public Function WorksheetExists(ByVal WorksheetName As String) As Boolean
On Error Resume Next
WorksheetExists = (ThisWorkbook.Sheets(WorksheetName).Name <> "")
On Error GoTo 0
End Function
Personally i use the function below to check if a sheet allready exist in the workbook, in which case it returns True:
Public Function doItExist(strSheetName as String) As Boolean
Dim wsTest As Worksheet: Set wsTest = Nothing
On Error Resume Next
Set wsTest = ThisWorkbook.Worksheets(strSheetName)
On Error GoTo 0
If wsTest Is Nothing Then
doExist = False
Else
doExist = True
End If
End Function
I cannot seem to find the original source for the code, but I cannot take credit, it is mearly a modified version of some code I found on either SO, ozgrid or Mrexcel
EDIT:
Taking a closer look at your code, it seems you allready check for the existence of the sheetname in the xst variable. As far as I can see the user is not able to update the sheetname if is invalid, as the retry block will just keep looping?
under retry:
'### This bit essentially does the same as doSheetExist
For Each sh In wb.Sheets
If sh.name = newname Then
xst = True: Exit For
End If
Next
'###
If Len(newname) = 0 Or xst = True Then 'if you go for the doSheetExist, then the xst check is obsolete. Else move the xst check to the elseif and remove the doSheetExist call
info = "Sheet name is invalid. Please retry."
'GoTo retry 'As far as I can tell calling retry would just cause an infinite loop as the user have had no chance to update sheetname
Exit Sub 'let the user update and click the button again
ElseIf doSheetExist(newname) = True Then
info = "Sheet name allready exist. Please specify other sheetname"
Exit Sub
End If
I was wondering if someone can help me solve the following problem. Someone has previously helped me on get the % of dctest/In value on the same worksheet. But right now, i need to do the same thing but on a different worksheet.
Say Sheet1
this is copied Sheet1 (1) after taking the %
Sub marco1()
'start making Sheet1 into %
'~~> Add/Remove the text here which you want to ignore
Excludetext = "In,test1,test2,test3,test4,test5,test6"
MyArray = Split(Excludetext, ",")
Set ws = Sheets("Sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
'Set Column B into %
For i = 1 To LastRow
boolContinue = True
For j = 0 To UBound(MyArray)
SearchText = UCase(Trim(MyArray(j)))
If UCase(Trim(ws.Range("A" & i).Value)) = SearchText Then
boolContinue = False
Exit For
End If
Next j
If boolContinue = True Then
With Range("B" & i)
.Formula = _
"=OFFSET(INDIRECT(ADDRESS(INDEX(MATCH(A" & i & _
",$A$1:$A$45,0),1,0),1,1,1,'Duplicated_Sheet1')),0,1)/$B$5"
.NumberFormat = "0.00%"
End With
End If
Next i
End sub
There is some error showing at the formula, did i make a mistake with the formula? Thank you in advance!
Is this what you are trying?
TRIED AND TESTED
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim wsData As String
Dim SearchText As String, Excludetext As String
Dim LastRow As Long, i As Long, j As Long
Dim MyArray() As String
Dim boolContinue As Boolean
'~~> Add/Remove the text here
Excludetext = "In,Test1,Test2,Test3,Test4,Test5,Test6"
'~~> Change this to the relevant sheetname which has the data
wsData = "Sheet1"
MyArray = Split(Excludetext, ",")
Set ws = Sheets("Sheet2")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To LastRow
boolContinue = True
For j = 0 To UBound(MyArray)
SearchText = MyArray(j)
If ws.Range("A" & i).Value = SearchText Then
boolContinue = False
Exit For
End If
Next j
If boolContinue = True Then
With ws.Range("B" & i)
.Formula = _
"=OFFSET(INDIRECT(ADDRESS(INDEX(MATCH(A" & i & _
"," & wsData & "!$A$1:$A$11,0),1,0),1,1,TRUE,""" & _
wsData & """)),0,1)/" & wsData & "!B1"
.NumberFormat = "0.00%"
End With
End If
Next i
End Sub
When using ADDRESS() for a cell in different sheet, you have to specify additional arguments.
Straight from Excel's help
Syntax of ADDRESS Function
ADDRESS(row_num, column_num, [abs_num], [a1], [sheet_text])
Where [sheet_text] is the name of the sheet which we are referring to. I would recommend reading more about it in Excel Help.
This is the actual formula for say dctest
=OFFSET(INDIRECT(ADDRESS(INDEX(MATCH(A7,Sheet1!$A$1:$A$11,0),1,0),1,1,TRUE,"Sheet1")),0,1)/Sheet1!B1
HTH
Sid