I have two sheets.
Data
Column A Column B Column C Column D Column E
1234
Sheet 1
Cell N3 = 1234
I am using this code to try and find the value in columns A-E.
But for some reason it always returns the wrong result.
Set c = Selection.Find(What:=Worksheets(1).Range("N3").Value, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Please can someone show me where I am going wrong?
Full Code:
Sub PhoneBook()
'Start Phone Book Directory Code
Dim Contact As String
Dim Email As String
Dim Phone As String
Dim Fax As String
'Start FIND
Dim c As Variant
With Worksheets("Contacts").Range("A2:E10000")
Set c = Selection.Find(What:=Worksheets(1).Range("N3").Value, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If c Is Nothing Then
'Introduce FailSafe, escape code if no result found
ThisWorkbook.Worksheets(1).Shapes("Suggest").Visible = False
ThisWorkbook.Worksheets(1).Shapes("Close").Visible = False
'ActiveSheet.Unprotect Password:="SecretPassword"
Else
'Check values are not blank
If c.Offset(0, 1).Value <> "" Then
Contact = "Contact: " & c.Offset(0, 1).Value & Chr(10)
Else
Contact = "Contact: No Contact Held" & Chr(10)
End If
If c.Offset(0, 2).Value <> "" Then
Email = "Email: " & c.Offset(0, 2).Value & Chr(10)
Else
Email = "Email: No Email Held" & Chr(10)
End If
If c.Offset(0, 3).Value <> "" Then
Phone = "Phone: " & c.Offset(0, 3).Value & Chr(10)
Else
Phone = "Phone: No Phone Held" & Chr(10)
End If
If c.Offset(0, 4).Value <> "" Then
Fax = "Fax: " & c.Offset(0, 4).Value
Else
Fax = "Fax: No Fax Held"
End If
If IsNumeric(c.Value) Then
what_found = c.Offset(0, 1).Value
Else
what_found = c.Value
End If
'Show Contacts
ThisWorkbook.Worksheets("Data").Range("I2").Value = "Hello," & vbNewLine & "Have you tried to contact " & what_found & " about your issue?" & vbNewLine _
& Contact & Email & Phone & Fax
'ThisWorkbook.Worksheets(1).Shapes("Suggest").TextFrame.AutoSize = True
CenterShape ThisWorkbook.Worksheets(1).Shapes("Suggest")
RightShape ThisWorkbook.Worksheets(1).Shapes("Close")
ThisWorkbook.Worksheets(1).Shapes("Suggest").Visible = True
'Show Close Button
'ThisWorkbook.Worksheets(1).Shapes("Close").OnAction = "HideShape"
ThisWorkbook.Worksheets(1).Shapes("Close").Visible = True
'Protect sheet
'ActiveSheet.Protect Password:="SecretPassword", userinterfaceonly:=True
'ActiveSheet.Shapes("Suggest").Locked = True
End If
End With
End Sub
Public Sub CenterShape(o As Shape)
o.Left = ActiveWindow.VisibleRange(1).Left + (ActiveWindow.VisibleRange.Width / 2 - o.Width / 2)
o.Top = ActiveWindow.VisibleRange(1).Top + (ActiveWindow.VisibleRange.Height / 2 - o.Height / 2)
End Sub
Public Sub RightShape(o As Shape)
o.Left = ThisWorkbook.Worksheets(1).Shapes("Suggest").Left + (ThisWorkbook.Worksheets(1).Shapes("Suggest").Width / 1.01 - o.Width / 1.01)
o.Top = ThisWorkbook.Worksheets(1).Shapes("Suggest").Top + (ThisWorkbook.Worksheets(1).Shapes("Suggest").Height / 30 - o.Height / 30)
End Sub
You need not use selection. it check range only in selection.
if you know the range to be checked as With Worksheets("Contacts").Range("A2:E10000") then
Change the code as shown below
Set c = .Find(What:=Worksheets(1).Range("N3").Value, After:=.Range("A1"), LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
As Jeeped suggested, remove the Selection object for your range and instead use the range you defined at the “With” statement. Also, I changed the “After” argument to be a reference to the first cell in the range defined at the “With” statement; and, the “LookIn” argument was changed to be xlValues.
...
With Worksheets("Contacts").Range("A2:E10000")
Set c =.Find(What:=Worksheets(1).Range("N3").Value, After:=.Cells(1), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
...
This search looks at all the columns from A to E. The Find method could return a reference to a cell in a column other than column A if it found a matching value. This may be producing some unusual results for the rest of your code because you are using offset to get the other contact numbers. You may want to consider defining constants for each column and use those with a call to the Cells property using the a constant for the "Column" parameter.
For Example:
Declare your constants for the columns at the beginning of Phonebook().
Const lCOLUMN_EMAIL as long = 3
Use the Cells property for returning values as with the email example below:
If .Cells(c.Row, lCOLUMN_EMAIL).Value <> "" Then
Email = "Email: " & .Cells(c.Row, lCOLUMN_EMAIL).Value & Chr(10)
Else
Email = "Email: No Email Held" & Chr(10)
End If
Limit your search to the A column or which ever column contains the values. (Ignore this part if you want to search all the cells in all the columns.)
Set c = .Columns(1).Find(What:=Worksheets(1).Range("N3").Value, After:=.Cells(1), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False
Related
I am still new to VBA. I am working on an excel sheet, and I want to look up data using InputBox and get results from the spreadsheet that I have. Here's an example:
Sheet Display:
Names
Occupation
IDs
James
Engineer
e2134
Linda
Programmer
f2123
Input Box:
"Enter IDs:"
e2134
Result:
Message Box will show:
IDs: e2134
Name: James
Occupation: Engineer
I did some code, but I can't access it from home (it's on my work computer).
I want to know what code can I use so VBA can collect the data on the same row (Name and Occupation) and display it in a MessageBox. Or there could be a better way to do that.
You may try below code-
Sub SearchNreturn()
Dim Rng As Range
Dim strID As String
strID = InputBox("Enter ID")
Set Rng = Sheets("Sheet1").Range("C:C").Find(What:=strID, _
After:=Cells(1, 3), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
MsgBox "ID: " & Rng.Value & vbNewLine & _
"Occupation: " & Rng.Offset(0, -1) & vbNewLine & _
"Name: " & Rng.Offset(0, -2)
Else
MsgBox "Nothing found."
End If
End Sub
In my UserForm, I have two Text Box. I want to be able to FIND by either Text Box, but use only one or the other. If both are empty I want a MSGBOX telling user to enter information. I can make my code do either/or text box entry but not two textbox where the user skips TextBox1 or does not entry anything.
Here is my code.....
Private Sub OkayCommandButton_Click()
Worksheets("Parts List").Select
Application.ScreenUpdating = False
Range("A2").Select
PN = PartNumber.Value
KN = KanbanNumber.Value
If PartNumber = vbNullString Then
MsgBox "Please enter a Part Number"
PartNumber.SetFocus
Else
Cells.find(What:=PN, After:=Range("A2"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
End If
If Kanban = vbNullString Then
MsgBox "Please enter a Kanban Number"
PartNumber.SetFocus
Else
Cells.find(What:=KN, After:=Range("A1"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
End If
PartInformation.Caption = _
"Part Number" & vbTab & ActiveCell & vbCrLf & _
"Kanban" & vbTab & vbTab & ActiveCell.Offset(0, 45) & vbCrLf & _
"Part Name" & vbTab & ActiveCell.Offset(0, 1) & vbCrLf & _
"Supplier" & vbTab & vbTab & ActiveCell.Offset(0, 2) & vbCrLf & _
"Next Process" & vbTab & ActiveCell.Offset(0, 3) & vbCrLf & _
"Qty in Tote" & vbTab & ActiveCell.Offset(0, 44) & vbCrLf & _
"PC Location" & vbTab & ActiveCell.Offset(0, 46)
PartInformation1.Caption = "Line " & ActiveCell.Offset(0, -1)
End Sub
You could check first if both TextBox-Elements are empty and then give a message to the user. If that check fails either one or both Text-Box-Elements contain text. You have a conflict there, since you only want to use one TextBox-Element for the search if both textboxes contain a search string. In this case you have to give one of the textboxes priority (the first one you check then wins):
This is only a snippet of your text:
PN = PartNumber.Value
KN = KanbanNumber.Value
If ((PartNumber = vbNullString) And (KanbanNumber = vbNullstring)) Then
' Both textboxes are empty, message box opened and focus to part number
MsgBox "Please enter a Part Number or Kanban Number"
PartNumber.SetFocus
Else
' One or more textboxes contain a search string
If Not (PartNumber = vbNullString) Then
'Part number is given, run search
Cells.find(What:=PN, After:=Range("A2"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Else
' Part Number is not given
' Since we checked that at least one textbox contains text
' the Kanban Number must be set if Part Number has not been set
Cells.find(What:=KN, After:=Range("A1"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
End If
End If
It has just dawned on me What if the user puts in something not in the database (excel spreadsheet)? I have poured over all these posted fixes and none seem to meet my needs. Would someone look over my code Please.
Private Sub OkayCommandButton_Click()
Worksheets("Parts List").Select
Application.ScreenUpdating = False
Range("A2").Select
PN = PartNumber.Value
KN = KanbanNumber.Value
If ((PartNumber = vbNullString) And (KanbanNumber = vbNullString)) Then
' Both textboxes are empty, message box opened and focus to part number
MsgBox "Please enter a Part Number or Kanban Number"
PartNumber.SetFocus
Else
' One or more textboxes contain a search string
If Not (PartNumber = vbNullString) Then
'Part number is given, run search
Cells.find(What:=PN, After:=Range("A2"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Else
' Part Number is not given
' Since we checked that at least one textbox contains text
' the Kanban Number must be set if Part Number has not been set
Cells.find(What:=KN, After:=Range("A1"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
End If
End If
PartInformation.Caption = _
"Part Number" & vbTab & ActiveCell & vbCrLf & _
"Kanban" & vbTab & vbTab & ActiveCell.Offset(0, 45) & vbCrLf & _
"Part Name" & vbTab & ActiveCell.Offset(0, 1) & vbCrLf & _
"Supplier" & vbTab & vbTab & ActiveCell.Offset(0, 2) & vbCrLf & _
"Next Process" & vbTab & ActiveCell.Offset(0, 3) & vbCrLf & _
"Qty in Tote" & vbTab & ActiveCell.Offset(0, 44) & vbCrLf & _
"PC Location" & vbTab & ActiveCell.Offset(0, 46)
PartInformation1.Caption = "Line " & ActiveCell.Offset(0, -1)
End Sub
The specification for Range.Find is that it returns Nothing if the search term doesn't exist in the searched area. Nothing is a special value which you can test for.
To deal with search terms which don't exist, try adding Dim rFindResult As Range immediately after the Private Sub... line and then alter the Cells.Find statements like this:
Set rFindResult = Cells.Find(What:=KN, After:=Range("A1"), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If (rFindResult Is Nothing) Then
` display MesgBox, reset focus appropriately, exit sub
Else
rFindResult.Activate
End If
Siddarth Rout's point about specifying which sheet to use rather than implicitly relying on the active sheet is well worth heeding. Also, in the case where neither part number nor kanban number is specified, there should probably be an Exit Sub after setting the focus to part number
I cannot find or create VBA code to allow pasting copied text from one cell in another sheet(sheet2) into a previously created comment in another sheet(sheet1).
Here is the code I have successfully compiled thus far, and I am stuck on how to get the text found into the comment box.
Sub For_Reals()
'Add Comment
Sheets("Sheet1").Range("F2").AddComment
Range("F2").Comment.Visible = False
'Find Value in Sheet2 based on Value from Sheet1
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Sheet1").Range("F2").Value
If Trim(FindString) <> "" Then
With Sheets("Sheet2").Range("C:C")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True
Else
MsgBox "Nothing found"
End If
End With
End If
'Copy Value 4 cells to the right of found Value
Selection.Offset(0, 4).Copy
'Need Code to paste copied value in previously created comment
End Sub
Rather than copy and paste the cell value into the comment, you create the text at the same time as creating the comment box. If a comment box already exists an error is raised - so remove any comment boxes in that cell beforehand.
The VBA help gives this as an example:
Worksheets(1).Range("E5").AddComment "Current Sales"
So with this in mind, this code will do the trick:
Sub For_Reals()
'Find Value in Sheet2 based on Value from Sheet1
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Sheet1").Range("F2").Value
If Trim(FindString) <> "" Then
With Sheets("Sheet2").Range("C:C")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
'Remove any existing comments, create comment and add text.
If Not Rng Is Nothing Then
Sheets("Sheet1").Range("F2").ClearComments
Sheets("Sheet1").Range("F2").AddComment Rng.Offset(0, 4).Value
Range("F2").Comment.Visible = True
Else
MsgBox "Nothing found"
End If
End With
End If
End Sub
Final code I ended up with is below. Added a loop to run through the column, and added a second reference to pull both the definition and description into the comment. Thank you Darren Bartrup-Cook for helping me out when I was stuck!
Sub Add_Comment_As_Def_Desc_Reference()
'Posted by Jeff Barrett 2015-04-10
Dim FindString1 As String
Dim Rng1 As Range
Dim sCommentText1 As String
Dim sCommentText2 As String
Dim str1 As String
Dim str2 As String
Dim cmmt As String
Dim i As Integer
str1 = "Definition: "
str2 = "Description: "
'Loop Code, must specify range for i based on # of FieldAlias
Sheets("Fields").Select
Range("F4").Select
For i = 4 To 59
'Find Definition & Description in NASDefs based on Value from FieldAlias
FindString1 = ActiveCell.Value
If Trim(FindString1) <> "" Then
With Sheets("NASDefs").Range("C:C")
Set Rng1 = .Find(What:=FindString1, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
End With
End If
'Remove any existing comments, create comment and add text in FieldAlias
If Not Rng1 Is Nothing Then
ActiveCell.ClearComments
sCommentText1 = Rng1.Offset(0, 4).Value
sCommentText2 = Rng1.Offset(0, 5).Value
ActiveCell.AddComment.Text Text:=str1 & Chr(10) & Chr(10) & sCommentText1 & Chr(10) & Chr(10) & str2 & Chr(10) & Chr(10) & sCommentText2
ActiveCell.Comment.Visible = False
ActiveCell.Comment.Shape.AutoShapeType = msoShapeRoundedRectangle
'Format lines of text
With ActiveCell.Comment.Shape.TextFrame
.Characters.Font.ColorIndex = 5
End With
Else
MsgBox "Nothing found"
End If
'End Loop
ActiveCell.Offset(RowOffset:=1, ColumnOffset:=0).Select
Next i
'Resize Comment to fit text
'posted by Dana DeLouis 2000-09-16
Dim MyComments As Comment
Dim lArea As Long
For Each MyComments In ActiveSheet.Comments
With MyComments
.Shape.TextFrame.AutoSize = True
If .Shape.Width > 300 Then
lArea = .Shape.Width * .Shape.Height
.Shape.Width = 300
' An adjustment factor of 1.1 seems to work ok.
.Shape.Height = (lArea / 200) * 0.6
End If
End With
Next ' comment
End Sub
I would like to find a match of a date in a column and would like to know the simplest way to do in VBA.
This is what I have tried:
date1 = Sheets("Part2").Cells(i, 1).Value
Dim matchRow As Integer
matchRow = 3
While Sheets("1.A").Cells(matchRow,1).Value != date1 Then
matchRow = matchRow + 1
End While
I am getting a date from another sheet and would like to match it with another sheet.
Need some guidance on how to simplify this.
The following should work - if you set the value for 'i' to get the date to search for...
date1 = Sheets("Part2").Cells(i, 1).value
Sheets("1.A").Select
Cells.Find(What:=date1, After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Debug.Print ActiveCell & vbTab & ActiveCell.Address
If ActiveCell = date1 Then
MsgBox "Found in: " & ActiveCell.Address
Else
MsgBox "Not found"
End If