Can not get the right syntax for nested array limit

JeffGrant

Well-known Member
Joined
Apr 7, 2021
Messages
516
Office Version
  1. 365
Platform
  1. Windows
Hi All, I am starting to realise how much I don't know. That is for sure :)

in a bid to speed up my calculations, I would like to move my Find & Replace functions from reading/writing the spreadsheet to an array in memory.
I have adopted this array code from Hacker95 and am trying to modified it by watching a bunch of YouTube videos.
Doing a single array is easy enough, but nesting arrays is throwing me.

Because I am new to memory array structures, I am stuck on this syntax. I know the arr(5, Row) is where I am falling down in this line.

For Each c In arr(5, Row)

5 equates to column E in the spreadsheet and Row is supposed to be the incremental row.

I would really appreciate fi somebody could tell me what I am doing wrong here.

Thanks in advance

Jeff

Here is the whole Sub for reference
VBA Code:
Sub ReadRange()
Dim arr As Variant, fnd As Variant

'Read the Arrays to read in
arr = Sheet15.Range("A1").CurrentRegion  'Range of values to be Updated
fnd = Sheet15.Range("G1").CurrentRegion  'Range of values to update with. Column G is Find Value, Column His Replace Value

'Am using this With Statement to find limits because I cant make the fnd array work 
With Sheet15 ' reading end of rows from here because is only a once off read
  LastRow = Range("H3").End(xlDown).Row
  Row = Range("A1").End(xlDown).Row
  sr = .Range("G3:H" & LastRow)
End With
 
'Do Find & Replace
  For Each c In arr(5, Row)     'THIS LINE GIVES A RUN-TIME 9, SUBSCRIPT OUT OF RANGE ERROR
    For i = LBound(sr) To UBound(sr)
      If InStr(c, sr(i, 1)) Then
        c = Replace(c, sr(i, 1), sr(i, 2))
      End If
    Next i
  Next c

'write the Array out
Sheet15.Range("A24").CurrentRegion.ClearContents
Dim rowCount As Long, columnCount As Long
rowCount = UBound(arr, 1)
columnCount = UBound(arr, 2)

Sheet15.Range("A24").Resize(rowCount, columnCount).Value = arr

End Sub
 

Excel Facts

Excel Joke
Why can't spreadsheets drive cars? They crash too often!
Find & Replace - Form Track Condition
class restrictionshorse nameform classform trackform track conditionFind WhatReplace With
Class 1BazookaBench. 72RandwickGood 4Firm 1Firm
Class 1BazookaBench. 72RosehillSoft 5Firm 2Firm
Class 1BazookaBench. 72RandwickHeavy 9Good 2Good
Class 1MantinelloClass 1SconeGood 4Good 3Good
Class 1MantinelloClass 1WyongSoft 6Good 4Good
Class 1MantinelloMaidenNewcastleSoft 5Soft 5Soft
Class 1Fine RubyMaidenHawkesburyGood 4Soft 6Soft
Class 1Fine RubyMaidenWyongGood 4Soft 7Soft
Class 1Fine RubyMaidenNewcastleGood 4Heavy 8Heavy
Class 1Chateaux ParkBench. 64NewcastleGood 4Heavy 9Heavy
Class 1Chateaux ParkClass 1GosfordSoft 5Heavy 10Heavy
Class 1Chateaux ParkClass 1HawkesburyHeavy 8Dead 4Dead
Class 1Tip Top TimingClass 1GosfordSoft 5Dead 5Dead
Class 1Tip Top TimingMaidenGoulburnHeavy 10Dead 6Dead
Class 1Tip Top TimingMaidenHawkesburySoft 7Slow 7Slow
Class 1SpeedzoneBench. 64Kembla GrangeGood 3Slow 8Slow
Class 1SpeedzoneClass 1WyongSoft 6Slow 9Slow
 
Upvote 0
Hi, @JeffGrant
Your sample data in post #2, is that your actual data?
So the content in col E is a SINGLE WORD followed by numbers, and you just want to remove the number part?
If yes, then there's a faster way than using Replace from a list.
If not, then using Dictionary object would be faster.
How many rows is your data?
 
Upvote 0
Hi Akuini,

I never thought about it like that, but you are correct. In this particular Find & Replace, only the number needs to be stripped away.

However, there are four other Find & Replaces that actually do involve find and replacing text.

Being - this block is run over two separate columns for example.

The number of records can be anywhere between 1,000 and 5,000 on any particular day.

If I run this over a week for example, the number of records can be up to 50,000.

Which is why I would like to do this in memory rather than reading/writing to a sheet.

Find WhatReplace With
MaidenMdn
Rest 0 Metro WinsRS0MW
Rest 1 Metro WinRS1MW
Rest 2 Metro WinsRS2MW
Rst 0 Met Win-LYRS0LY
Rst 1 Met Win-LYRS1LY
Rst 2 Met Win-LYRS2LY
Rst 3 Met Win-LYRS3LY
RestrictedRST
Rest.RST
ClsClass
56+BM56+
58+BM58+
64+BM64+
Bench.BM
BenchmarkBM
BMBMBM
 
Upvote 0
However, there are four other Find & Replaces that actually do involve find and replacing text.
Ok, so there are data that just need the number to be removed & data that need Find-Replace.
Are they in separate column or sheet?
If not, can you easily separate them?
 
Upvote 0
Yes, everything is in separate columns.

For the purpose of this example.....
From reply #2 above.
The number is separated off the data in Column 5, as you have identified.

From Reply # 4 above.
The Find and Replace needs to be applied to Columns 1 and 3.

Then there is another Find and Replace Text list, that I have not put up here, that is applied to Column 4.

Then there is another Find & Replace list made up of silly odd bits to clean the data up.

Unfortunately, the input data comes from a variety or sources, and the purpose of these Find and Replace routines is to normalize the data.

Effectively, I run the Find and Replace Sub four times on different columns, which is why I didn't notice what you identified about the number separation :) in column 5.

These Find and Replace are the slowest part of the whole model, which is why I am looking to speed it up anywhere I can.
 
Upvote 0
Ok, try this:
1. Sub remove_number : it's for col E, to remove the number , assuming the value are only a single word and number
2. Sub to_FR: it's for Find-Replace, you need to adjust the code:
Call to_Replace("G", "D") 'G means list of find-replace is in col G:H, D means column where data is located
and because you have multiple column of data then add some other line accordingly.

Note: I put the result in col J:K so you can see the result without changing the data, but of course you need to adjust it.

VBA Code:
Sub remove_number()
Dim i As Long
Dim va, t
t = Timer
va = Range("E3", Cells(Rows.Count, "E").End(xlUp))
For i = 1 To UBound(va, 1)
    va(i, 1) = Split(va(i, 1), " ")(0)
Next

'change K3 to E3
Range("K3").Resize(UBound(va, 1), 1) = va
Debug.Print "It's done in: " & Timer - t & " seconds"

End Sub

Sub to_FR()
    Call to_Replace("G", "D") 'G means list of find-replace is in col G:H, D means column where data is located
    'add another list & data column here
    'Call to_Replace("M", "A")
End Sub

Sub to_Replace(a As String, b As String)

Dim i As Long
Dim va, vb, t
Dim d As Object
t = Timer
va = Range(a & 3, Cells(Rows.Count, a).End(xlUp)).Resize(, 2)
vb = Range(b & 3, Cells(Rows.Count, b).End(xlUp))

Set d = CreateObject("scripting.dictionary")
d.CompareMode = vbTextCompare

For i = 1 To UBound(va, 1)
    d(va(i, 1)) = va(i, 2)
Next

For i = 1 To UBound(vb, 1)
    If d.Exists(vb(i, 1)) Then vb(i, 1) = d(vb(i, 1))
Next

Range("J3").Resize(UBound(vb, 1), 1) = vb

'use this one:
'Range(b & 3).Resize(UBound(vb, 1), 1) = vb
Debug.Print "It's done in: " & Timer - t & " seconds"
End Sub

Book1
ABCDEFGHIJK
1GoodFind & Replace - Form Track Condition
2Softhorse nameform classform trackform track conditionFind WhatReplace With
3HeavyBazookaBench. 72RandwickGood 4GosfordGIGood
4GoodBazookaBench. 72RosehillSoft 5GoulburnNZSoft
5SoftBazookaBench. 72RandwickHeavy 9HawkesburyUIHeavy
6SoftMantinelloClass 1SconeGood 4Kembla GrangeRWGood
7GoodMantinelloClass 1WyongSoft 6NewcastleBHSoft
8GoodMantinelloMaidenNewcastleSoft 5RandwickIBSoft
9GoodFine RubyMaidenHawkesburyGood 4RosehillZUGood
10GoodFine RubyMaidenWyongGood 4SconeWHGood
11SoftFine RubyMaidenNewcastleGood 4WyongHBGood
12HeavyChateaux ParkBench. 64NewcastleGood 4BGood
13SoftChateaux ParkClass 1GosfordSoft 5GSoft
14HeavyChateaux ParkClass 1HawkesburyHeavy 8UHeavy
15SoftTip Top TimingClass 1GosfordSoft 5GSoft
16GoodTip Top TimingMaidenGoulburnHeavy 10NHeavy
17SoftTip Top TimingMaidenHawkesburySoft 7USoft
18Class 1SpeedzoneBench. 64Kembla GrangeGood 3RGood
19Class 1SpeedzoneClass 1WyongSoft 6HSoft
20
Sheet1
 
Upvote 0
Hi Akuini,

Um--I am blown away, gob smacked, surprised, in total Awe....

1629455910658.png


Thank you so much...

I wish I knew more like you.
 
Upvote 0
You're welcome, glad to help & thanks for the feedback.:)
 
Upvote 0
Akuini, thank you again for such a fantastic response. As you would appreciate it has sped up the calculations immensly.

Unfortunately, I have found one minor glitch. Using CompareMode like this is comparing the whole cell and does not do a partial comparison.

For example, if we pick any Find value, say 56 as part of the string.

In the original Find & Replace, I would have:

Find values
Restricted -> Replace with RST
RST. -> Replace with RST
Bench. -> Replace with BM
Benchmark -> Replace with BM

with the CompareMode based on entire cell value, I have to effectively quadruple the size of the FIND List to be in the order of some 500 entries, just for this sequence of numbers.

Given that exponential increase in processing speed, it is not such a big deal, but I was just wondering if there a more efficient way to handle the partial string search?

cheers
 
Upvote 0

Forum statistics

Threads
1,215,069
Messages
6,122,958
Members
449,096
Latest member
Anshu121

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top