I have got through every compile error post on the site and I know it has something to do with the .Value. I have tried setting it to = Now and adding (Now, term.Value) similar to what others have done. Does anyone see why I'm getting the "Compile error: Method or data member not found"
Please let me know if you see anything wrong specifically with the words() = Split(term.Value) code:
Sub FindSimilar()
Dim phrases As Range, phrase As Range
Dim terms As Range, term As Range
Dim matches As String
Dim words() As String
'ensure this has the correct sheet names for your workbook
Set phrases = ThisWorkbook.Worksheets("Export").Range("B2:B4345")
Set terms = ThisWorkbook.Worksheets("Topics").Range("D1847:D4847")
For Each term In terms
matches = ""
words() = Split(term.Value)
For i = 0 To UBound(words, 1)
If Len(words(i)) > 2 Then
Select Case words(i)
Case "business", "example", "string"
Case Else
For Each phrase In phrases
If InStr(1, phrase.Value, words(i)) Then
matches = matches & phrase & "/"
End If
Next phrase
End Select
End If
Next i
If matches <> vbNullString Then
term.Offset(0, 6).Value = Left(matches, Len(matches) - 1)
Else
term.Offset(0, 6).Value = "No match"
End If
Next term
End Sub
Also, as a note, this code was working well and it just stopped working so I'm assuming it's just an update or some small text. I'm using Excel for Mac.
Related
I am writing a VBA code to go through a specified range or ranges, look for a keyword provided by the user at run-time, and grab the value in the cell offset from the cell with the keyword by an amount also provided by the user. For instance, if you wanted to look through A1:B10 for the word "Apple" and then grab the value in the cell to the right of every instance of "Apple", it can do that. Two weird things have been occurring for me. First and not so weird, when I run it and click the cancel button on the userform that only contains the single line "Unload Me", it throws an error saying it expected and End Sub statement, but it has one. I don't know why it is doing that. Weird thing number 2. Whenever I click and move the cursor to the end of the file after the Cancel_Click() sub, my excel crashes and closes. Every. Single. Time. And it is weird that it does that just from me clicking. It also sometimes happens when I click around the Cancel_Click() sub or hit enter around there too. Just simply from clicking. I don't get it. Any ideas? Code contained in the userform is below. Fyi, the user can input ranges like "A1:A10,E1:E10" separated by commas for multiple ranges. I don't think it is important for this question, but I thought I would add that since i don't know how to add the userform here, if you even can.
Private Sub Accept_Click()
'Searches for string input into the KeywordBox
'Grabs contents of the cell defined by the OffsetBox
'The range it searches through is defined by the RangeBox
Dim rawRange As String: rawRange = Me.RangeBox.Text
Dim rawOffset As String: rawOffset = Me.OffsetBox.Text
Dim Keyword As String: Keyword = Me.KeywordBox.Text
Dim numOfRanges As Integer: numOfRanges = 1
Dim Ranges() As Range
Dim commaLoc As Integer: commaLoc = -1
Dim tempRange As String: tempRange = rawRange
Dim offset As Integer
Dim values() As Double
Dim valCount As Integer: valCount = 0
'--------------------------------------------------------
'Set ranges
For i = 1 To Len(rawRange)
If (Mid(rawRange, i, 1) = ",") Then
numOfRanges = numOfRanges + 1
End If
Next
ReDim Ranges(numOfRanges) As Range
If (Not numOfRanges = 1) Then
For i = 1 To numOfRanges - 1
commaLoc = InStr(1, tempRange, ",")
Set Ranges(i) = Range(Left(tempRange, commaLoc - 1))
tempRange = Right(tempRange, Len(tempRange) - commaLoc)
Next
End If
Set Ranges(numOfRanges) = Range(tempRange)
'---------------------------------------------------------
'Set offset
If (IsNumeric(rawOffset)) Then
offset = CInt(rawOffset)
Else:
MsgBox ("Offset was not input as a number")
Exit Sub
End If
'----------------------------------------------------------
'Searches for keyword
For i = 1 To numOfRanges
For Each cell In Ranges(i)
If (cell.Value = Keyword) Then
valCount = valCount + 1
End If
Next
Next
ReDim values(valCount) As Double
valCount = 0
For i = 1 To numOfRanges
For Each cell In Ranges(i)
If (cell.Value = Keyword) Then
valCount = valCount + 1
values(valCount) = cell.offset(0, offset).Value
End If
Next
Next
For i = 1 To valCount
Range("I" & i).Value = values(i)
Next
Unload Me
End Sub
I've had similar, weird things happen to me. A good thing to try is to force the VBA project to reset, then save, exit, and restart Excel.
To force a project reset, add an Enum to the general section of one of your code modules. It doesn't matter what the enum is...make it something simple, like
Enum stoplight
Red
Yellow
Green
End Enum
As you do that, you'll get a message saying that it will reset your project. That's fine; let that happen. Then save your Excel workbook, exit excel completely, start it up again, reload your workbook, go into the VBA Editor, and delete the enum you added. Then recompile and see if things work better for you.
You put an "Exit Sub" in the set offset, this is probably causing your problem.
I was able to fix the issue by making a new workbook and copying everything over. It worked fine. I think the original was corrupted somehow. For those having the same issue, I think Rich Holton's answer would be worth a try in case you have more than just a few things to copy. Thanks everyone for you time and input on this!
I'm trying to write a program in VBA for excel that will search through a column of "names", and if that name has the case-sensitive string "CAN" within it, then the column 6 columns over will be added to a total (canadaTotal). This is what I have so far... The problem is within the instr/isnumeric portion. I'm sure I'm using one of them incorrectly.. and if anybody could offer an alternative solution, or a quick fix, I would appreciate it.
(hint... I'm not sure if i can use my "search" variable as the second input of the instr function...)
Private Sub CommandButton5_Click()
Dim i As Integer
Dim col As Integer
Dim canadaTotal As Integer
Dim search As String
Dim canadaCheck As Long
i = 1
col = 4
canadaTotal = 0
Worksheets("sheet1").Activate
While Not Worksheets("Sheet1").Cells(i, col).Value = ""
search = Cells(i, col).Value
If IsNumeric(InStr(0, search, "CAN")) Then
canadaTotal = canadaTotal + Cells(i, col).Offset(0, 6).Value
End If
i = i + 1
Wend
MsgBox (canadaTotal)
End Sub
The problem you are having is that the Instr function starts with position 1, not position 0.
Also, Instr returns 0 if the string is not found, not a non-numeric value, so your test will always be true.
Additionally, the default for Instr is that it will not search case sensitive. In order to search case sensitive, you need to use the last "compare" parameter and set it to vbBinaryCompare.
Change this to:
If Instr(1, search, "CAN", vbBinaryCompare) <> 0 Then
and it should work.
Sub test1()
Dim Str As String
Dim Search As String
Dim Status As String
Str = Cells(2, 5).Value
Search = FDSA!Cells(2, 5).Value
Status = FDSA!Cells(2, 10).Value
If InStr(Search, Str) = True Then
Status = "ok"
Else
End If
End Sub
I will be building up from this with loops. I want to check if what is in Cells(2,5) is contained in FDSA!Cells(2,5). If it is true then I would like to mark FDSA!Cells(2,10) as ok. I am getting an object required message. This is what I could come up with after looking at examples and tutorials. Let me know if you have questions
Only second time working on VBA.
Thanks in advance, Alexis M.
Your syntax for referencing the worksheet is incorrect. That is probably throwing the error. You need to call to Worksheets("FDSA") and not use the FDSA! call like you have.
Also, you will have to set the cell value equal to Status for this to work. Just changing Status will not write it back into the workbook.
Also InStr returns the location of the match. If you want to know if there was a match, you need to check that the return is >0. This code should run and hopefully is closer to correct than your current code.
Sub test1()
Dim Str As String
Dim Search As String
Str = Cells(2, 5).Value
Search = Worksheets("FDSA").Cells(2, 5).Value
If InStr(Search, Str) > 0 Then
Worksheets("FDSA").Cells(2, 10).Value = "ok"
End If
End Sub
It's my first time writing a code that actually attempts to do something and I'm having some trouble with writing an error handler. The code attempts to match 'tosearch' to the range I1:I10. If it finds a match and the cell is blank is asks for user input.
Obviously there is a problem in matching with loops as the loop will break at the slightest sniff of a mismatch. I attempted to solve this with the 'If iserror(etc.)' but I still get mismatch error type 13 and the debugger points me to this line
If IsError(myvalue = Application.Match(tosearch, Range("i1:i10"), 0)) Then
Please ignore the horrendous, sprawling mess beneath. It works (just) and while it doesn't have any practical use yet, i hope to use it to quickly identify matches between arrays but also have some control over whether the 'correct' match is displaying the right information.
If anyone has any answers your help would be hugely appreciated.
Dim myvalue As String
Dim myrng As Long
Dim tosearch As String
Dim myrnglimit As Long
Dim Uchoose As String
Dim animal As Variant
Dim blankchck As String
myrnglimit = 15
For myrng = 2 To myrnglimit
'isblank check
blankchck = Range("c" & myrng).Value
If blankchck = "" Then
'sets tosearch as each cell
tosearch = Range("a" & myrng).Value
'error checker then it matches each cell to the table hardcoded into the code
If IsError(myvalue = Application.Match(tosearch, Range("i1:i10"), 0)) Then
GoTo nextloop:
Else
myvalue = Application.Match(tosearch, Range("i1:i10"), 0)
'fills in the second column with Animal data
animal = Range("j" & myvalue).Value
Range("a" & myrng).Offset(0, 1).Value = animal
'User input for animal
Uchoose = MsgBox("Excel says : " & Range("k" & myvalue).Value & ". So are " & animal & " good?", vbYesNoCancel, "Status")
If Uchoose = vbYes Then
Range("a" & myrng).Offset(0, 2).Value = "Good"
ElseIf Uchoose = vbNo Then
Range("a" & myrng).Offset(0, 2).Value = "Bad"
ElseIf Uchoose = vbCancel Then
GoTo nextloop:
End If
'Select case to identify 1004 mismatch and skip
nextloop:
'Error checker if
End If
'Avoidblank if
End If
Next myrng
I think the problem may be caused because there is a difference between the data types in your range and the string variable toSearch. I'd recommend settting toSearch as follows:
Dim tosearch As Variant
The following link describes a similar problem and a similar solution to the one I have defined here.
http://www.excelforum.com/excel-programming-vba-macros/358571-application-match.html
I have a problem. I spent hours designing a form which works just great with all your feedback. Today, everything went wrong. The reason for this is simple. A few new columns got added and, obviously, the data my form is reading in is now wrong.
Thus I was thinking of trying the following...
Rather than using the column number as below
TK = Cells(ActiveCell.Row, "S").Value 'everything in the form refers to the active row
I could possibly use the column headings in Row 1.
Is that possible ? This way the spreadsheet can have columns added up to as many as a user would like and the form would dynamically scan for the right heading and get the column number that way.
My thought is, on opening the form, read in all the headings, pick out the ones I need and assign them to a variable. Then I use my normal code and substitute the variable into the column section.
It sounds easy, but I have no idea how to do this.
Use the versatile Find to give you a quick method of detecting where your header is - or if it is missing
Find details here
In the code below I have specified that the search must return
an exact match (xlWhole)
a case sensitive match (False)
The match can be a partial match (xlPart) if you were looking to match say Game out of Game X
code
Const strFind = "Game"
Sub GetEm()
Dim rng1 As Range
Set rng1 = ActiveSheet.Rows(1).Find(strFind, , xlValues, xlWhole, , , False)
If Not rng1 Is Nothing Then
MsgBox "Your column is " & rng1.Column
Else
MsgBox strFind & " not found", vbCritical
End If
End Sub
Why use a loop? There's no need to.
Dim col as variant
Col = application.match("my header", rows(1), 0)
If iserror(col) then
'not found
Else
TK = cells(activecell.row, col)
End if
For this purpose I usually use a function which runs through the headers (in the first row of a sheet) and returns the number of the column which contains the value I have searched for.
Public Function FindColumn(HeaderName As String, Sht As String) As Long
Dim ColFound As Boolean
Dim StartingPoint As Range
ColFound = False
Set StartingPoint = Sheets(Sht).Range("A1")
Do While StartingPoint.Value <> ""
If UCase(Trim(StartingPoint.Value)) = UCase(Trim(HeaderName)) Then
FindColumn = StartingPoint.Column
ColFound = True
Exit Do
Else
Set StartingPoint = StartingPoint.Offset(0, 1)
End If
Loop
If Not ColFound Then FindColumn = 0
End Function
Example:
If the first row of your sheet named "Timeline" contains headers like e.g. "Date" (A1), "Time" (B1), "Value" (C1) then calling FindColumn("Time", "Timeline") returns 2, since "Time" is the second column in sheet "Timeline"
Hope this may help you a little.
Your thought is a good one. Reading in column headers to calculate addresses is one way to avoid hard coding - e.g.
Sub Test()
Dim R As Range
Set R = ActiveSheet.[A1]
Debug.Print ColNo(R, "Col1Hdr")
End Sub
Function ColNo(HdrRange As Range, ColName As String) As Integer
' 1st column with empty header is returned if string not found
ColNo = 1
Do While HdrRange(1, ColNo) <> ""
If HdrRange(1, ColNo) = ColName Then Exit Do
ColNo = ColNo + 1
Loop
End Function
Another way I frequently use - and I must admit I prefer it over the above, is to define Enum's for all my tables in a seperate "definition" module, e.g.
Public Enum T_VPN ' sheet VPN
NofHRows = 3 ' number of header rows
NofCols = 35 ' number of columns
MaxData = 203 ' last row validated
GroupNo = 1
CtyCode = 2
Country = 3
MRegion = 4
PRegion = 5
City = 6
SiteType = 7
' ....
End Enum
and use it like
Sub Test1()
Debug.Print ActiveSheet(T_VPN.NofHRows, T_VPN.Country)
End Sub
As you can see, the usage is simpler. Allthough this is again "some kind" of hardcoding, having all definition in one place reduces maintenance significantly.