Find blank cells and array items addresses to arraylist

Vincent88

Active Member
Joined
Mar 5, 2021
Messages
382
Office Version
  1. 2019
Platform
  1. Windows
  2. Mobile
Hi Guys, I want to find the cell addresses to a Arraylist (blankarray) of those values in an array (bArray). It seems that the code adds those blank cells' addresses only but not those values to Arraylist. Please advise correction to my code to make it works.
Also I want to list those findings of each row in individual column in the Arraylist (meaning findings of row 3 in rngData shown in column 1 of Arraylist , that of row 4 shown in column 2 of Arraylist and so on).
Thanks.

VBA Code:
Sub rngOver32()

Dim cl As Range, rngData As Range

Application.DisplayStatusBar = False
Application.EnableEvents = False
Application.ScreenUpdating = False


Dim lastrow As Long, lastcol As Long
lastrow = Range("A3").End(xlDown).Row
lastcol = Cells(1, Columns.Count).End(xlToLeft).Column

'LIST OF VALUE TO FIND
Dim bArray As Variant
bArray = Array("AL", "SL", "BL", "CL", "PL", "VL", vbNullString)
Dim bArraystr As String


'EXPORT CELL ADDRESSES TO ARRAYLIST
Dim blankarray As Object
Set blankarray = CreateObject("System.Collections.ArrayList")

'SET DATA RANGE TO SEARCH
Set rngData = Range(Cells(3, 3), Cells(lastrow, lastcol))
Debug.Print rngData.Address

On Error GoTo ErrorHandler

For Each cl In rngData
    If cl.Value = bArraystr Then
       If Not blankarray.contains(cl.Address) Then blankarray.Add cl.Address
    End If
Next cl

ErrorHandler:
Application.EnableEvents = True
   
Application.DisplayStatusBar = True
Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub

AgentProposal_Roster0728_1025M.xlsm
ABCDEFGHIJKLMNOPQRSTUVWXYZAAABACADAEAFAGAHAIAJAKAL
1MDateAttendance26-Nov27-Nov28-Nov29-Nov30-Nov1-Dec2-Dec3-Dec4-Dec5-Dec6-Dec7-Dec8-Dec9-Dec10-Dec11-Dec12-Dec13-Dec14-Dec15-Dec16-Dec17-Dec18-Dec19-Dec20-Dec21-Dec22-Dec23-Dec24-Dec25-Dec26-Dec27-Dec28-Dec29-Dec30-Dec31-Dec
2DateSummary(5)(4)(3)(2)(1)12345678910111213141516171819202122232425262728293031
3Xia MT:22 L:2.5 D:16.5 E:7 N:0GGGGGGVLVLGGDKEEEDDDDDAMDDDDDDEEEE
4Zita VT:22 L:1 D:12 E:11 N:0DDDDDDDEEEEEDDDDDDDDCLEEEEEE
5Ken CT:22 L:6 D:5 E:5 N:11KKKKKKKKALNNNNNEEEEEALNNNNNNALALALAL
6Larry QT:22 L:0 D:15 E:0 N:0D3D3D3D3D3D3D3D4D4D4D4D4D4D4D4D4D4G
7John GT:22 L:0.5 D:17.5 E:5 N:0EEEEEEED1D1D1GGGGGPMGGGGGGGGG
202112
Cells with Data Validation
CellAllowCriteria
A3:A7List=HelpAgent
H3:AL7List=ShiftcodeNew
A1List=Data!$U$2:$U$15
 
the "indi" shown 1 when error occurs.
 

Attachments

  • error.PNG
    error.PNG
    25.6 KB · Views: 11
Upvote 0

Excel Facts

Lock one reference in a formula
Need 1 part of a formula to always point to the same range? use $ signs: $V$2:$Z$99 will always point to V2:Z99, even after copying
That makes sense, what it means is that No matches have been found, so in the line:
VBA Code:
 .Range(.Cells(1, 1), .Cells(indi - 1, 1)) = blankarray
indi-1 = 0, there is no row zero so you get an error. So you must be running the code on the wrong worksheet or else there really aren't any matches for the the string in Barray.
One other alternative you might have copied the code incorrectly, so what about posting the code you are actually running.
It is easy to put some protection for this case if you need it
 
Upvote 0
I just had another look at your debug listing and it shows LASTROW=2, this means there is NO DATA to check because the checks only start on row 3, so the code will crash. I suspect you are running it on the wrong sheet
 
Upvote 0
Hi offthelip,
Please help how to apply the sorting as shown in the image in arraylist not in physical cells.
The code that I make the sorting in physical cells is listed.
The sorting is as follows :
I need to sort those cells' addresses in column AA in following order
1. sort the row number first (as shown in column AD)
2. then sort the column number (col AC) (in order to sort the column, I use ToColNum to convert the column letters (Column AB) to column numbers (Column AC))

VBA Code:
Sub rngOver33()

'Dim cl As Range,
Dim rngData As Variant

Dim lastrow As Long, lastcol As Long
lastrow = Range("A2").End(xlDown).Row
lastcol = Cells(2, Columns.Count).End(xlToLeft).Column

'LIST OF VALUE TO FIND
Dim bArray As Variant
bArray = Array("AL", "SL", "BL", "CL", "PL", "VL", "ML", vbNullString)
Dim bArraystr As String

Debug.Print lastrow, lastcol


Dim blankarray() As Variant

ReDim blankarray(1 To lastrow * lastcol, 1 To 1)
'Load DATA RANGE TO SEARCH
rngData = Range(Cells(1, 1), Cells(lastrow, lastcol)) ' this load the data into a variant array (much faster)


'On Error GoTo ErrorHandler don't do this it just hides any error
indi = 1
For i = 1 To UBound(bArray)
bArraystr = bArray(i)
 For j = 3 To lastrow ' Note we are starting on row 3 as per the original
   For k = 3 To lastcol
    If rngData(j, k) = bArraystr Then
       blankarray(indi, 1) = colno2let(k) & j
       indi = indi + 1
    End If
   Next k
 Next j
Next i
With Worksheets("Data")
 .Cells(1, 27).CurrentRegion.Value = vbNullString
 .Range(.Cells(1, 27), .Cells(indi - 1, 27)) = blankarray
 
'End With

Application.ScreenUpdating = False
Application.EnableEvents = False
'With Worksheets("Data")
'Dim lrow As Long
 'lrow = .Range("AA1").End(xlDown).Row
 lRow = .Cells(1, 27).End(xlDown).Row
 
For Each c In .Range(.Cells(1, 28), .Cells(.Cells(1, 27).End(xlDown).Row, 28))
     c.Value = tex(c.Offset(, -1))
Next c

For Each k In .Range(.Cells(1, 29), .Cells(.Cells(1, 27).End(xlDown).Row, 29))
     k.Value = ToColNum(k.Offset(, -1))
Next k

For Each n In .Range(.Cells(1, 30), .Cells(.Cells(1, 27).End(xlDown).Row, 30))
     n.Value = num(n.Offset(, -3))
Next n

'.Range("AA1:AB" & lrow).Sort Key1:=.Range("AB1"), _

.Cells(1, 27).CurrentRegion.Sort key1:=.Cells(1, 30), _
                     Order1:=xlAscending, _
                     key2:=.Cells(1, 29), _
                     order2:=xlAscending, _
                     Header:=xlNo, _
                     Orientation:=xlTopToBottom

Application.ScreenUpdating = True
Application.EnableEvents = True
End With


End Sub

Function colno2let(colno As Variant) As String
let2 = colno / 26

If let2 > 1 Then
 let22 = Round(let2)
 txt = Chr(let22 + 64)
 txt = txt & Chr(64 + colno - (26 * let22))
Else
txt = Chr(colno + 64)
End If
colno2let = txt

End Function


Function num(rng As Range) As String
Dim n As Integer
For n = 1 To Len(rng)
If Mid(rng, n, 1) Like "[0-9]" Then
num = num & Mid(rng, n, 1)
End If
Next n
End Function

Function tex(rng As Range) As String
Dim n As Integer
For n = 1 To Len(rng)
If Mid(rng, n, 1) Like "[A-Z]" Then
tex = tex & Mid(rng, n, 1)
End If
Next n
End Function


Public Function ToColNum(ColN)
    ToColNum = Range(ColN & 1).Column
End Function
 

Attachments

  • aftersorting.png
    aftersorting.png
    30.9 KB · Views: 8
Upvote 0
you are making very hard work of what is very simple to do: because the code is doing a triple loop through Barray, then rows , then columns, you can solve your "sorting" probelm just by changing the order of the three loops. so all your code and your additional functions are not necessary. So thy this which will create the list in a "sorted order"
VBA Code:
Sub rngOver33()

'Dim cl As Range,
Dim rngData As Variant

Dim lastrow As Long, lastcol As Long
lastrow = Range("A2").End(xlDown).Row
lastcol = Cells(2, Columns.Count).End(xlToLeft).Column

'LIST OF VALUE TO FIND
Dim bArray As Variant
bArray = Array("AL", "SL", "BL", "CL", "PL", "VL", "ML", vbNullString)
Dim bArraystr As String

Debug.Print lastrow, lastcol
Dim blankarray() As Variant

ReDim blankarray(1 To lastrow * lastcol, 1 To 1)
'Load DATA RANGE TO SEARCH
rngData = Range(Cells(1, 1), Cells(lastrow, lastcol)) ' this load the data into a variant array (much faster)


'On Error GoTo ErrorHandler don't do this it just hides any error
indi = 1
For k = 3 To lastcol   ' note the change in order of these 3 loops
 For j = 3 To lastrow '    
  For i = 1 To UBound(bArray)
    bArraystr = bArray(i)
    If rngData(j, k) = bArraystr Then
       blankarray(indi, 1) = colno2let(k) & j
       indi = indi + 1
    End If
   Next i    ' and here
 Next j
Next k
With Worksheets("Data")
 .Cells(1, 27).CurrentRegion.Value = vbNullString
 .Range(.Cells(1, 27), .Cells(indi - 1, 27)) = blankarray
 

End With


End Sub

Function colno2let(colno As Variant) As String
let2 = colno / 26

If let2 > 1 Then
 let22 = Round(let2)
 txt = Chr(let22 + 64)
 txt = txt & Chr(64 + colno - (26 * let22))
Else
txt = Chr(colno + 64)
End If
colno2let = txt

End Function

If you really want the column numbers and row numbers in separate columns. you don't need to decode them from the Alpah numeric address , they are already available because the indices j and k are row and column nuumbers so if you want then they just need to be saved in a variant array and written to the worksheet.
Note: I actually needed to include the function colno2let, specifically to convert column numbers to letters, because that is what you asked for. Column numbers are much easier to deal with in VBA than column letters.
 
Upvote 0
@offthelip
When I tried your function like this:
VBA Code:
Debug.Print colno2let(40) 'result B4
the result is B4 which is wrong

A simpler code to get column letter from column number:

VBA Code:
colno = 40
Debug.Print Split(Cells(1, colno).Address, "$")(1) 'result AN
 
Upvote 0
You are correct, thank you for pointing it out. I got the round down wrong, I had only tested it up the first half of the alphabet. this modification works:
VBA Code:
Function colno2let(colno As Variant) As String
let2 = colno / 26

If let2 > 1 Then
 let22 = Int(let2)
 txt = Chr(let22 + 64)
 txt = txt & Chr(64 + colno - (26 * let22))
Else
txt = Chr(colno + 64)
End If
colno2let = txt

End Function
I prefer to make my functions independent of any access to worksheets because it slow the functions down.
 
Upvote 0
You are correct, thank you for pointing it out. I got the round down wrong, I had only tested it up the first half of the alphabet. this modification works:
VBA Code:
Function colno2let(colno As Variant) As String
let2 = colno / 26

If let2 > 1 Then
 let22 = Int(let2)
 txt = Chr(let22 + 64)
 txt = txt & Chr(64 + colno - (26 * let22))
Else
txt = Chr(colno + 64)
End If
colno2let = txt

End Function
I prefer to make my functions independent of any access to worksheets because it slow the functions down.
Hi offthelip,
What about if I want to sort it by row number ?
 
Upvote 0
I also recognize that the code did not find cell addresses of the value "AL". Very strange !
My screenshot shown cell address E3 and M3 with value "AL"
 

Attachments

  • noALcell.png
    noALcell.png
    11.2 KB · Views: 8
  • Screenshot 2021-11-16 123015.png
    Screenshot 2021-11-16 123015.png
    42.5 KB · Views: 7
Upvote 0

Forum statistics

Threads
1,215,429
Messages
6,124,842
Members
449,193
Latest member
MikeVol

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