I was wondering if someone could assist me please. I have created a very simple userform to log information. My issue is however when one of the fields is blank I am receiving an error message :
Sub or Function not defined.
Private Sub CommandButton1_Click()
Dim iRow As Long
Dim ws As Worksheet
Set ws = Worksheets("Data")
'find first empty row in database
iRow = ws.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1
'check for a Name number
If Trim(QueryType.Value) = "" Then
QueryType.SetFocus
MsgBox "Please complete the form"
Exit Sub
End If
'copy the data to the database
ws.Cells(iRow, 1).Value = Format(Now, "DD/MM/YYYY")
ws.Cells(iRow, 2).Value = Format(Now, "HH:MM")
ws.Cells(iRow, 3).Value = Application.UserName
ws.Cells(iRow, 4).Value = CType.Value
ws.Cells(iRow, 5).Value = IName.Value
ws.Cells(iRow, 6).Value = QType.Value
ws.Cells(iRow, 7).Value = 1
ws.Cells(iRow, 8).Value = Format(Date, "MMM-YY")
'ws.Cells(iRow, 9).Value = Application.WorksheetFunction.VLookup(InternalName.Value, Sheet2.Range("C1:D23"), 2, 0)
'ws.Cells(iRow, 9).Value = Application.WorksheetFunction.IfError(VLookup(InternalName.Value, Sheet2.Range("C1:D23"), 2, 0), "")
ws.Cells(iRow, 10).Value = Application.WorksheetFunction.VLookup(InternalName.Value, Sheet2.Range("C1:E23"), 3, 0)
ws.Cells(iRow, 11).Value = "IB"
Unload Me
MsgBox "Data added", vbOKOnly + vbInformation, "Data Added"
End Sub
The issue is in either one of the commented out lines where I receive the error. I only receive if I leave the dropdown box empty. If populated then no error occurrs. I could easily fit an extra menu option for "Not Applicable" however would rather it was just blank. Does anyone have any suggestions at all please?
Three things.
1- VLookup is not a VBA function on its own, it's a member method of either the Application object or the WorksheetFunction object. So you should qualify VLookup by either, even if you had it inside another method, such as WorksheetFunction.IfError(...).
ws.Cells(iRow, 9).Value =
WorksheetFunction.IfError(WorksheetFunction.VLookup(InternalName.Value, Sheet2.Range("C1:D23"), 2, 0), "")
' ^^^^^^^^^^^^^^^^^^
2- The same methods in WorksheetFunction and in Application objects work differently. In the former, an error is raised in VBA if the result is an error (such as: no match for the searched value). In the latter, no error is raised, but the returned value is an Error Variant. This latter form is usually safer for VBA, because you dont need to have some On Error Resume Next or so, but you can just check the result with If(IsError(result)).
3- When your search criteria is empty or unmatched, you had the error raised due to the use of WorksheetFunction.VLookup (According to 2). If your intention is to just set the resulting value and proceed, you can use Application.VLookup instead:
ws.Cells(iRow, 9).Value = Application.IfError(Application.VLookup(InternalName.Value, Sheet2.Range("C1:D23"), 2, 0), "")
p.s. I personally prefer Application. most of the time. Some prefer WorksheetFunction mostly because it offers Intellisense, but I find that pretty useless, because the arguments of the methods in Intellisense are unnamed and untyped, i.e. VLookup(arg1, arg2, arg3, [arg4]).. (non-sense to me).
Related
I have written some VBA in excel to iterate a relatively large set of data in order to perform some basic formatting and tidying up. The code previously worked and still works when I use a break point and step through it. However, when i don't step through it and just let the code run by itself, the spreadsheet becomes unresponsive. Once I've pressed escape a few times I get the runtime 1004 error (see title) and the relevant line is hightlighted.
I'd like to reiterate that when i set a break point on the offending line and step through it, it works fine and the row is deleted as appropriate. Also when I test the syntax in a much smaller data set it works perfectly so this is not syntax related.
Any help will be greatly appreciated because I'm stumped. Here is the code:
Private Sub CommandButton21_Click()
Dim index As Integer, lapsedSchemes As New Collection, lapseDates As New
Collection
Dim iRow As Long
Dim iCol As Integer
Sheet1.Columns(5).NumberFormat = "dd-mmm-yy"
Sheet1.Columns(14).NumberFormat = "dd-mmm-yy"
iRow = 2
Do While Sheet3.Cells(iRow, 1).Value <> ""
lapsedSchemes.Add Sheet3.Cells(iRow, 1).Value
lapseDates.Add Sheet3.Cells(iRow, 2).Value
iRow = iRow + 1
Loop
iRow = 2
Do While Cells(iRow, 7).Value <> ""
index = 1
If Cells(iRow, 9).Value = "" Then
If Cells(iRow, 7).Value = Cells(iRow, 8).Value Then
Cells(iRow, 9).Value = "Policy Holder"
Else
Cells(iRow, 9).Value = "Dependant"
End If
End If
For Each scheme In lapsedSchemes
If Cells(iRow, 4).Value = scheme And Cells(iRow, 5) = lapseDates(index) Then
Cells(iRow, 4).EntireRow.Delete
iRow = iRow - 1
Exit For
End If
index = index + 1
Next scheme
iRow = iRow + 1
Loop
appendLegacyData (iRow)
Range("A1:AZ10000").Sort Key1:=Range("A1"), Order1:=xlAscending, Key2:=Range("D1"), Order2:=xlAscending, Key3:=Range("E1"), Order3:=xlAscending, Header:=xlYes
End Sub
The offending line is:
Cells(iRow, 4).EntireRow.Delete
The sheet becomes unresponsive and only when I press escape a few times does the runtime error show.
Unresponsive doesn't mean that Excel crashed. Deleting rows one by one is just painfully slow.
You can use
application.statusbar=cstr(iRow)
DoEvents
to see your progress and keep Excel responsive.
If it will work to slow, I recommend you to set some value in rows to delete, sort by that value and then delete them all together.
Fellow StackOverFlow-ians,
I come to you with another question that i'm trying to learn from.
I have a UserForm which adds Employees to an Employee-database.
Code is as below, and working perfectly.
Private Sub CommandButton1_Click()
Dim iRow As Long
Dim ws As Worksheet
Set ws = Worksheets("Employee-Data")
iRow = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ws.Cells(iRow, 4).Value = Me.TextBox1.Value
ws.Cells(iRow, 3).Value = Me.TextBox2.Value
ws.Cells(iRow, 7).Value = Me.TextBox3.Value
ws.Cells(iRow, 6).Value = Me.TextBox4.Value
ws.Cells(iRow, 15).Value = Me.TextBox5.Value
ws.Cells(iRow, 9).Value = Me.TextBox6.Value
ThisWorkbook.Save
Unload Employee
End Sub
My problem is as following, I want to restrict the format of TextBox6 to a Dutch telephone-number, which is 06-########. I want TextBox6 to show 06- and make it only able to type 8 numbers in as Value.
I've tried the following and more:
Private Sub TextBox6_Change()
TextBox1.Text = Format(ws.Cells(iRow, 9).Value,"##""-"########")
End Sub
What is my error in thinking here, am i using a wrong approach? Can anybody suggest a decent solution for this problem? As said before, trying to learn from my errors, so please tell me what I'm doing wrong instead of just providing a solution.
ws.Cells(iRow, 9).Value = "06-" & Me.TextBox6.Value
Be aware of cell formatting as you may get a date. Convert to text or number etc.
I am at a very basic part of VB and I am stuck with this relentless issue. I am trying to copy data from a form to a bunch of cells in excel and I am facing this error.
Object doesn't support this property or method: Runtime Error - 438
Although the first row gets inserted. The issue is with the second row. I don't see the problem. Kindly help
Sub sbInsertingRows()
Range("A3").EntireRow.Insert
End Sub
Sub EditAdd()
sbInsertingRows
Cells(3, 19).Value = Order_Details_Form.Controls(TextBox_orderid).Value
Cells(3, 20).Value = Order_Details_Form.Controls(TextBox_name).Value
Cells(3, 24).Value = Order_Details_Form.Controls(TextBox2).Value
ActiveWorkbook.Save
End Sub
EditAdd gets called on click
I think TextBox_orderid is a name of your textbox control not a variable so you should enclose it with " like:
Cells(3, 19).Value = Order_Details_Form.Controls("TextBox_orderid").Value
Or you can simply use:
Cells(3, 19).Value = Order_Details_Form.TextBox_orderid.Value
Apply this at your other two lines.
Hi sorry this is almost certainly going to be a "doh" moment but I haven't coded for a long time and I'm a bit rusty.
I have a cell value which I keep getting a type mismatch when I try and treat it as a string, yet CStr and testing for IsNull etc don't seem to help. Grateful for some advice.
Set ClientTable = SourceBook.Sheets("Source Data").Range("extdata")
For Each rng1 In ClientTable.Columns(1).Cells
'if not first row (header row) and the customer name is matching the selected customer
If (i <> 0) And (rng1.Value = SourceBook.Sheets("Source Data").Range("C1")) Then
If Not IsNull(ClientTable.Columns(6).Cells.Offset(i, 0).Value) Then
MsgBox ClientTable.Columns(6).Cells.Offset(i, 0).Value ' type mismatch here
End If
With Sheets("Contacts").Range("A1")
.Offset(rowToWriteTo, 0).Value = ClientTable.Columns(6).Cells.Offset(i, 0).Value ' first name
.Offset(rowToWriteTo, 1).Value = ClientTable.Columns(2).Cells.Offset(i, 0).Value ' last name
.Offset(rowToWriteTo, 5).Value = ClientTable.Columns(3).Cells.Offset(i, 0).Value ' email
.Offset(rowToWriteTo, 6).Value = ClientTable.Columns(4).Cells.Offset(i, 0).Value ' DDI
.Offset(rowToWriteTo, 7).Value = ClientTable.Columns(7).Cells.Offset(i, 0).Value ' mobile
.Offset(rowToWriteTo, 8).Value = ClientTable.Columns(5).Cells.Offset(i, 0).Value ' title
End With
rowToWriteTo = rowToWriteTo + 1
End If
i = i + 1
Next
If I remove this bit of code the Sheets("Contacts").Range("A1") assignments all work fine.
PS: use of MsgBox is just for debugging. Trying to assign ClientTable.Columns(6).Cells.Offset(i, 0).Value to a string variable produces the same error.
Many thanks in advance for any assistance!
The expression ClientTable.Columns(6).Cells.Offset(i, 0).Value results in an array of values because Columns(6) is a Range object with multiple cells. You can't assign this array to a string. Maybe you should use ClientTable.Cells(i, 6).Value instead. So you get a single value.
I am programming a little and easy add client code. But when I add a client it gives me this little error where I can't get rid off. Maybe it will be an easy solution. Here is my code:
Private Sub btn_Toevoegen_Click()
Dim laatsteKlantNummer As Integer
Range("B4:B13").End(xlDown).Select
laatsteKlantNummer = ActiveCell.Value
ActiveCell.Offset(1, 0).Value = txtKlant
ActiveCell.Offset(1, 1).Value = txtNaam
ActiveCell.Offset(1, 2).Value = txtAdres
ActiveCell.Offset(1, 3).Value = txtWoonplaats
ActiveCell.Offset(1, 4).Value = txtContact
Me.Hide
Range("B4:B13").Sort Key1:=Range("B4:B13"), Order1:=xlAscending
End Sub
This code works properly but the thing happening is when it places it in the excel worksheet it is placed as text and not as number. So it gives me the error: "Number stored as text". After that I can click convert to number. Like this:(http://i.imgur.com/mfMnGFI.png) But is it possible to code it instead of clicking it all the time?
I am not sure on what line you get this error, but for example if its this one:
ActiveCell.Offset(1, 4).Value = txtContact
You can add this to 'convert' it to a number:
ActiveCell.Offset(1, 4).Value = txtContact + 0