Item way of thinking as alternative to conventional row column looping.
URL links to here: This is post: https://www.excelfox.com/forum/showt...1D-arr2D-arr1D
https://www.excelfox.com/forum/showthread.php/2789-Item-way-of-thinking-as-alternative-to-conventional-row-column-looping-arr1D-arr2D-arr1D?p=16456&viewfull=1#post16456
https://www.excelfox.com/forum/showt...ll=1#post16456
https://excelfox.com/forum/showthread.php/2789-Item-way-of-thinking-as-alternative-to-conventional-row-column-looping
https://excelfox.com/forum/showthrea...ping#post16456
https://excelfox.com/forum/showthread.php/2789-Item-way-of-thinking-as-alternative-to-conventional-row-column-looping#post16456
Computers v Humans
It can help a lot in understanding and producing advanced VBA solutions in thinking about the difference in
_ Computers, and
_ how we prefer to see things.
A computer is just a long string of characters. Very quickly. We find that difficult.
Excel makes it a bit easier for us to look at: it puts a bit of it on a row, notches that up ( "Line feed" ) , goes back ( "Carriage Return" ), and puts the next bit on the next row etc. Then it lets us see it all on a screen. (Or it is updating each bit so us stupid humans quickly that we think it’s there all the time. Some of my better solutions are based on tapping into that fast updating to do something most efficiently, making it seem like something across a large range or table is done all at once).
Its handy to have in your tool box at hand a way to move easily between the two ,
_ the long single string, and
_ the 2 Dimensional display.
That is what this series of Blogs/ This Thread, is all about
Thread Contents
It’s easy to get mixed up as we are mixing up Excel Spreadsheet and VBA things, so here is an overview to help get quicker to things you may be looking for.
Post #2 ( and Post #4 ) Item way of thinking as alternative to conventional row column looping in VBA
The traditional way to loop all cells is 2 loops, one inside the other, going for example along the columns for a row, then next row etc., pseudo
__ For Each row, r
____ For Each column, c, in the row
_____Cell (r, c)
____ Next column
__ Next row
All that is done in and with, VBA. We are looping through all cells
Post #2 primarily talks about an alternative single loop idea. This is possible as many things in Excel are also ordered in a sequential single item number, (sometimes referred to as index, to help confuse things later). This is done in a specific way for a range of cells, so because we know what this specific way is, it this allows to alternatively loop the item nubers instead, calculating if needed the row and column number, pseudo like
__For all items
___Cell(rcalculated from item number , ccalculated from item number )
You see, for each item number we are able to determine/ calculate the row and column associated with it. Each cell is assigned an item number, so looping the item numbers we can also be looping all cells, since we can calculate which cell is by the calculated row and column number for that item number.
__Next item
All that is done in and with, VBA
This Item way of thinking is generally useful to know about, and can have practice advantages, but it’s unlikely to have great performance advantages. If for example we have a two row, 3 column range, the convention of the item number is like
1 2 3
4 5 6
, then the conventional way does 3 columns twice and the item way does 6 items, so we effectively loop 6 times in either way. Simple example: For 6 items, 1 2 3 4 5 6 , then at each item loop, I needed to get at each item number loop, ( 1 to 6 ),
_ the row indices of 1 1 1 2 2 2 and
_ the column of where those things were was 1 2 3 1 2 3
The main purpose of Post #2 and # 4 is to calculate those row and column indicies
Post #5 and Post #6 and Post #7 and Post #8 VBA Range Evaluate(" ") ( 2Darray() to 1DArray() )
The relevance to this Thread is a bit shirttail, and this subject is tackled many tines elsewhere. It fits in here as
_ we share similar mathematics to the last post
_ It fits well to the concept of a different, arguably often better, approach to looping/ reduced looping, - in this case, .. none!!
We tap into the way Excel tries to put something almost simultaneously in a 2 dimensional picture that to us humans looks like a static immediate picture.
Taking again the 2 row 3 column example we take an array of numbers in an item type list, { 1 2 3 4 5 6 } and get the corresponding array
_ for the rows { 1 1 1 2 2 2 } , and
_ the columns { 1 2 3 1 2 3 }
We can mess about with Excel things and functions that more usually take single values, and give them arrays of values instead. We are not technically doing then what mathematically is strictly array calculations**, although we are doing something similar to get an array of results instead of a single value result. (** It’s often called array calculations which can be a bit misleading)
Post #5 is just one example of this VBA Range Evaluate(" ") idea, but is included here as it happens to use very similar mathematics to Post #2 and Post #4
Item way of thinking as alternative to conventional row column looping.
URL links to here: This is post: https://www.excelfox.com/forum/showt...ll=1#post23384
https://www.excelfox.com/forum/showthread.php/2789-Item-way-of-thinking-as-alternative-to-conventional-row-column-looping-arr1D-arr2D-arr1D?p=23384&viewfull=1#post23384
https://www.excelfox.com/forum/showt...rr1D#post23384
https://www.excelfox.com/forum/showthread.php/2789-Item-way-of-thinking-as-alternative-to-conventional-row-column-looping-arr1D-arr2D-arr1D#post23384
Item way of thinking as alternative to conventional row column looping
Current conventional way of thinking
This Blog post assumes that you have some basic Excel VBA programming experience, and that you are familiar with this general idea used typically when filling or getting data from cells
__For Rw = 1 To maximumRows
____For Clm = 1 To maximumColumns
_____( Rw, Clm )
____Next Clm
__ Next Rw
This basic process you should make sure you fully understand before reading further.
This Blog post suggest a slightly different way about thinking about that process
Introduction
Excel Spreadsheets can be turned into pretty pictures, computer graphics and games and “dashboards”.
But they are usually not the best at doing those things.
They are best for doing things with 2 dimensional “tables” of data.
They bridge the gap between
_ dead stores of data or long fast streams of string data (Computers),
and
_ relatively slow and static living humans interacting with them
I expect we are not a long way from interacting in a 3 dimensional way, but it will settle down, I think, to be useful in a limited way. More than 3 dimensions are difficult for humans to react easily with.
A 2 dimensional desktop is particularly convenient for us.
Smartphones are a trend that I think might go back a bit to being just glorified telephones, walkmans, live cameras and simple computer games.
I personally would say, live actively physically in 3 dimensions, forget smart phones, and sit down occasionally and watch the telly or a 2 dimensional PC or laptop to get some stuff done in your computer corner.
We are basically talking in this Thread about organising a string of data travelling at the speed of light into a static line or row of the data, then carrying the rest of the data back, feeding in another row or line or “going down”, then doing the same again.
I think for Excel formulas and VBA we should not take the core of the thinking much further than this.
For furthering the study and manipulation of static table data something else , another concept, such as Power Query / Get and Transform might be more appropriate.
Looping along columns for every row The conventional way
__For Rw = 1 To maximumRows
____For Clm = 1 To maximumColumns
_____do stuff for each Cell( Rw, Clm )
____Next Clm
__ Next Rw
This is what we have got used to, from reading books, to the workings of old printers, to how a screen is filed with data. It is an efficient and logical consequence that a spreadsheet, or a rectangular range in a spreadsheet, is filled and otherwise updated in the same way.
Usually we look at a cell when doing formula calculations, but if we increase the exposed area during a screen update, we can get an efficient, almost simultaneous, calculation across an entire range. This latter is the basis of the workings of the so called array formulas, ( “CSE” stuff ). We will come on to that in the next post
Looping the Items
Many things in VBA, and computers generally, are actually ordered somewhere by something similar to a unique item number , 1 2 3 4 5 6 … etc. ( Note: in some computer conventions the first may start at 0 so we have 0 1 2 3 4 5… etc. )
Conventionally, the Range Item numbers are also so organised, and further follow the generally accepted convention of
Across
_____<- back (Carriage Return)
Down (Line Feed)
Across
_____<- back (Carriage Return)
Down (Line Feed)
………etc.
( Conventionally in computer stream strings we may refer to those
backs as carriage returns, vbCr ,
and
the downs as line feeds, vbLf.
These may be referred to as “invisible characters”, as we do not typically see them, but they must be there in the electronic string stream to indicate the start of a new line or new row )
For example for a 2 row x 3 column range, this is where the item numbers are/ what cells the item number refers to
1 2 3 vbCr & vbLf
4 5 6
Furthermore, for many things that do not have such an item number they may have a consistent order such that we can assume or assign some simple count mechanism to give them an index that we can use in a similar way to the Item number
The crux of my suggestion in this Thread is to think of the basic process shown at the start of this Blog, in a slightly different way.
A couple of reasons I can think of for doing this
_ It may be helpful to think back to the more fundamental single string idea of what computers are, as the table type arrangement is only an interface for us, and is less representative of what is actually going on in a computer
_ In some situations the alternative looping may have some advantages. For example we would not be limited to a rectangular range. (See Post #3)
Some simple required maths
What we want to do is this sort of thing as an alternative to the basic process
__For Itm = 1 To maximumItems
___( Row, Column)
__Next Itm
Before looking at the actual solution, lets simply put in words a simple solution idea, and consider again a 2 row, 3 column range
1 2 3
4 5 6
In this case, our maximumRows will be 2 and the maximumColumns will be 3
We have those sequentially numbers, and we want to convert then to row and column indices that would give us that spreadsheet range.
Row Number from Item Number
If we were to divide the actual item number by the maximumColumns , 3 , and take the integer of the result we would almost be there. But that would actually give us
0 0 1
1 1 2
If we were to first subtract 1 from the Item number, then do the same again, divide that modified number by the maximumColumns , 3, and take the integer of the result we would have,
Integer ( ( ItmNumber -1 ) / maximumColumns ) =
0 0 0
1 1 1
So we now see that we only have to add 1 to the final results and we have the row number what we want.
RowNumber = [ Integer ( ( ItmNumber -1 ) / maximumColumns ) ] + 1
1 1 1
2 2 2
Column Number from Item Number
This is slightly more tricky. But not much. I do this second as we need some of the ideas from the previous maths.
An observation:
To get the column number from the item number, in the second row the item number needs to be reduce by 1 x maximumColumns , and
if we had a third row the item number would need to be reduced by 2 x maximumColumns, (and
for the first row, the item number needs to be reduce by nothing , so by 0 x maximumColumns ) … and so on.
Note also, that it also fits this same logic to apply a reduction of 0 x maximumColumns to the first row.
So we are looking for a multiplication factor based on the Item number which gives us that sort of number sequence like 0 0 0 ; 1 1 1 ; 2 2 2 etc. sequence
We can see from one of the stages in the maths from the last section where we determined the row from the item number, that we did actually already have it:
It was at this stage: -
__________________Integer ( ( ItmNumber -1 ) / maximumColumns )
___=___0 0 0
_______1 1 1
and that would have further gone on for more rows to
0 0 0 ; 1 1 1 ; 2 2 2 ; 3 3 3 … etc.
So we can see one formula possibility:
ItemNumber - [ Integer ( ( ItmNumber -1 ) / maximumColumns ) X maximumColumns ]
This would result in our required column Indicies of
1 2 3
1 2 3
_.______
Simple VBA macro examples
Code:
Sub ItmNumbersLoopToRng()
Dim Ws1 As Worksheet: Set Ws1 = ThisWorkbook.Worksheets("Sheet1")
Dim ItmIndx As Long
Dim maxClms As Long, maxRws As Long: Let maxClms = 3: Let maxRws = 2
For ItmIndx = 1 To 5
Dim Rw As Long, Clm As Long
Let Rw = Int((ItmIndx - 1) / maxClms) + 1
Let Clm = ItmIndx - (Int((ItmIndx - 1) / maxClms) * maxClms)
Let Ws1.Cells.Item(Rw, Clm).Value = " (" & Rw & ", " & Clm & ")"
Next ItmIndx
End Sub
Sub ItmNumbersLoopToRng2()
Dim Ws1 As Worksheet: Set Ws1 = ThisWorkbook.Worksheets("Sheet1")
Dim ItmIndx As Long
Dim maxClms As Long, maxRws As Long: Let maxClms = 3: Let maxRws = 2
For ItmIndx = 1 To 5
' Dim Rw As Long, Clm As Long
' Let Rw = Int((ItmIndx - 1) / maxClms) + 1
' Let Clm = ItmIndx - (Int((ItmIndx - 1) / maxClms) * maxClms)
Let Ws1.Cells.Item(Int((ItmIndx - 1) / maxClms) + 1, ItmIndx - (Int((ItmIndx - 1) / maxClms) * maxClms)).Value = " (" & Int((ItmIndx - 1) / maxClms) + 1 & ", " & ItmIndx - (Int((ItmIndx - 1) / maxClms) * maxClms) & ")"
Next ItmIndx
End Sub
__Result:_____
_____ Workbook: OekyDoekyAmelynn.xls ( Using Excel 2007 32 bit )
| Row\Col |
A |
B |
C |
D |
1 |
(1, 1) |
(1, 2) |
(1, 3) |
|
2 |
(2, 1) |
(2, 2) |
|
|
3 |
|
|
|
|
Worksheet: Sheet1
_.____
Item way of thinking as alternative to conventional row column looping.
This is post
https://www.excelfox.com/forum/showt...ll=1#post16457
https://www.excelfox.com/forum/showt...ping#post16457
There is one interesting observation already that may help us understand some of the secret workings of Excel:
Note that we have not needed to use the parameter of maximumRows
Now, Consider a range object of 3 columns x 2 rows anywhere in a spreadsheet
x x x vbCr & vbLf
x x x
Reasonably we would say that has 6 items, and conventionally we have, and we could confirm by experiment, that we have item 6 as shown here, X:
x x x vbCr & vbLf
x x X
What is somewhat surprising perhaps, is that we can go on to reference any further item without causing any errors, and we remain in the maximum columns restriction but seem to have no limit, ( within reason ), in the rows.
For example, referring to item 12, would get us here X:
x x x vbCr & vbLf
x x x vbCr & vbLf
x x x vbCr & vbLf
x x X
This could be by design, or might just be an accident due to some internal calculations having a similar form to those I have suggested and discussed, - those that do not have any consideration of maximum row
I intend adding some further post on this thread later to discuss the ideas and develop them further.
https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA
https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgwTUdEgR4bdt6crKXF4AaABAg. 9xmkXGSciKJ9xonTti2sIx
https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgwWw16qBFX39JCRRm54AaABAg. 9xnskBhPnmb9xoq3mGxu_b
https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgzgWvzV-kvC4TJ8O414AaABAg.9xnFzCj8HRM9xon1p2ImxO
https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgybZfNJd3l4FokX3cV4AaABAg. 9xm_ufqOILb9xooIlv5PLY
https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgzgWvzV-kvC4TJ8O414AaABAg.9xnFzCj8HRM9y38bzbSqaG
https://www.youtube.com/watch?v=XQAIYCT4f8Q&lc=UgyWm8nL7syjhiHtpBF4AaABAg. 9xmt8i0IsEr9y3FT9Y9FeM
https://www.youtube.com/watch?v=jTmVtPHtiTg&lc=Ugy_RiNN_kAqUvZ8W994AaABAg. 9xhyRrsUUOM9xpn-GDkL3o
https://www.youtube.com/watch?v=jTmVtPHtiTg&lc=Ugy_RiNN_kAqUvZ8W994AaABAg
https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgNsaS3Lp1
https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgR1EPUkhw
https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgNe_XC-jK
https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgNPOdiDuv
https://www.youtube.com/watch?v=QjEWAJ3d-jw&lc=UgxJLVpwY8fIla7G-pN4AaABAg.9BLeCWVhxdG9wgN7AC7wAc
https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA
https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA
https://eileenslounge.com/viewtopic.php?p=316254#p316254
https://eileenslounge.com/viewtopic.php?p=316280#p316280
https://eileenslounge.com/viewtopic.php?p=315915#p315915
https://eileenslounge.com/viewtopic.php?p=315512#p315512
https://eileenslounge.com/viewtopic.php?p=315744#p315744
https://www.eileenslounge.com/viewtopic.php?p=315512#p315512
https://eileenslounge.com/viewtopic.php?p=315680#p315680
https://eileenslounge.com/viewtopic.php?p=315743#p315743
https://www.eileenslounge.com/viewtopic.php?p=315326#p315326
https://www.eileenslounge.com/viewtopic.php?f=30&t=40752
https://eileenslounge.com/viewtopic.php?p=314950#p314950
https://www.eileenslounge.com/viewtopic.php?p=314940#p314940
https://www.eileenslounge.com/viewtopic.php?p=314926#p314926
https://www.eileenslounge.com/viewtopic.php?p=314920#p314920
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=314837#p314837
https://www.eileenslounge.com/viewtopic.php?f=21&t=40701&p=314836#p314836
https://www.eileenslounge.com/viewtopic.php?f=27&t=40621&p=314621#p314621
https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA