Excel cant cope with large data set - need to lookup - excel

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

Related

problem with VBA Find function in cells with formula

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"

Set range equal to multiple named ranges with line break

I am setting a range variable equal to a list of ranges. The list is so long that I would like to use a line break for easier management. However, I am having a tough time getting the syntax. I've tried many combinations.
The code in one line works and looks like this (with a lot more named ranges):
Dim xNamedRangeList As Range
Set xNamedRangeList = Range("NamedRange1, NamedRange2")
My best attempt so far is this.
Set xNamedRangeList = " Range(""" & _
"NamedRange1," & _
"NamedRange2" &_
""")"
Debug.print looks like this: Ranged("NamedRange1, NamedRange2")
While this works in debug.print, it sure doesn't work when I set xNamedRangeList equal to it. I think I've turned the formula into a string, but not sure how to make it work in the formula.
The correct syntax would be as shown by #TimWilliams.
But you say "with a lot more named ranges", so please note that the length an address used in Range(address) can have is limited to 255 characters. So if you have a lot of ranges you might hit that limit and it doesn't work.
If that might be the case you must use the Application.Union method:
Dim xNamedRangeList As Range
Set xNamedRangeList = Application.Union(Range("NamedRange1"), Range("NamedRange2"))
Line breaks are always Space followed by underscore _ and Enter.
Set xNamedRangeList = Application.Union(Range("NamedRange1"), _
Range("NamedRange2"))
Set xNamedRangeList = Range("NamedRange1," & _
"NamedRange2," & _
"NamedRange3")
If NamedRange1 and NamedRange2 are variables then try:
Range(NamedRange1 + NamedRange2)

Performing same operation on multiple named ranges

I have a bunch of named ranges within a sheet that must get cleared every day. Currently I have it set up within VBA like this:
Range("CustomList1").ClearContents
Range("CustomList2").ClearContents
Range("CustomList3").ClearContents
Range("CustomList4").ClearContents
Range("CustomList5").ClearContents
(+15 more)
Not really a big deal but I feel like there must be a better way of going about it. That being said after doing some searching I didn't really see anything about looping through multiple named ranges. Any ideas/thoughts on this?
Dim i As Long
For i = 1 to 20
Range("CustomList" & i).ClearContents
Next
... something like that.
If you had some sort of naming convention for named ranges that you want to clear, you could do something like this which means you don't ever need to update your code ...
Dim objName As Name
For Each objName In ThisWorkbook.Names
If InStr(1, objName.Name, "NamedRange", vbTextCompare) = 1 Then
With objName.RefersToRange
.Worksheet.Range(.Address).ClearContents
End With
End If
Next
Skin's solution will work if the name is consistent, but if not, you could always create an array with all the range names.
Something Like
RngArray = Array("CustomList1","CustomList2","CustomList3, etc.")
For i = 0 to 19
Range(RngArray(i)).ClearContents
Next
A Union may be more typing than a loop but it completes the operation in a single statement.
Union(Range("CustomList1"), Range("CustomList2"), Range("CustomList3"), _
Range("CustomList4"), Range("CustomList5"), Range("CustomList6"), _
Range("CustomList7"), Range("CustomList8"), Range("CustomList9"), _
Range("CustomList10"), Range("CustomList11"), Range("CustomList12"), _
Range("CustomList13"), Range("CustomList14"), Range("CustomList15"), _
Range("CustomList16"), Range("CustomList17"), Range("CustomList18"), _
Range("CustomList19"), Range("CustomList20")).ClearContents
This method would likely be better suited to named ranges with abstract or dissimilar naming conventions.
I would do this slightly differently.
I would store the names under one name in the Formula==>Names Manager as shown below.
And then I will only use the below every where. No need for several lines of code everytime you want to clear the range.
Range("MyCustomList").ClearContents

(Excel) Pick formula criteria/logical etc from another cell(reference)

Im writing an If+Or function and would like to use several cell references for the different Logicals in the function, instead of writing each logical statements in the original if+or function. Any ideas of how to solve this? Hope im not too unclear here..
As example: instead of writing =If(or(A1=A2,A3=A4),A1,0) I would like to write out all different logical values in a list of cells, and the just write the original if+or formula like this: =IF(OR(B1),A1,0) where B1 contains the text "A1=A2,A3=A4"
Thanks for any help on this!
You can use the INDIRECT function.
For example, if the value in cell A6 is 10, INDIRECT("A6") = 10.
So basically you can write INDIRECT("A6")=INDIRECT("A7") instead of the A1=A2 condition in your IF formula.
If you want to have "A1=A2" in one cell, you can use LEFT and RIGHT.
Here is an example: https://docs.google.com/spreadsheets/d/157tRicA55TFKKOi86yYBQScnjaQE6fYxaCHFdZx4uUM/edit?usp=sharing
PS: this solution is for Google Sheets so the solution might differ a little if you're using Excel but that should work for Excel too.
You CANNOT Have It All
Instead of using =IF(OR(B1),A1,0) you have to use
e.g. =IFOR(B1,A1) (I prefer "" instead of 0, sorry)
or =IFOR(B1,A1,0) if you (prefer 0 instead of ""),
or change the ElseValue in the declaration to 0,
then you can use =IFOR(B1,A1) to get 0.
Function IFOR(IfOrCell As Range, ThenCell As Range, _
Optional ElseValue As Variant = "", _
Optional SplitDelimiter As String = ",") As Variant
'Description:
'Pending...
'Recalculation
Application.Volatile
'Variables
Dim arrIfOr As Variant
Dim iIfOr As Integer
Dim blnIfOr As Boolean
'The Array: The Split
If InStr(IfOrCell.Value2, SplitDelimiter) = 0 Then Exit Function
arrIfOr = Split(IfOrCell.Value2, SplitDelimiter)
'An Additional Split Introducing the Boolean
For iIfOr = LBound(arrIfOr) To UBound(arrIfOr)
If InStr(arrIfOr(iIfOr), "=") <> 0 Then
If Range(Split(arrIfOr(iIfOr), "=")(0)).Value2 _
= Range(Split(arrIfOr(iIfOr), "=")(1)).Value2 Then
blnIfOr = True
Exit For
End If
End If
Next
'Output
If blnIfOr = True Then
IFOR = ThenCell.Value2
Else
IFOR = ElseValue
End If
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

Resources