problem with VBA Find function in cells with formula - excel

I have a find function, it is supposed to look for "2021" in the range DP.
Range(DP).Find("2021", LookIn:=xlValues, LookAt:=xlWhole).Offset(1, 0) = t
2021 is in range but it is the result of a formula.
(Cell A2 in range DP is =$B$5 and B5=2021)
All ranges and variables are defined and the code works perfectly.
However, every once in while, I get the "'Run-time Error '91'"!!
I press debug, vba page opens and the Find function is the issue. (the value isn't found)
And the best part is, if I delete a random letter of the code and rewrite the EXACT same letter (basically changing NOTHING), and close vba and run again, the code works again without errors!!!
Any idea how to fix this bug?
Thanks in advance.

Make sure to define the worksheet
ThisWorkbook.Worksheets("Sheet1").Range(DP)
Make sure DP is a defined variable (use Option Explicit) or if you meant to use column DP then make sure it is a string Range("DP").
So maybe it should look something like
Dim t As String
t = "test"
Dim DP As String
DP = "A:A"
ThisWorkbook.Worksheets("Sheet1").Range(DP).Find("2021", LookIn:=xlValues, LookAt:=xlWhole).Offset(1, 0) = t
or something like this
ThisWorkbook.Worksheets("Sheet1").Range("DP").Find("2021", LookIn:=xlValues, LookAt:=xlWhole).Offset(1, 0) = "t"

Related

With Statement Proper VBA Syntax

Both of these code lines seem to work but are they both ok behind the scenes?
Dim Name as Range
With Sheet7
Set Name = .Cells(Selection.Row, Application.Match("A3", Rows(2), 0))
Set Name = .Cells(Selection.Row, Application.Match("A3", .Rows(2), 0))
End With
Do you have to put a period in front of "Rows" or not? Again it seems both work fine for finding the correct value.

Excel cant cope with large data set - need to lookup

So I have a data set of about 150k lookup references. I am trying to see if at any point these appear in my other dataset of around 4 Million.
If so, return true. Anything that returns false will be deleted from our crm.
I am currently just trying lookups of the 150k against 200k at a time but it still keeps crashing...
Does anyone have any ideas?
Since you don't have any code here, I could provide one example from a code I recentrly wrote. Maybe you can get an idea how to handle your problem.
Dim rFoundCell As Range
Dim the_string As String
Set xFoundCell = Sheets("Database").Range("B1:B100000").Find(Userform.Something,
LookAt:=xlPart, MatchCase:=False)
Sheets("ED").Range("B2") = xFoundCell.Address
the_string = Sheets("ED").Range("B2")
the_string = Replace(the_string, "B", "")
the_string = Replace(the_string, "$", "")
Sheets("ED").Range("B2") = the_string
This is a part of my code which is used to get the adress of my cell.
You could customize something like this in a loop and lookup all your cells.
Hope this can help you
Best regards

Please assist with writing a Macro to clean up data entries

Quick question that should be easy enough for a lot of you but I'm not well versed in VBA or code in general for that matter but I have a problem that only a Macro or piece of VBA code can resolve for me. I have to edit a large number of data entries in a spreadsheet, cell by cell.
So on to the question. Could you please show me an example or provide a complete macro for me to use to edit these cells?
The editing that I require is as follows:
I need to read each cell in the following range: B2 to Q383. A typical entry that needs to be examined and edited looks like this: 629.64\3.00\01:30
What needs to happen now is for everything to the left of the first "\" and everything to the right of the second "\" needs to be removed, including the "\", from each cell.
I've tried fiddling around with the LEFT and RIGHT commands and I can output the data that needs to be removed from the cells with something like this
=left(B11, Find("\", B11) - 1)
So what would be the delete command in a macro to target that data selection in that cell? Or how do I use a delete command with those parameters?
Thanks in advance for any advice or answers!
Not 100% sure what you're after - you say you want to remove the bits from the left and right, but the formula returns the bit on the left.
Anyway, here's 3 formula to do it:
Left: =TRIM(LEFT(B11,FIND("\",B11)-1))
Middle: =LEFT(MID(B11,FIND("\",B11)+1,LEN(B11)),FIND("\",MID(B11,FIND("\",B11)+1,LEN(B11)))-1)
Right: =MID(B11,FIND("\",SUBSTITUTE(B11,"\","~",1))+1,LEN(B11))
And three VBA functions to do it
(use these as you would formula - =leftbit(B11), or if you're looking for something other than backslashes - =leftbit(B11,"|") will find the I-bar as a divider. )
Public Function LeftBit(target As Range, Optional Divider As String = "\") As String
LeftBit = Trim(Left(target, InStr(target, Divider) - 1))
End Function
Public Function MiddleBit(target As Range, Optional Divider As String = "\") As String
Dim First As Long, Second As Long
First = InStr(target, Divider)
Second = InStr(First + 1, target, Divider)
MiddleBit = Mid(target, First + 1, Second - First - 1)
End Function
Public Function RightBit(target As Range, Optional Divider As String = "\") As String
RightBit = Right(target, Len(target) - InStrRev(target, Divider))
End Function

Passing a range from one VB function to another

I'm writing a few VBA functions for work and ran into a problem that should be easy to solve, but somehow I can't manage to, despite my best attempts at finding an answer here and on Google. I wrote a function that should give me the range between two strings in a column:
Function FindRng(StartRng As String, EndRng As String) As Variant
Dim TopOfRange As Single
Dim BottomOfRange As Single
TopOfRange = WorksheetFunction.Match(StartRng, Sheets("InfCom").Range("B:B"), 0)
BottomOfRange = WorksheetFunction.Match(EndRng, Sheets("InfCom").Range("B:B"), 0)
FindRng = Range(Sheets("InfCom").Cells(TopOfRange, 2), Sheets("InfCom").Cells(BottomOfRange, 2))
End Function
So if the inputs A and B are on rows 100 and 105, it should return B100:B105. When I test this by adapting the code to read FindRng = Range(...).Address, I indeed get $B$100:$B$105.
However, when I then input the result of FindRng into a customized Index Match function, I get an error. The function is as follows:
Function subsetPBPC(rngReturn As Range, LookupValueH As Variant, TopOfRange As String, BottomOfRange As String, LookupValueV As Variant) As Variant
subsetPBPC = sPBPC(rngReturn, LookupValueH, FindRng(TopOfRange, BottomOfRange), LookupValueV)
End Function
The problem is that it seems to read the output of FindRng not as a range, but as the content of that range: when I use the Evaluate Formula tool on FindRng embedded in another formula, it shows the output of FindRng as {A,B,C,D,E} instead of $B$100:$B$105, where A to E are the contents of the cells in the range. I have the feeling the solution is really simple, but I don't see it. The functions underlying the customized Index Match function have been tested and all work like a charm.
Set instead of let. Let assigns the value of an expression to a variable. Set assigns an object reference to a variable. You want to return a reference to the range object, not return the value produced by the range object's default property.
In VBA writing
FindRng = Range(...)
is implicitly writing
Let FindRng = Range(...)
However you want
Set FindRng = Range(...)
Edit 1:
It is quite important to understand the difference between an object reference and a value in VBA. This is a similar concept to passing arguments by value or by reference. Hopefully these two links help some:
The Let statement on MSDN
The Set statement on MSDN
Edit 2:
Oh, and I guess I should touch on default properties! Some objects like range have default properties. If you treat the range as a value instead of an object, it uses the default property instead of throwing an error because it's an object not a value. In the case of range the default property is Value. So if you say A = Range("A1") what you're actually saying is Let A = Range("A1").Value when you might mean Set A = Range("A1"). So you're getting the value contained in the cell A1, instead of a range object representing that cell.
Picking up that your current code should both
use Set as per AndADM's commnet
dimension SetRng as a Range rather than Variant
you can simplify your function as below (which may save time if you are calling it repetitively)
Also, you could test for this range being Nothing (if your two strings werent found), whereas you current code will error out if either string is missing.
Function SetRng(str1 As String, str2 As String) As Range
With Sheets("infCom").Columns(2)
Set SetRng = Range(.Find(str1, , xlValues, xlWhole), .Find(str2, , xlValues, xlWhole))
End With
End Function

Excel 2010 index match VBA

Tried everything and can't seem to get this. Trying to replace values in Row B (SiteTag) of one worksheet with the proper sitetag from an index match in another worksheet.
Worksheet(Site_Visit)
SiteTag
AL27
AS26
GBEM4
...
Worksheet(Sites)
SiteTag Project Name
203AL27 AL27
203AS26 AS26
201GBEM4 GBEM4
... ...
I need to replace the values SiteTag in Sheets("Site_Visit") with the appropriate SiteTag from Sheets("Sites").
For now I've simply tried to get the code to place the correct index value into a variable in which I'll place as the value for each cell, and run it in a loop. But for the life of me can't get it to get a value. This is what I've tried for the variable (everything has been declared).
ST_Cells2 = Application.WorksheetFunction.Index("Sites!A2:A34", Application.WorksheetFunction.Match("Site_Visit!B2", "Sites!B2:B34", 0), 0)
Where "Sites!A2:A34" is the range for the appropriate replacement value
"Sites_Visit!B2" is the lookup value
"Sites!B2:B34" is the lookup range
I'm getting a Run Time error '1004' Unable to get the Match property of the WroksheetFunction class. Anyone have any ideas?
The Index and Match functions are expecting Ranges, but you are sending them strings. The easiest way to turn strings into Ranges is to use Excel's Range function:
st_cells2 = Application.WorksheetFunction.Index(Range("Sites!A2:A34"), Application.WorksheetFunction.Match(Range("Site_Visit!B2"), Range("Sites!B2:B34"), 0), 0)
I had the same error, but it run ok when I changed to "Application" indstead of WorksheetFunction:
Cells(12, 12).Value = Application.Index("Sheet1!B1:9", 2)
Somehow running the Function from Application directly worked...
/K

Resources