Hi RickXL
.......I think it is reusing space if it can. I tried this:
.......If you run the code repeatedly, you can see that sometimes the same address is re-used. When it becomes free, because the Sub has completed, the address becomes available for re-use. So it is still making a copy but it may sometimes put it in the same place.
Running repeatedly shows that the addresses can be re-used for different things for different runs.
Thanks for the extra input.
Having slept on it i see my first conclusion
_1a) Is this telling me..
_1a)(i) I can only make 1 copy ?
Was stupid , maybe..- i was missing the point again about the StrPtr(x) address – just because that is the same does not mean VBA is not making another copy – it is simply using the same address.
But this one seems very complicated. You are getting different results to me. But this may be explained by:
“sometimes”. You used this word
“sometimes” as well, in a slightly different context. The word seems to need to be extended to cover the same code working on a different run, different computer etc. etc....
_ ....But this could also be covered by your “..
.Running repeatedly shows that the addresses can be re-used for different things for different runs….“
Just a quick demo in that: your code from Post #12 and your results and mine:
Code:
[color=blue]Sub[/color] TestByValByRefStr_Post12() [color=darkgreen]' RickXL Post # 12[/color]
10 [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]String[/color]
20 [color=blue]Let[/color] x = "qwer"
30 Debug.Print StrPtr(x) [color=darkgreen]'Address: Rick 479669860[/color] [color=red]; Alan 367477188[/color] [color=orange]; 118892172 [/color] [COLOR="#800080"]160373356[/COLOR]
40 [color=blue]Call[/color] mySubByVal(x) [color=darkgreen]'Address: Rick 535500540[/color] [color=red]; Alan 367478508[/color] [color=orange]; 118890516 [/color] [COLOR="#800080"]160373396[/COLOR]
50 [color=blue]Call[/color] mySubByVal(x) [color=darkgreen]'Address: Rick 476610300[/color] [color=red]; Alan 367478508[/color] [color=orange]; 118890516 [/color] [COLOR="#800080"]160373396[/COLOR]
60 [color=blue]Call[/color] mySubByRef(x) [color=darkgreen]'Address: Rick 479669860[/color] [color=red]; Alan 367477188[/color] [color=orange]; 118892172 [/color] [COLOR="#800080"]160373356[/COLOR]
65 x = "111111"
70 [color=blue]Call[/color] mySubByVal(x) [color=darkgreen]'Address: Rick 625821292[/color] [color=red]; Alan 367477188[/color] [color=orange]; 118890124 [/color] [COLOR="#800080"]160373436[/COLOR]
75 [color=blue]Call[/color] mySubByVal(x) [color=darkgreen]'Address: Rick 625752244[/color] [color=red]; Alan 367477188[/color] [color=orange]; 118890124 [/color] 1[COLOR="#800080"]60373436[/COLOR]
80 Debug.Print StrPtr(x) [color=darkgreen]'Address: Rick 479669860[/color] [color=red]; Alan 367478468[/color] [color=orange]; 118892172 [/color] [COLOR="#800080"]160373356[/COLOR]
[color=blue]End[/color] [color=blue]Sub[/color]
[color=blue]Sub[/color] my[color=blue]Sub[/color]ByRef(ByRef c [color=blue]As[/color] [color=blue]String[/color])
Debug.Print StrPtr(c)
c = "22"
[color=blue]End[/color] Sub
Sub mySubByVal(ByVal c [color=blue]As[/color] [color=blue]String[/color])
Debug.Print StrPtr(c)
c = "22"
[color=blue]End[/color] Sub
Your results ; Mine XL2007 ; Mine XL2003 ; Mine XL 2010
( My different versions are on different computers. )
I get different results to you. The main difference being that the results are suggesting that my StrPtr(x) , that is to say the initial pointer address is in fact changing sometimes! This allows then the copy by a following
ByVal call to use this address, which it sometimes does!
It looks like this one is virtually impossible to answer fully as clearly VBA is too inconsistent!
Note for example my first XL 2007 results.. the last result appeared to say that the StrPtr(x) address had changed. As I write I am looking at the results of this first run in my Immediate Window ( Ctrl G ). They are still there!! But repeating again my XL 2007 results then go on to tie up with my XL 2003 and XL 2010 results.
It would appear in order to be completely certain one must experiment using the specific version / computer one is using and specific code.
Passing on codes of this nature could clearly be very problematic!!
Even doing a
Debug.Print appeared effect whether my StrPtr(x) , that is to say the initial pointer address is changed or not!!! Clearly there lies madness down the road of trying to figure out exactly what is going on in VBA here
Maybe these inconsistencies have been cleared up, or there is a change now since XL 2013 ( which you are using.....) Or maybe you have somehow a different computer / memory that is somehow allowing your StrPtr(x) , that is to say the initial pointer address, to remain constant.
The only consistent statements I seem to be able to say is:
The StrPtr(x) , that is to say the initial pointer address, assigned to a string variable itself can change. Clearly that appears to be happening by me
If that happens, the original address is “free” and often seems to be used by a following, or following, ByVal Call, or Calls
A whole multiple number of things can effect this,
_... even just testing for it that is to say doing the
Debug.Print StrPtr(x) !!!!! Clearly this puts a question on the validity of using StrPtr(x) to get at the address – you may
Either:
_a).. change it as you try to determine what it is!!
( I see a parallel to the UsedRange phenomenon where the UsedRange Register is updated when for example you do a UsedRange.Rows
VBA .SpecialCells(xlCellTypeBlanks) – Only works on UsedRange? (Regardless of specified ra
)
If this is occurring, my experiments suggest it is occurring within the called ByRef Sub Procedure with a change in c ( that is to say x in c ) , mySubByRefcChange(x), but i expect the ther next explanation is the more likely
or
_b)..In the Sub routines that are called the actual change in StrPtr(x) occurs on leaving the Sub Procedure. Hence the
Debug.Print within those Sub procedures will not catch those changes. A debug.Print immediately after will display the change
Further I would note that when reading up on getting Addresses of Variables in Visual Basic you often see disclaimers saying words to the effect “ take it as it is... no guarantees..!!...”
I note finally, that it is your
c=”22” ( in the Sub mySubByRef() )
Or
X=”111111” in the main program
That puts the spanner in the works for me and results in my StrPtr(x) possibly changing.
If i comment these out, then, as yet my StrPtr(x) remains constant. Maybe this makes some sense: For some reason my system needs to, or chooses to, change StrPtr(x) to accommodate the new string. It would appear not to be the case in your system or Excel Version.
( Note: c=”22” in the Sub mySubByVal() has no effected on StrPtr(x) – as expected, I think, as it is making no reference to x in the
Call ByVal . However it can change the address given for the copy. )
The following is an attempt to summarise all the above Points:
Codes:
Code:
[color=darkgreen]'[/color]
[color=blue]Sub[/color] TestByValByRefStrWonky() '
10 [color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]String[/color] [color=darkgreen]'I am using this as a "pseudo" Global Variable. That is to say it has assigned a Pigeon Hole containing the Address where the String would be[/color]
11 [color=darkgreen]' "get the Address of variable".. maybe.... https://support.microsoft.com/en-us/kb/199824[/color]
12 Debug.Print " 12 Address main program-------StrPtr(x) " & StrPtr(x) [color=darkgreen]'I expect no Address yet[/color]
13 [color=blue]Let[/color] x = "qwer"
14 Debug.Print " 14 Address main program-------StrPtr(x) " & StrPtr(x) [color=darkgreen]' Bet it has an address now[/color]
15 [color=blue]Let[/color] x = ""
16 Debug.Print " 16 Address main program-------StrPtr(x) " & StrPtr(x) [color=darkgreen]' Might have another address now[/color]
17 [color=blue]Let[/color] x = vbNullString
18 Debug.Print " 18 Address main program-------StrPtr(x) " & StrPtr(x) [color=darkgreen]' Suspect it has no address again[/color]
20 [color=blue]Let[/color] x = "qwer"
30 Debug.Print " 30 Address main program-------StrPtr(x) " & StrPtr(x) [color=darkgreen]' Might have another address now, or the very first one as it is available[/color]
40 Debug.Print " 40 ";: [color=blue]Call[/color] mySubByVal(x) [color=darkgreen]'[/color]
50 Debug.Print " 50 ";: [color=blue]Call[/color] mySubByVal(x)
60 Debug.Print " 60 ";: [color=blue]Call[/color] mySubByValcChange(x)
70 Debug.Print " 70 ";: [color=blue]Call[/color] mySubByValcChange(x)
80 Debug.Print " 80 ";: [color=blue]Call[/color] mySubByVal(x)
90 Debug.Print " 90 Address main program-------StrPtr(x) " & StrPtr(x)
100 Debug.Print "100 Address main program------StrPtr(x) " & StrPtr(x)
110 Debug.Print "110 ";: [color=blue]Call[/color] mySubByRef(x)
120 Debug.Print "120 Address main program------StrPtr(x) " & StrPtr(x)
130 Debug.Print "130 ";: [color=blue]Call[/color] mySubByRefcChange(x)
140 Debug.Print "140 ";: [color=blue]Call[/color] mySubByRefcChange(x)
150 Debug.Print "150 Address main program------StrPtr(x) " & StrPtr(x)
160 Debug.Print "160 Address main program------StrPtr(x) " & StrPtr(x)
170 Debug.Print "170 ";: [color=blue]Call[/color] mySubByRefcChange(x)
180 Debug.Print "180 Address main program------StrPtr(x) " & StrPtr(x)
190 Debug.Print "190 Address main program------StrPtr(x) " & StrPtr(x)
200 Debug.Print "200 ";: [color=blue]Call[/color] mySubByRefcChange(x)
210 Debug.Print "210 ";: [color=blue]Call[/color] mySubByVal(x)
220 Debug.Print "220 Address main program------StrPtr(x) " & StrPtr(x)
230 Debug.Print "230 Address main program------StrPtr(x) " & StrPtr(x)
240 Debug.Print "240 ";: [color=blue]Call[/color] mySubByVal(x)
250 Debug.Print "250 ";: [color=blue]Call[/color] mySubByVal(x)
260 Debug.Print "260 ";: [color=blue]Call[/color] mySubByValcChange(x)
270 Debug.Print "270 ";: [color=blue]Call[/color] mySubByValcChange(x)
280 Debug.Print "280 ";: [color=blue]Call[/color] mySubByVal(x)
290
300 Debug.Print "300 ";: [color=blue]Call[/color] mySubByRef(x)
310 Debug.Print "310 Address main program------StrPtr(x) " & StrPtr(x)
320 Debug.Print "320 letting x = 111111": [color=blue]Let[/color] x = "111111"
330 Debug.Print "330 Address main program------StrPtr(x) " & StrPtr(x)
340 Debug.Print "340 ";: [color=blue]Call[/color] mySubByRef(x)
350 Debug.Print "350 Address main program------StrPtr(x) " & StrPtr(x)
360 Debug.Print "360 ";: [color=blue]Call[/color] mySubByRefcChange(x)
370 Debug.Print "370 Address main program------StrPtr(x) " & StrPtr(x)
[color=blue]End[/color] [color=blue]Sub[/color]
[color=darkgreen]'[/color]
'
[color=blue]Sub[/color] mySubByRef(ByRef c [color=blue]As[/color] [color=blue]String[/color])
Debug.Print "Address my[color=blue]Sub[/color]ByRef--------StrPtr(c) " & StrPtr(c)
[color=blue]End[/color] [color=blue]Sub[/color]
[color=darkgreen]'[/color]
Sub my[color=blue]Sub[/color]ByRefcChange(ByRef c [color=blue]As[/color] [color=blue]String[/color])
Debug.Print "Address my[color=blue]Sub[/color]ByRefcChange StrPtr(c) " & StrPtr(c)
c = "22"
[color=blue]End[/color] Sub
[color=darkgreen]'[/color]
[color=blue]Sub[/color] my[color=blue]Sub[/color]ByVal(ByVal c [color=blue]As[/color] [color=blue]String[/color])
Debug.Print "Address mySubByVal--------StrPtr(c) " & StrPtr(c)
[color=blue]End[/color] [color=blue]Sub[/color]
[color=darkgreen]'[/color]
Sub mySubByValcChange(ByVal c [color=blue]As[/color] [color=blue]String[/color])
Debug.Print "Address mySubByValcChange StrPtr(c) " & StrPtr(c)
c = "22"
[color=blue]End[/color] Sub
12 Address main program-------StrPtr(x) 0 – from
Dim x As
String – No Address in Pigeon Hole
14 Address main program-------StrPtr(x) 367399700 – from
Let x = "qwer" – First Available Address given
16 Address main program-------StrPtr(x) 367395380 – from
Let x = "" - In my system a different Address given
18 Address main program-------StrPtr(x) 0 – from
Let x = vbNullString – Back to no address
30 Address main program-------StrPtr(x) 367399700 – from
Let x = "qwer" – back to an Address. ( The first is available so is used again)
40 Address mySubByVal--------StrPtr(c) 367395380 – from
Call mySubByVal(x) – Chooses next available address for copy of x
50 Address mySubByVal--------StrPtr(c) 367398900 – from same
Call mySubByVal(x) – My system chooses a new adresss, sometimes..
60 Address mySubByValcChange StrPtr(c) 367395380 – from
Call mySubByValcChange(x) – data length has changes, my system has chosen to choose a new address..
70 Address mySubByValcChange StrPtr(c) 367395380 – from same
Call mySubByValcChange(x) – my system has “settled down”, uses the same address this time for another copy.
80 Address mySubByVal--------StrPtr(c) 367395380 – from slightly different
Call mySubByVal(x) – but my system stays calm and uses same address again for another copy.
90 Address main program-------StrPtr(x) 367399700 – from main program StrPtr(x) – Still using original address for “pseudo” global x
100 Address main program------StrPtr(x) 367399700 – from same main prog StrPtr(x) – no need to change x address, - has not changed
110 Address mySubByRef--------StrPtr(c) 367399700 – from
Call mySubByRef(x) – I expect no change to x address caused by this as nothing is done to x which is taken in
by Ref
120 Address main program------StrPtr(x) 367399700 - – from same main prog StrPtr(x) – just checking that no address change in x
130 Address mySubByRefcChange StrPtr(c) 367399700 – from
Call mySubByRefcChange(x) – I actually expect x address has changed, but change occurred on leaving mySubByRefcChange(x) so the
Debug.Print in it did not display it
140 Address mySubByRefcChange StrPtr(c) 367394820 - from same
Call mySubByRefcChange(x) – i actually expect a change once again, but now the
Debug.Print in from mySubByRefcChange(x) displays that from line 130.
150 Address main program------StrPtr(x) 367398900 – from main program StrPtr(x) – confirming now the change caused by Line 140
160 Address main program------StrPtr(x) 367398900 – from main program StrPtr(x) – just checking that
Debug.Print does not change the address of x
170 Address mySubByRefcChange StrPtr(c) 367398900 - I expect a change again not shown by the
Debug.Print in the mySubByRefcChange(x)
180 Address main program------StrPtr(x) 367399700 - from main program StrPtr(x) - change confirmed.
190 Address main program------StrPtr(x) 367399700 – no reason for change
200 Address mySubByRefcChange StrPtr(c) 367399700 - I expect a change again not shown by the
Debug.Print in the mySubByRefcChange(x)
210 Address mySubByVal--------StrPtr(c) 367399700 – from
Call mySubByVal(x) – At this poinjt my System has got a bit excited by all that has gone on with addresses and so by this call ByVal ( Copy Call ) it has looked for a new address. The reason it appears to have that of the last address of x is because actually the address of x has changed on leaving the last
ByRef Call Sub. Threrefore the last address used for x is available now.
220 Address main program------StrPtr(x) 367394820 – from main program StrPtr(x) – confirming now the change caused by Line 200
230 Address main program------StrPtr(x) 367394820 - – no reason for change
240 Address mySubByVal--------StrPtr(c) 367395380 – in Lines 240 to .....
250 Address mySubByVal--------StrPtr(c) 367399700 - .....280, my system....
260 Address mySubByValcChange StrPtr(c) 367395380 - ... sometimes changes the....
270 Address mySubByValcChange StrPtr(c) 367395380 – address for the copy, but....
280 Address mySubByVal--------StrPtr(c) 367395380 – eventually settles down!!
300 Address mySubByRef--------StrPtr(c) 367394820 – from
Call mySubByRef(x) which does not change c ( and so does not change x that is in c ) , I expect the address of x may not be changed...
310 Address main program------StrPtr(x) 367394820 – from main program StrPtr(x) - confirmed no change
320
letting x = 111111 – I expect this will change the address of x
330 Address main program------StrPtr(x) 367399700 - from main program StrPtr(x) - change confirmed
340 Address mySubByRef--------StrPtr(c) 367399700 - from
Call mySubByRef(x) which does not change c ( and so does not change x that is in c ) , I expect the address of x may not be changed...
350 Address main program------StrPtr(x) 367399700 – from main program StrPtr(x) - confirmed no change
360 Address mySubByRefcChange StrPtr(c) 367399700 - from
Call mySubByRefcChange(x) – I actually expect x address has changed, but change occurred on leaving mySubByRefcChange(x) so the
Debug.Print in it did not display it
370 Address main program------StrPtr(x) 367478788 - from main program StrPtr(x) - change confirmed.
_ ...................................
_ ...I am not necessarily expecting anyone to wade through all the above, not immediately at least , but for future reference it may be useful...
_.... I may ask for some help in getting some results from my code from other users with other Excel versions and other computers, than i may think again and try to make a more concise, clear summary....in a day or two... when i have slept on it a few days!!!!
Alan
_...............................................
Last Quick EDIT: Actually the Debug.Print in mySubByRefcChange will give the right results, I just need to move it after the
c = "22"
which causes the Address in the Pigeon Hole to change