I'm very new to VBA and only have a basic level of knowledge.
I have been trying to create a macro to cross-reference data on one sheet against multiple other sheets within the same work book. If a record is found I would like a msgbox to appear to alert the user of the location of the data.
After many hours searching the internet and piecing together bits of code this is what I have
Sub search()
Dim ws As Worksheet, found As Range
Dim TextToFind(1 To 20) As String
Dim iText As Long
TextToFind(1) = "Jade Smith"
TextToFind(2) = "Bob Collins"
TextToFind(3) = "Jemima Smythe"
For Each ws In ThisWorkbook.Worksheets
With ws
If .Name <> "Blacklisted Candidates" Then 'Do not search blacklist candidates!
iText = 1
Do While iText <= UBound(TextToFind)
If TextToFind(iText) <> "" Then 'Do not search blank strings!
Set found = .UsedRange.Find(what:=TextToFind(iText), LookIn:=xlformulas, LookAt:=xlPart, MatchCase:=False)
If Not found Is Nothing Then
MsgBox "Proxy Candidate Found at " & found.Address
Else
MsgBox "No Proxy Candidates Found ", vbOKOnly, "Success!"
End If
iText = iText + 1
End If
Loop
End If
End With
Next ws
End Sub
This code however doesn't find the values from other sheets.
when testing this I just get the msgbox when no data has been found even though there is test data there.
I have a workbook of approx 9 sheets (ever growing) and I want to search the first 9 columns of each work book for the specified data which as you can see I have manually input into the macro but when running the macro I get no results returned even though there is data to find.
You are trying to use the binary operator And on two strings. You probably meant to use & instead to concatenate strings.
Documentation :
And
&
(The docs are for VB.Net, but they work the same in both languages)
So to fix it, replace
MsgBox ("Proxy Candidate Found at " And rngX.Address)
By
MsgBox ("Proxy Candidate Found at " & rngX.Address)
edited to account for searching in cell whose content derives from a formula
to both summarize all what has been already pointed out in comments and litelite answer and add some 0.02 cents, here a working code
Option Explicit
Sub search()
Dim ws As Worksheet, found As Range
Dim TextToFind(1 To 20) As String
Dim iText As Long
TextToFind(1) = "xxxx"
TextToFind(2) = "xxxx"
TextToFind(3) = "xxxxx"
For Each ws In ThisWorkbook.Worksheets
With ws
If .name <> "Blacklisted Candidates" Then 'Do not search blacklist candidates!
iText = 1
Do While iText <= UBound(TextToFind)
If TextToFind(iText) <> "" Then 'Do not search blank strings!
Set found = .UsedRange.Find(what:=TextToFind(iText), LookIn:=xlFormulas, LookAt:=xlPart, MatchCase:=False)
If Not found Is Nothing Then
MsgBox "Proxy Candidate Found at " & found.Address
Else
MsgBox "No Proxy Candidates Found ", vbOKOnly, "Success!"
End If
iText = iText + 1
End If
Loop
End If
End With
Next ws
End Sub
Related
I have a workbook that is essentially an automated test, marking and feedback tool for end of topic tests for students. On the '701Test' sheetThey input their teaching group via a drop down list and the select their from subsequent list. They answer the multiple choice questions and press a button when finished. The button takes them to a 'results' page which gives their marks for each question, give feedback for incorrect answers and gives a total score. They then hit the finish button which generates a PDF copy of the mark sheet in their my documents folder and then emails a copy to themselves and the Schools email account. At this point I also wanted to post the final score to the students record on a central registry using a loop through the student list to find the name and offset to post the Score value from the 'Results' page and finally return to the test page. This last bit I wrote the code for in a module and it executes perfectly, but when added to the main code and run from the button the loop part fails to execute but the return to the test page does work, but no error is recorded for the loop failure.
Here is the 'Results' page code in full the 'With Central reg' bit at the bottom is the problem, any help is greatly appreciated.
Private Sub CommandButton1_Click()
Dim IsCreated As Boolean
Dim PdfFile As String, Title As String
Dim OutlApp As Object
Dim cell As Range
Dim Students As Range
Title = Range("D1").Value
sname = Range("B2").Value
PdfFile = CreateObject("WScript.Shell").SpecialFolders("MyDocuments") & "\" & sname & Title & ".pdf"
With ActiveSheet
.ExportAsFixedFormat Type:=xlTypePDF, Filename:=PdfFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End With
On Error Resume Next
Set OutlApp = GetObject(, "Outlook.Application")
If Err Then
Set OutlApp = CreateObject("Outlook.Application")
IsCreated = True
End If
OutlApp.Visible = True
On Error GoTo 0
With OutlApp.CreateItem(0)
.Subject = Title
.to = Range("B2").Value ' <-- Put email of the recipient here"
.CC = "" ' <-- Put email of 'copy to' recipient here
.Body = "Hi," & vbLf & vbLf _
& "Yr 7 701 EOT test attached in PDF format." & vbLf & vbLf _
& "Regards," & vbLf _
& "KDS ICT Dept" & vbLf & vbLf
.Attachments.Add PdfFile
Application.Visible = True
.Display
End With
If IsCreated Then OutlApp.Quit
Set OutlApp = Nothing
With CentralReg
For Each cell In Range("A2:A250")
If cell = Range("Results!B2").Value Then
cell.Offset(0, 4).Activate
ActiveCell.Value = Range("Results!B27").Value
End If
Next
End With
End Sub
I believe you are trying to refer to CentralReg which is a worksheet, which means you should qualify it as such.
Also, you should not dim variables that are similar to defined objects/properties in VBE. Try MyCell instead of cell (good practice, not required).
I am assuming you want to see if the value on sheet CentralReg in Column A is equal to sheet Result B2. If this condition is met, your MyCell will take on the value equal sheet Result B27
Dim MyCell As Range
Dim Result, NewValue as Variant
Result = ThisWorkbook.Sheets("Result").Range("B2")
NewValue = ThisWorkbook.Sheets("Result").Range("B27")
With ThisWorkbook.Sheets("CentralReg")
For Each MyCell In .Range("A2:A250")
If MyCell = Result Then MyCell.Offset(, 4) = NewValue
Next MyCell
End With
That with statement is useless as nothing actually uses it within the construct.
Delete with CentralReg and End with and it will work.
alternatively if CentralReg IS something like a sheet then you need to precede your code with a . so this: Range("A2:A250") becomes this: .Range("A2:A250") and so on, the . tells the code that it is related to whatever your with construct surrounds
I wrote a VBA module within an excel document I am working on. I got everything working on my laptop and finally published it to my team to begin a wave of testing.
Unfortunately, a lot of them are met with the following error:
Compile error in hidden module: pushEmail. This error commonly occurs when code is incompatible with the version, platform, or architecture of this application.
At first, I assumed that people were not using the same version of Excel as I was (Excel 2016), however, it turns out that they all were. Other solutions I've attempted are:
Checking the references to ensure that all were included on other user's computers. They were.
Check the add-ins I was using on excel. Besides the default ones, I had none.
Ensure I was using 32/64bit compatible code (as per a recommended solution I found through google). Me and my team all have x64 computers.
I'm not sure what else to try and I have been through the first 30 pages of Google to try and find a solution, to no avail. Could someone suggest a solution that I could attempt?
Thank you in advance.
UPDATE
Here is the code in question:
Sub AcceptPush()
Dim track As Excel.Workbook
Dim push As Excel.Workbook
Dim trackFC As Excel.Workbook
Dim trackWks As Excel.Worksheet
Dim pushWks As Excel.Worksheet
Dim FCWks As Excel.Worksheet
Dim pName As String
Dim TLPass As Variant
Dim lastrow As Long
Dim rngFoundCell As Range
Set rng = Nothing
Dim MyCell As Range
Set push = Workbooks("Push Alert - Software.xlsm")
Set pushWks = push.Worksheets("Push")
Set rngFoundCell = pushWks.Range("R11:R53").Find(What:="y")
pName = pushWks.Range("D2").Value
TLPass = InputBox("Enter the TL Password")
Select Case TLPass
Case "password"
MsgBox "Password correct"
If rngFoundCell Is Nothing Then
MsgBox "You did not select a push to accept."
Else
Set track = Workbooks.Open(ThisWorkbook.Path & "\Account Pushing Tracker - Software.xlsm")
Set trackWks = track.Worksheets("Accounts")
Set trackFC = Workbooks.Open(ThisWorkbook.Path & "\Account Pushing Tracker - Team Tax.xlsm")
Set FCWks = trackFC.Worksheets("Accounts")
pushWks.Range("PushData[#All]").AdvancedFilter _
Action:=xlFilterInPlace, _
CriteriaRange:=push.Worksheets("Filter Criteria").Range("B6:Q7")
pushWks.Range("R:S").EntireColumn.Hidden = True
pushWks.Range("PushData").Copy
trackWks.Range("B" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlValues
pushWks.Range("PushData").Copy
FCWks.Range("B" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlValues
pushWks.Range("R:S").EntireColumn.Hidden = False
pushWks.Range("PushData").ClearContents
pushWks.ShowAllData
Range("A1").Select
Application.CutCopyMode = True
track.Close SaveChanges:=True
trackFC.Close SaveChanges:=True
End If
Case Else
MsgBox "INCORRECT! Your attempt has been recorded"
ActiveWorkbook.Worksheets("Log").Unprotect "123"
ActiveWorkbook.Worksheets("Log").Range("A" & Rows.Count).End(xlUp).Offset(1).Value = Application.UserName
ActiveWorkbook.Worksheets("Log").Range("B" & Rows.Count).End(xlUp).Offset(1).Value = Format(Now(), "dd/mm/yyyy hh:mm:ss")
ActiveWorkbook.Worksheets("Log").Protect "123"
End Select
End Sub
When I try to compile your code, it shows you haven't declared the Rng variable:
Set Rng = Nothing
this can occure if 2 Installation of Word/Excel (64 /32 ) or rest of them are on computer.
The apdada....\Excel\STARTUP must be empty too
Maybe try to deinstall all Excel entirely and after new installation try again
The series of commands seems to result in Runtime Error: 1004 I would like to know what the cause of this error is.
If I do not have the Activesheet.Hyperlinks.add line the cell values get set correctly, just missing the hyperlink... which would make me think I've lost the xCell reference but I've placed debug statements just before the hyperlink.add and it seems to be accessible.
Example URL: http://www.walmart.com/ip/Transformers-Robots-in-Disguise-3-Step-Changers-Optimus-Prime-Figure/185220368
For Each xCell In Selection
Url = xCell.Value
If Url = "" Then
'Do Nothing
ElseIf IsEmpty(xCell) = True Then
'Do Nothing
ElseIf IsEmpty(Url) = False Then
splitArr = Split(Url, "/")
sku = splitArr(UBound(splitArr))
xCell.Value = "https://www.brickseek.com/walmart-inventory-checker?sku=" & sku
'Error happens on next command
ActiveSheet.Hyperlinks.Add Anchor:=xCell, Address:=xCell.Formula
End If
Next xCell
Don't both with .ValueDon't use .Formula:
Sub demo()
Dim s As String, xCell As Range
s = "http://www.walmart.com"
Set xCell = Range("B9")
ActiveSheet.Hyperlinks.Add Anchor:=xCell, Address:=s, TextToDisplay:=s
End Sub
is a typical working example.
There is always another possibilty, that your sheet may be locked and you have to grant permission to do so when locking the sheet.
I know this is not the solution for the problem described here, but the non-deterministic error messages provided by Microsoft VBA is the same. I came here looking for the solution of my problem, an others might bump in this and find my comment relevant.
I am creating a table in my spreadsheet that contains categories, questions and answers for a quiz.
The user is presented with a form, allowing them to navigate around the workbook easily, this also includes a textbox option, allowing them to search for a phrase if they are unsure what category the question/answer may fall into.
I have generated a vlook up to pull from the table of categories/questions and answers to the user on a different worksheet.
I have also generated a count, so I am able to identify how many times this work appears across the quiz table.
My problem is I am struggling to develop a loop so that if the key phrase is found 6 times for example, i want 6 questions and answers to be listed to the user. Currently it is only pulling the final time it is found.
My current code includes the following:
Private Sub CommandButton1_Click()
If Len(search_text) = 0 Then
MsgBox "Please enter a key word to search for!", vbCritical
End If
Dim wordCount As Integer
wordCount = Application.WorksheetFunction.CountIf(Sheet1.Range("A2:c600"), "*" & search_text.Value & "*")
'Else: wordCount = WorksheetFunction.CountIf(Sheet1.Range("A2:c600"), search_text.Value)
If wordCount = 0 Then
MsgBox "No match found"
Else
Sheet2.Range("a7").Value = WorksheetFunction.VLookup("*" & search_text.Value & "*", Sheet1.Range("A2:c600"), 3, False)
Sheet2.Range("b7") = wordCount
End If
End Sub
Any advice on implementing a loop and to allow the question/answer to be printed one after another would be very much appreciated.
I have read many other question pages about this and none seem to match what I am trying to do.
Many thanks in advance
I use a combination of Find and FindNext to search through a range of cells for the term entered in the search_text input field. I added comments to my code to better help you understand what exactly is going on.
I don't know exactly what you need to do with the results when you find them, for now I just display a message box showing the match. We can work on what to actually do with the results if you want to clarify in the comments what exactly you want.
This code assumes you have a worksheet named Results
Private Sub CommandButton1_Click()
Dim rngResult As Range
Dim strFirstAddress As String
Dim i As Long
If Len(search_text.Text) = 0 Then
MsgBox "Please enter a key word to search for!", _
vbCritical
'Stop code exeuction if no search
'term is entered
Exit Sub
End If
'Clear the previous results range
Sheets("Results").Range("A2:C600").ClearContents
'Set i to row 2 of the results worksheet
i = 2
'Look in range A2:C600 of Sheet1
With Sheet1.Range("A2:C600")
'Perform the initial find
Set rngResult = .Find(What:=search_text.Text, LookAt:=xlPart)
'Check to ensure that the term is found
If Not rngResult Is Nothing Then
'Grab the cell address of the first match
'This will help to avoid an infinite loop
strFirstAddress = rngResult.Address
'Continue Searching
Do
'Display the output to you
'MsgBox "Matched '" & search_text.Text & "' to " & rngResult.Value & " in cell " & rngResult.Address
'Put the result on the results page
Sheets("Results").Range("A" & i & ":C" & i).Value = Range("A" & rngResult.Row & ":C" & rngResult.Row).Value
i = i + 1
'Move on to the next result
Set rngResult = .FindNext(rngResult)
'Break out of the loop when we return to the starting point of the search
Loop While Not rngResult Is Nothing And rngResult.Address <> strFirstAddress
End If
End With
'Clean up variables
Set rngResult = Nothing
End Sub
I'm at a loss when trying to figure out where this code is tripping up. I am looking to rename the activesheet by using a concat of two ranges on the activesheet and some static text. When only one worksheet is in the workbook, the code works great. As soon as a second worksheet is added, I get a Runtime Error 1004. I'll highlight the line of code where it is breaking. This code currently resides in a normal module.
Option Explicit
Sub updateName()
Dim fNumber
Dim pCheckNumber
Dim asName As String
Dim tempASName As String
Dim worksheetName As Object
If ActiveSheet.Name = "Launch Page" Then Exit Sub
fNumber = ActiveSheet.Range("FlightNumber").Value
pCheckNumber = ActiveSheet.Range("PerformanceCheckNumber").Value
If fNumber <> "" And pCheckNumber <> "" Then
tempASName = "Flight " & fNumber & " | Run " & pCheckNumber & " (0.0%)"
asName = tempASName
MsgBox ActiveSheet.Name & vbCr & asName
ActiveSheet.Name = asName
worksheetName.Caption = asName
Else
Exit Sub
End If
End Sub
I'm in the process of adding error checking to ensure that I don't have duplicate sheet names. However, due to the nature of the field names, this will never occur.
I appreciate all of the insights!
The error you are reporting is, most likely, provoked because of trying to rename a Worksheet by using a name already in use. Here you have a small code to avoid this kind of situations:
Dim newName As String: newName = "sheet1"
Dim addition As String: addition = "_2"
Do While (Not sheetNameFree(newName))
newName = newName & addition
Loop
Where sheetNameFree is defined by:
Function sheetNameFree(curName As String) As Boolean
sheetNameFree = True
For Each Sheet In ActiveWorkbook.Sheets
If (LCase(Sheet.Name) = LCase(curName)) Then
sheetNameFree = False
Exit Function
End If
Next Sheet
End Function
You can adapt this code to your specific needs (for example, by converting addition into a number which grows after each wrong name).
In your code I see one other problem (although it shouldn't be triggering a 1004 error): you are accessing the property Caption from an non-instantiated object (worksheetName), whose exact functionality is not too clear. Just delete this line.
NOTE: good point from KazJaw, you might be using an illegal character. If fNumber and pCheckNumber are numbers or letters, it would be OK.
NOTE2: if with worksheetName you want to refer to an ActiveX Label in your workSheet, better do: ActiveSheet.Label1.Caption (where Label1 is the name of the Label). You cannot define worksheetName as a Label, because it is not a "conventional Label".