Type Mismatch Error Excel - vba

I am currently running a VBA script in excel to allow for specific username and password access to specific sheets. I was following this tutorial on youtube and everything seemed to be going well until I began encountering errors.
I am getting a Type mismatch error in my code, which is below. There are two lines that are giving me errors, they are commented, any help would be greatly appreciated!
Option Explicit
Sub CheckUser()
Dim UserRow, SheetCol As Long
Dim SheetNm As String
With Sheet34
.Calculate
If .Range("B6").Value = Empty Then 'Incorrect Username
MsgBox "Please enter a correct username"
Exit Sub
End If
If .Range("B5").Value <> True Then 'Incorrect Password
MsgBox "Please enter a correct password"
Exit Sub
End If
UserForm1.Hide
UserRow = .Range("b6").Value 'userrow
.Range("B3").Value = ""
.Range("b4").Value = ""
For SheetCol = 6 To 26
SheetNm = .Cells(2, SheetCol).Value 'SheetName
If .Cells(UserRow, SheetCol).Value = "Ð" Then ' line where error occurs
Sheets(SheetNm).Protect "TEP2003"
Sheets(SheetNm).Visible = xlSheetVisible
End If
If .Cells(UserRow, SheetCol).Value = "Ï" Then ' line where error occurs
Sheets(SheetNm).Visible = xlVeryHidden
End If
Next SheetCol
End With
End Sub
Sub closeworkbook()
Sheet1.Activate
Dim WkSht As Worksheet
For Each WkSht In ThisWorkbook.Worksheets
If WkSht.Name <> "Main" Then WkSht.Visible = xlSheetVeryHidden
Next WkSht
ThisWorkbook.Save
End Sub

Use the Range.Text property. Range.Text will not fix a worksheet error code but it will evaluate one as text where Range.Value will fail. Combine the two with an ElseIf; there is no point in evaluating the second if the first passes.
...
If .Cells(UserRow, SheetCol).Text = "Ð" Then
...
ElseIf .Cells(UserRow, SheetCol).Text = "I" Then
...
End If

Related

How to use Public Range value in multiple user forms?

I have a userform which will ask for a number that is then getting looked up in a spreadsheet, saving that range in a variable. When it's found the number, it will hide the first userform and bring up the second one, but in order for me to proceed with the update, I will need to use the same range that I've previously set against my variable in userform1, any idea how to do that? I have declared it as a Public variable but it still doesn't work. Code as it follows:
UserForm1:
Public FillRange As Range
Public BKref As Variant
Private Sub CommandButton1_Click()
On Error GoTo errhndlr:
Set FillRange = Sheets("Loader").Cells.Find(TextRef.Value).Offset(0, 2)
BKref = TextRef.Value
If Not FillRange = "" Then
UserForm1.Hide
UserForm2.Show
Exit Sub
ElseIf FillRange = "" Then
MsgBox "Booking Reference cannot be empty!", vbCritical, "Error: No Booking Ref."
UserForm1.Hide
Exit Sub
Else
MsgBox "Unexpected error, please re-start and try again. If you had this message more than 2 times, please update the line manually.", vbCritical, "Error"
UserForm1.Hide
Exit Sub
End If
Exit Sub
errhndlr:
MsgBox "Booking reference not found, please double-check that the booking reference you've entered is correct, alternatively update it manually.", vbCritical, "Error"
UserFrom1.Hide
End Sub
UserForm2:
Private Sub CommandButton1_Click()
FillRange = TextPloaded.Value
FillRange.Offset(0, 2) = TextTime.Value
FillRange.Offset(0, 3) = TextLoader.Value
If Not TextComm.Value = "" Then
FillRange.Offset(0, 4) = TextComm.Value
ElseIf TextComm.Value = "" Then
FillRange.Offset(0, 4) = ""
End If
If Not FillRange = FillRange(0, -1) Then
MsgBox "Actual and Planned pallets doesn't match, please highlight the diescrepancies on the assembly sheet!"
BKref = FillRange.Offset(0, -2)
Sheets("Assembly").Activate
Sheets("Assembly").Rows(1).AutoFilter Field:=16, Criteria1:=BKref
UserForm2.Hide
Else
UserForm2.Hide
UserForm1.Show
End If
End Sub
If you make use of Option Explicit in every module/userform etc. This forces you to declare all variables properly and shows a message if a variable is not declared.
The issue is that if you declare Public FillRange As Range in Userform1 the variable is only valid in Userform1 but not in Userform2.
So I recommend to decare the variable in a Module instead of Userform1. This way it is accessible everywhere.
Alternative
You can access a public Userform1 variable in Userfrom2 by Userform1.FillRange
Add a property in your first form:
Property Get FillRange() As Range
Set FillRange = Range("A1")
End Property
And read it from your second form:
Dim FillRange
Set FillRange = UserForm1.FillRange

Run-Time Error 91: Can't run through the second line

Here is part of the code I am working on which is a part of a macro.
This is also the same on another file which is basically the same also.
The macro works on the other file while on the other, it doesn't and comes with the Run-time error '91'.
Attached is the code:
shtData.Activate
Dim r As Integer
Dim strassured As String
r = 1
While ActiveSheet.Cells(r, 1) <> ""
ActiveSheet.Cells(r, 1).Select
strassured = ActiveCell.Value
If shtWorkSpace.Range("B3").Value = strassured Then
If shtWorkSpace.Range("A60").Value = "Pending" Then
DataHandling.OverwriteDataTab (strassured)
Exit Sub
Else
MsgBox "This assured name is already in the database. Assured Names must be unique!", vbCritical
shtWorkSpace.Activate
ActiveSheet.Range("A1").Select
Exit Sub
End If
Else
r = r + 1
End If
Wend
I've added an answer, not to provide how to define and Set both worksheets (shtData and shtWorkSpace).
But also to provide a better coding practice, there is no need to Activate worksheets, or use Select and ActiveCell. Instead use fully qualified Ranges and Worksheets.
Code
Sub Test()
Dim shtData As Worksheet
Dim shtWorkSpace As Worksheet
Dim r As Integer
Dim strassured As String
Set shtData = Worksheets("Data") '<-- modify "Data" to your sheet name
Set shtWorkSpace = Worksheets("Workspace") '<-- modify "Workspace" to your sheet name
r = 1
While shtData.Cells(r, 1) <> ""
strassured = shtData.Cells(r, 1).Value
If shtWorkSpace.Range("B3").Value = strassured Then
If shtWorkSpace.Range("A60").Value = "Pending" Then
DataHandling.OverwriteDataTab (strassured)
Exit Sub
Else
MsgBox "This assured name is already in the database. Assured Names must be unique!", vbCritical
shtWorkSpace.Activate
ActiveSheet.Range("A1").Select '<-- not sure why you need to select the sheet and Range("A1")
Exit Sub
End If
Else
r = r + 1
End If
Wend
End Sub

Setting Cells or Ranges to Blank on different worksheets through VBA code

I am having difficulty setting Ranges and cells to a blank value on different worksheets, UNLESS the worksheet is visible.
The code is as follows:
Sub Clean_Up_Ranges()
Dim nm As Worksheet
On Error Resume Next
For Each nm In Worksheets
Worksheets("nm").Select
Range("d7:d37") = ""
Range("k7:k37") = ""
Range("L40:l42") = ""
'..... plenty more ranges
Range("h80:j179") = ""
Calculate
Debug.Print nm.Name
Next
On Error GoTo 0
End Sub
Any ideas appreciated.
Explicitly reference the sheet.
Sub Clean_Up_Ranges()
Dim nm As Worksheet
On Error Resume Next
For Each nm In Worksheets
'Worksheets("nm").Select
nm.Range("d7:d37") = ""
nm.Range("k7:k37") = ""
nm.Range("L40:l42") = ""
'..... plenty more ranges
nm.Range("h80:j179") = ""
Calculate
Debug.Print nm.Name
Next
On Error GoTo 0
End Sub
You can use Activate keyword in your code which will activate the sheet.
See This to know difference between SHEETS.SELECT or SHEETS.ACTIVATE.
Sub Clean_Up_Ranges()
Dim nm As Worksheet
On Error Resume Next
For Each nm In Worksheets
nm.Activate 'Activate the sheet
Range("d7:d37") = ""
Range("k7:k37") = ""
Range("L40:l42") = ""
'..... plenty more ranges
Range("h80:j179") = ""
Calculate
Debug.Print nm.Name
Next
On Error GoTo 0
End Sub

Getting a "Subscript out of range" error, and I don't know whats wrong. (I'm kind of new to vba)

This is my code:
Private Sub New_User_Create_Click()
CreateUsername_L = LCase(Create_User_Text.Text)
For Each ws In Worksheets
If (Worksheets(CreateUsername_L).Name <> "") Then
MsgBox "Username is already taken! Try again!"
Create_User_Text.Text = ""
NewUser.Hide
Exit For
Else
Dim work As Worksheet
With ThisWorkbook
Set worksheetname = .Sheets.Add(After:=Worksheets(Worksheets.Count))
worksheetname.Name = CreateUsername_L
On Error Resume Next
Create_User_Text.Text = ""
NewUser.Hide
[B1].Value = (UserName + "'s Personal Profile")
Exit For
End With
End If
Next ws
End Sub
If you could help me with this it would be much appreciated
(also the error only occurs when the condition is not met e.g there is no sheet with the same name as "CreateUsername_L". When the condition is met the message box with "Username is already taken..." shows up so its only when the condition is not met when this error occurs)
You can't test for the existance of the worksheet name like you're trying to do. The 'Subscript out of range' error is looking for that worksheet name and if it can't find it then you get your error. You can write a function to test for the existence of a name and use that instead. Here's mine:
Public Function doesSheetNameExist(inputName As String) As Boolean
Dim ws As Worksheet
On Error GoTo ErrorCatch
Set ws = Thisworkbook.Worksheets(inputName)
'if no error here then worksheet exists
doesSheetNameExist= True
CloseFunction:
Exit Function
ErrorCatch:
doesSheetNameExist= False
Resume CloseFunction
End Function
This handles the error within the function. Alternatively you could loop through each worksheet and test the name.
You'd then replace your line
If (Worksheets(CreateUsername_L).Name <> "") Then
with
If doesSheetNameExist(CreateUsername_L) Then

Need to copy certain data over workbooks

new to VBA here. I've been stuck on this problem for a while now:
Essentially, I need to create a macro that copies over specific data from one sheet to another, that is up to the user to specify. The catch is that while all the data is in one column (B), not all rows of the column have relevant entries; some are blank and some have other data that I don't want.
Only entries that begin with 4 numbers are wanted. I can't seem to get how the iterated copy-pasting works; what I've come up with is as follows:
'defining input
Dim dater As Date
dater = Range("B2")
If dater = False Then
MsgBox "Date not specified"
Exit Sub
End If
Dim sheetin As String
sheetin = Range("B5")
If sheetin = "" Then
MsgBox "Input Sheet not specified"
Exit Sub
End If
Dim wbin As String
wbin = Range("B4")
If wbin = "" Then
MsgBox "Input workbook not specified"
Exit Sub
End If
Dim sheetout As String
sheetout = Range("B9")
If sheetout = "" Then
MsgBox "Output Sheet not specified"
Exit Sub
End If
Dim wbout As String
wbout = Range("B8")
If wbout = "" Then
MsgBox "Output Workbook not specified"
Exit Sub
End If
Windows(wbout).Activate
Dim sh As Worksheet, existx As Boolean
For Each sh In Worksheets
If sh.Name Like sheetout Then existx = True: Exit For
Next
If existx = True Then
If Sheets(sheetout).Visible = False Then Sheets(sheetout).Visible = True
Else
Sheets.Add.Name = CStr(sheetout)
End If
'copy pasting values
Windows(wbin).Activate
Sheets(sheetin).Select
'specify maximum row
iMaxRow = 500
For iRow = 1 To iMaxRow
With Worksheets(sheetin).Cells(iRow, 2)
'Check that cell is not empty.
If .Value = "####*" Then
.Copy Destination:=Workbooks(wbout).Worksheets(sheetout).Range("A" & i)
'Else do nothing.
End If
End With
Next iRow
End Sub
Subsequently i'll have to match data to these entries that have been copied over but I figure once i get the hang of how to do iterated stuff it shouldn't be too much of a problem. But right now i'm really stuck... Please help!
It looks like it should work, except for that part :
With Worksheets(sheetin).Cells(iRow, 2)
If .Value = "####*" Then
.Copy Destination:=Workbooks(wbout).Worksheets(sheetout).Range("A" & i)
End If
End With
The third line contains an unknown variable : i.
You need to define it to contain the number of the line to which you're copying. For example, if you want to copy to the first available line, try this :
Set wsOut = Workbooks(wbout).Worksheets(sheetout)
With Worksheets(sheetin).Cells(iRow, 2)
If .Value = "####*" Then
i = wsOut.Cells(wsOut.Rows.Count, 1).End(xlUp).Row + 1
.Copy Destination:=wsOut.Range("A" & i)
End If
End With