How do I store a formula in VBA as a Variable to be pasted out so that it works as if i had typed it in correctly by hand
Hallo,
_ I think this is good follow up and good reference Post for later based on the Thread Title and content so far....
_ maybe the following is documented and many people know the following but I struggled to find it and hit on it by chance through experimenting, so am sharing ..
_ Briefly again the basic idea is / was
_ 1) to build up an Array of formula ( “Strings” ) to be Pasted out to the spreadsheet in one go
_ 2) Range references may be known by sheet Name and the Row and Column Indicies as whole numbers.
_ 2a) At the outset to hopefully avoid confusion my Dimensioned ( as Long ) Numbers for any row will be r or j and any column will be c or i and I hope this does not confuse with R and C which somehow VBA seems to recognise as a Row and Column reference.......
_ I am basically trying to put into simple words how to put a formula into a cell, possibly storing it in the meantime in A Variable or Array element. Sounds simple. What i have found by experimenting I could not clearly in English find spelt out anywhere!!? Maybe I hit on it coincidentally as i have the added confusion of my formulas all looking different than the English versions ( I have German Excel )
_ As simple example some Input sheet captured in a “One Liner”
50
Dim arrIn()
As Variant: arrIn() = wsIn.UsedRange.Value
( Complete code here:
Excel Help Forum
.. which i will update and correct )
And again at the end of this Post
Using Excel 2007
- | A | B | C |
1 | 6 | 1 | |
2 | 7 | 2 | |
3 | A String | 3 | C3Value |
_ An Internal Array arbitrarily dimensioned as 6 x 6
60
Dim arrOut()
As Variant:
ReDim arrOut(1 To 6, 1 To 6)
will be used to store output values and formulas created internally,
_ A simple manually entered formula in Output sheet to link cell Output Sheet C1 to Input sheet B1 looks like this
=Input!B1 ( In
English or German )
If I put that in my Output Array, then I get it in my Output Array !
arrOut(1, 3) = "=Input!B1": Debug.Print arrOut(1, 3) '
Returns =Input!B1 ( held in Array As String )
If my code pastes that out to the Output Sheet
VBA “interferers and i get this outputted,
=Input!'B1' which
Excel errors ?!?
( In passing, If I manually type into Output Sheet C1 =Input!R1C2 excel errors also as expected, )
The crux of the first few posts in this Thread showed various ways to construct that last expression into
arrOut(1, 3) = "=Input!R1C3": Debug.Print arrOut(1, 3)
' Returns =Input!R1C2 ( held in Array As String )
If my code pastes that out to the Output Sheet
VBA “interferers" at the pasting stage and i get this outputted
=Input!$C$1 which Works!
So then I wrote lines 130 to 170 do something similar to bring in numbers 1 2 and 3 from Input Sheet into my Output Sheet
So far, ( almost ) so good, ( Just the weird VBA interfering To give =Input!'B1'
_ .............
Lets take it a bit further for Putting a formula in the output sheet say to sum those brought over values 1 2 and 3 .
Manually typed in by me (
German ) as
=SUMME(C1:C3)
By you ( maybe, if you are
English or similar ) typed in as in the complete screen shots
Formulas:
Using Excel 2007
- | C | D | E |
1 | =Input!$B$1 | =Input!$B$1 | |
2 | =Input!$B$2 | =Input!$B$2 | |
3 | =Input!$B$3 | =Input!$B$3 | |
4 | =SUM($C$1:$C$3) | =SUM($D$1:$D$3) | |
5 | | | |
Values:
Using Excel 2007
- | C | D | E |
1 | 1 | 1 | |
2 | 2 | 2 | |
3 | 3 | 3 | |
4 | 6 | 6 | |
5 | | | |
No problem with manually entered.
However, On pasting out Strings (
seen to be by Debug.Print excactly those formulas )
using my code Line 200 ,
VBA Interferers Giving me
=SUMME($A:$C) which errors!
Clearly the letter C tells
VBA to do something on pasting a string into a cell if it starts with
= , which seems fundamentally to be the indication for
VBA that a formula is in play, ( not the .Formula , which as discussed in this Thread earlier seems to have little effect.... and reacts the same as .Value )
The above example was unfortunate perhaps in choosing column C as C means something special when
VBA “interferres” at the pasting stage.
Repeating the experiment for column D and formula =SUMME(D1:D3), pasting out,
VBA “Interferers” Giving me
=SUMME('D1':'D3') which errors also!
So my guess for success was getting
VBA to
interfere in a “
positive way” , that is to say trying...
arrOut(4, 4) = "=SUMME(R1C4:R3C4)” and arrOut(4, 3) = "=SUMME(R1C3:R3C3)"
it almost worked . I get the correct (
German ) Formulas pasted into the cells as
=SUMME($D$1:$D$3) and =SUMME($C$1:$C$3)
Initially they errored. On selecting the Formula bar and hitting enter, they worked. Weird ?!?
A shot in the dark was to use the
English Formulas in my code as i know they error in my
Excel if i type them in manually . .....
arrOut(4, 4) = "=SUM(R1C4:R3C4)” and arrOut(4, 3) = "=SUM(R1C3:R3C3)"
As before I get exactly that String stored in my Array. So obviously no chance of it working.
Or so I thought. Ha! VBA now “
interferes” at the pasting stage and not only turns it into the correct ( German ) Language form, but it also works without that last Weird requirement of selecting the Formula bar and hitting Enter. (
So i have invented how to get VBA to put a formula in a cell. useful. )
_...............................................................................
My Point and conclusions here is that in the building of my formulas in
VBA:
_ 1 ) the R C within a string plays an important role causing VBA and or Excel to interfere at the Pasting stage with what is actually pasted in, that is to say it is converted to the correct cell reference.
_ 2 ) using an English Formula causes
VBA and or
Excel to
interfere with what is actually pasted in, that is to say give the correct formula for the version of language version of
Excel in use
_ 3) maybe something else ? ! ? to do with the strange
‘ which i do not know yet.
_ 4) The first “
=” is what seems to start
VBA and or
Excel to
interfere in what is actually pasted in the cell, the relevance of .FormulaR1C1 as opposed to .Value appears lost and Redundant
( _ 5) A last strange bit: In general all the formulas can be stored in Variant type Variables ( as strings ) or in String Type Variables as Strings. Even for the case of Arrays of more than one Element. Then pasting out one formula at a time will work.
But for some strange reason if pasting out a Multidimensional Array to a Spreadsheet range in one go then the Array must be dimensioned as Variant ( see lines 450 – 500 ) For some reason VBA “ interferers” a bit differently in the one Liner Output assignment of a data field of size )
My final conclusion.
Question:
How do I write or store a formula in VBA as a Variable to be pasted out so that it works as if I had typed it in correctly by hand
Answer:
In general:
The Formula must be written exactly as it would be written in the Cell ( including the = at the start ) using the
English version of the Formula.
Then either:
Pasted directly out to the Sheet
Or
Stored as a String in a String or Variant Type variable or as a String in a Variant or String type / types Element / Elements of an Array and pasted out line by line.
Or
If intended to store more than one Element In an Array and paste out all values at once in a one Liner assignment then the Array Elements must be Dimensioned as errors initially but on hitting Enter Returns correct working formula Variant ( Even if only one element is a Formula )
I am a novice and i would very much appreciate any Profi Comments ( or insults ) to my conclusions.. I am particularly worried that i may be relying on some strange Implicit ( what i am referring to as
VBA or
Excel “
interfering” ) which might bite me in the A_s_ sometime later
Many Thanks for watching
Alan
Code:
Rich (BB code):
Sub LinkAndFormulaInArrayForOutputToRange() ' http://www.mrexcel.com/forum/excel-questions/887822-formula-link-cell-array-instead-cell-value-based-cell-r-c-co-ordinates.html
10 'Some Workshhet Info
20 Dim wsIn As Worksheet, wsOut As Worksheet
30 Set wsIn = ThisWorkbook.Worksheets("Input"): Set wsOut = ThisWorkbook.Worksheets("Output")
40 Dim arrIn() As Variant:
50 Let arrIn() = wsIn.UsedRange.Value
60 Dim arrOut() As Variant: ReDim arrOut(1 To 6, 1 To 6) 'Will not work if Dimensioned as String - see lines 450 - 500
70 wsOut.Range("A1:F6").Clear 'Get rid of everything including any strange formatting
80
90 'Input some arbritrary "row" Value from Input Array into Output Array by pasting in appropriate link.
100 Dim r As Long: 'The r and x value would be found by some criteria, looping, search, etc. in an actual File
110 Dim x As Long: Let x = 2
120 Let arrOut(1, 3) = "=Input!B1": Debug.Print arrOut(1, 3) ' Returns =Input!B1 ( held in Array As String ) Pastes out =Input!'B1' which errors
130 Let arrOut(1, 3) = "=Input!R1C2": Debug.Print arrOut(1, 3) ' Returns =Input!R1C3 ( held in Array As String ) Pastes out =Input!$C$1 which Works
140 For r = 1 To 3 Step 1
150 Let arrOut(r, 3) = "=" & wsIn.Name & "!R" & r & "C" & x & "": Debug.Print arrOut(r, 3)
160 Let arrOut(r, 4) = "=" & wsIn.Name & "!R" & r & "C" & x & "": Debug.Print arrOut(r, 3)
170 Next r
180 '
190 'Non Working Formulas
200 Let arrOut(4, 3) = "=SUMME(C1:C3)": Debug.Print arrOut(4, 3) ' Returns =SUMME(C1:C3) ( held in Array As String ) Pastes out =SUMME($A:$C) which errors
210 Let arrOut(4, 4) = "=SUMME(D1:D3)": Debug.Print arrOut(4, 4) ' Returns =SUMME(D1:D3) ( held in Array As String ) Pastes out =SUMME('D1':'D3') which errors
220 Let wsOut.Range("a1").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).Value = arrOut() 'Errors
230 Let arrOut(4, 4) = "=SUMME(R1C4:R3C4)": Debug.Print arrOut(4, 4) ' Returns =SUMME(R1C4:R3C4) ( held in Array As String ) Pastes out =SUMME($D$1:$D$3) which errors initially but on hitting Enter Returns correct working formula
240 Let arrOut(4, 3) = "=SUMME(R1C3:R3C3)": Debug.Print arrOut(4, 3) ' Returns =SUMME(R1C3:R3C3) ( held in Array As String ) Pastes out =SUMME($C$1:$C$3) which errors initially but on hitting Enter Returns correct working formula
250
260 Let wsOut.Range("a1").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).Value = arrOut() 'errors initially but on hitting Enter Returns correct working formula
270 Let wsOut.Range("a1").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).FormulaR1C1 = arrOut() 'errors initially but on hitting Enter Returns correct working formula
280 'wsOut.Range("C4").FormulaR1C1 = wsOut.Range("C4").Value: wsOut.Range("D4").Select: wsOut.Range("C4").Select: 'All this does not help
290
300 'Working Formulas Use R and C for cell referrences and English Formulas
310 Let arrOut(4, 4) = "=SUM(R1C4:R3C4)": Debug.Print arrOut(4, 4) ' Returns =SUM(R1C4:R3C4) ( held in Array As String ) Pastes out =SUMME($D$1:$D$3) which Works!
320 Let arrOut(4, 3) = "=SUM(R1C3:R3C3)": Debug.Print arrOut(4, 3) ' Returns =SUM(R1C3:R3C3) ( held in Array As String ) Pastes out =SUMME($C$1:$C$3) which Works!
330
340
350 Let wsOut.Range("a1").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).Value = arrOut()
360 Let wsOut.Range("a1").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).FormulaR1C1 = arrOut()
370
380 'Alternatives: Direct Output or String Variables or Single Element Arrays Variables
390 Let wsOut.Range("D4").Value = "=SUM(R1C4:R3C4)" ' Works
400 Let wsOut.Range("D4").Value = "=SUMME(R1C4:R3C4)" ' errors initially but on hitting Enter Returns correct working formula
410 Dim strFormulaD4 As String: Let strFormulaD4 = "=SUM(R1C4:R3C4)": Let wsOut.Range("D4").Value = strFormulaD4 'Works
420 Let strFormulaD4 = "=SUMME(R1C4:R3C4)": Let wsOut.Range("D4").Value = strFormulaD4 ' errors initially but on hitting Enter Returns correct working formula
430 Dim strLinkD3(0) As String: Let strLinkD3(0) = "=Input!R3C2": Let wsOut.Range("D3").Value = strLinkD3(0) 'Works
440 Dim strArrayFormulaD4(0) As String: Let strArrayFormulaD4(0) = "=SUM(R1C4:R3C4)": Let wsOut.Range("D4").Value = strArrayFormulaD4(0) 'Works
445
447 'Demo to show that For pasting out of more than one Element / Formula at a time , The Array must be Variant Type
450 Dim strarrOut2(1 To 2, 1 To 1) As String
460 Let strarrOut2(1, 1) = "=Input!R3C2": Let strarrOut2(2, 1) = "=SUM(R1C4:R3C4)"
465 Let wsOut.Range("D3").Value = strarrOut2(1, 1) 'Works
467 Let wsOut.Range("D4").Value = strarrOut2(2, 1) 'Works
470 Let wsOut.Range("D3:D4").Value = strarrOut2() 'Does not work. Outputs Text of Link and Formula
473 Let wsOut.Range("D3:D4").Formula = strarrOut2() 'Does not work. Outputs Text of Link and Formula
475 Let wsOut.Range("D3:D4").FormulaR1C1 = strarrOut2() 'Does not work. Outputs Text of Link and Formula
476 Let strarrOut2(1, 1) = 3: Let strarrOut2(2, 1) = "=SUM(R1C4:R3C4)"
478 Let wsOut.Range("D3:D4").FormulaR1C1 = strarrOut2() 'Does not work. Outputs 3 and Text of Formula
479
480 Dim vararrOut2(1 To 2, 1 To 1) As Variant
490 Let vararrOut2(1, 1) = "=Input!R3C2": Let vararrOut2(2, 1) = "=SUM(R1C4:R3C4)"
500 Let wsOut.Range("D3:D4").Value = vararrOut2() 'Works
End Sub