how to convert formula into text? - vba

I have cells(1,1)="=add(a,b)". I want modify this text and place it into some VBA variable string and NOT the result of calculation. In other words, I want to be able to see in some VBA variable the text = "=add(a,b)".

Use .Formula
Sub Foo()
Dim FormText as String
FormText = ActiveSheet.Cells(1,1).Formula
Debug.Print FormText
End Sub

Related

Getting text from header columns

I have an MS Word document with a three-column header like in the screenshot below.
Please advise a VBA macro to get the text in each of the columns (in my case "foo", "bar" and "baz").
So far I have tried
Sub Test()
MsgBox Documents(1).Sections(1).Headers(wdHeaderFooterPrimary).Range.Text
End Sub
enter code here
, but it returns text with zeros ("foo0bar0baz"), which seems not to be suitable to break this text in general case, when the column texts themselves can contain zeros (e.g. "foo0", "0bar00" and "0baz").
You use the Split function to create an array of the text. You will need to know what character has been used to separate the columns. It will probably be either a normal tab or an alignment tab.
For a normal tab:
Sub SplitHeader()
Dim colHeads As Variant
colHeads = Split(ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text, vbTab)
Debug.Print colHeads(0)
Debug.Print colHeads(1)
Debug.Print colHeads(2)
End Sub
For an alignment tab:
Sub SplitHeader()
Dim colHeads As Variant
colHeads = Split(ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text, Chr(48))
End Sub

Insert Array formula in Excel VBA

I recorded the array formula in order to put in VBA. Here is what I have after the recording. However, when I run the Macro, it just doesn't work.
Will it be because of the negative sign?
From Macro
Range("D3").FormulaArray = "=IFERROR(INDEX('RMS
Maint'!R1C[-2]:R3542C[-2],SMALL(IF(('RMS Maint'!R2C27:R3542C27=R1C2)*('RMS
Maint'!R2C13:R3542C13=R2C4)*('RMS Maint'!R2C21:R3542C21=""Late"")*ROW('RMS
Maint'!R2C1:R3542C1)=0,"""",('RMS Maint'!R2C27:R3542C27=R1C2)*('RMS
Maint'!R2C13:R3542C13=R2C4)*('RMS Maint'!R2C21:R3542C21=""Late"")*ROW('RMS
Maint'!R2C1:R3542C1)),ROW('RMS Maint'!R[-2]:R[3538])),1),"""")"
From Excel formula
=IFERROR(INDEX('RMS Maint'!C$1:C$3542,SMALL(IF(('RMS
Maint'!$AA$2:$AA$3542=$B$1)*('RMS Maint'!$M$2:$M$3542=$D$2)*('RMS
Maint'!$U$2:$U$3542="Late")*ROW('RMS Maint'!$A$2:$A$3542)=0,"",('RMS
Maint'!$AA$2:$AA$3542=$B$1)*('RMS Maint'!$M$2:$M$3542=$D$2)*('RMS
Maint'!$U$2:$U$3542="Late")*ROW('RMS Maint'!$A$2:$A$3542)),ROW('RMS
Maint'!1:3541)),1),"")
The error is 1004 - Unable to set the FormulaArray property of the Range class
I'm sorry for the code format. It looked terrible.
Or you may break the long formula into few parts and replace it in the end with the actual formula like below...
Dim LogicalTest As String, FalseValue As String
LogicalTest = "('RMS Maint'!$AA$2:$AA$3542=$B$1)*('RMS Maint'!$M$2:$M$3542=$D$2)*('RMS Maint'!$U$2:$U$3542=""Late"")*ROW('RMS Maint'!$A$2:$A$3542)=0"
FalseValue = "('RMS Maint'!$AA$2:$AA$3542=$B$1)*('RMS Maint'!$M$2:$M$3542=$D$2)*('RMS Maint'!$U$2:$U$3542=""Late"")*ROW('RMS Maint'!$A$2:$A$3542)"
Range("D3").FormulaArray = "=IFERROR(INDEX('RMS Maint'!C$1:C$3542,SMALL(IF(""LogicalTest"","""",""FalseValue""),ROW('RMS Maint'!1:3541)),1),"""")"
Range("D3").Replace """LogicalTest""", LogicalTest, LookAt:=xlPart
Range("D3").Replace """FalseValue""", FalseValue, LookAt:=xlPart
There is an option of last resort: Use a human.
Have the macro place the formula into the cell as a String and have the user complete the process:
Sub pinocchio()
Range("D3") = "'=1+2"
MsgBox "User: Make this into a real array formula"
End Sub

Value in cell as variable in select formula

I have programmed the following VBA code:
Sub test()
Dim Variable As Variant
Variable = "R2:R11"
Sheet1.Select
Range(Variable).Select
End Sub
This formula works perfectly. Now I want to replace the "R2:R11" part of the variable and instead referring to a cell (W12) in the spreadsheet. In this cell I have written "R2:R11" and I changed the formula to the following:
Variable = Sheet1.Range("W12")
which leads to the following code:
Sub test()
Dim Variable As Variant
Variable = Sheet1.Range("W12")
Sheet1.Select
Range(Variable).Select
End Sub
However, with this formula I now get the ERROR 1004.
Do you guys have any solution how I can make the variable referring to the cell in the spreadsheet and then use it in the select formula?
Thanks for any help :-)
You need to declare your variables properly and access the actual .Value property of the Range object.
Sub test()
Dim Variable As String
Variable = Sheet1.Range("W12").Value
Sheet1.Select
Range(Variable).Select
End Sub
Which can also be written as:
Sub test()
Sheet1.Activate
Range([W12]).Activate
End Sub
A note on the .Value property - if you omit this, the value will usually be assigned anyway because it's the default property of the range object. That being said there are scenarios where this won't be the case and therefore it's always best practice to explicitly state that you want the value.
you most probably typed "R2:R11" in W12 cell, i.e with double quotes too
in that cell you only have to type R1:R12
moreover you can simply code
Sub test()
Sheet1.Range(Sheet1.Range("W12")).Select
End Sub

How do I change the text of a cell without changing the formula?

I am new to VBA. This question has been asked and answered here but the answer seems way too hackish. Is there a better way to change the value of a cell without changing the underlying formula in it? I've tried target.text="changed" but that gives me an error of "Object Required"
The reason I ask is that in a UDF you can change the display of the cell but the formula remains there. How can I do this outside of a UDF?
EDIT:
In the example below, myudf and my_udf appear to do the same thing and everyone is telling me to just do NumberFormat. The problem is that Numberformat will change the cell permanently. If you entered "=my_udf()" in A2 then just go back and type some random text there. Unless you go back and manually re-format the cell (or enter in an excel built-in function), it will display "ThisThatThere".
Module1
Function myudf()
myudf = "ThisThatThere"
End Function
Function my_udf()
my_udf = "Temporary"
End Function
ThisWorkBook:
Sub Workbook_SheetChange(ByVal sh As Object, ByVal target As Range)
If target.HasFormula Then
If LCase(target.Formula) Like "=my_udf(*" Then
target.NumberFormat = "0;0;0;""ThisThatThere"""
End If
End If
End Sub
It is easy if the formula returns a number value rather than a text value .Place a formula in a cell, select it and run:
Sub ChangeText()
Dim DQ As String, mesage As String
DQ = Chr(34)
mesage = DQ & "override" & DQ
ActiveCell.NumberFormat = mesage & ";" & mesage & ";" & mesage & ";"
End Sub
By itself, a UDF , like a non-VBA worksheet formula, can only return a value to a cell.................the best the value can do it to affect conditional formatting.

How to change RefersTo for named range?

I have a class ValidationChanger, with a method changeNamedRangeAddress that should change the RefersTo address for a named range. However, my code is unexpectedly wrapping the new address in double quotes.
Class definition for ValidationChanger here:
'ValidationChanger
Sub changeNamedRangeAddress(bk As Workbook, rangeName As String, newAddress As String)
bk.Names(rangeName).RefersTo = newAddress
End Sub
I test it on a range named TestRange, which refers to an address in sheet Instructions: Instructions!$A$133:$A$138. My test should change the address to Instructions!$A$133:$A$139 with the following:
Sub testValidationChanger()
Dim vc As New ValidationChanger
Dim bk As Workbook
Set bk = Workbooks("test.xlsm")
Debug.Print bk.Names("TestRange").RefersTo
vc.changeNamedRangeAddress bk, "TestRange", "Instructions!$A$133:$A$139"
Debug.Print bk.Names("TestRange").RefersTo
End Sub
The output is:
=Instructions!$A$133:$A$138
="Instructions!$A$133:$A$139"
Any idea why the new address is wrapped in double quotes (which makes it function as a text string instead of an address)?
Pass the new range as a range object, and not as a string:
vc.changeNamedRangeAddress bk, "TestRange",[Instructions!$A$133:$A$139]
The reason you got a text string is that you did not preface the text string with an = sign (so that Excel would know it was supposed to be a formula)
If you use a named range instead of the addresses then you can alter that named range to adapt to whatever you want.
'this line creates the name that you can use in formulas in
'much the same way as "Instructions!$A$133:$A$139"
thisworkbook.Names.Add Name:="examplerange", RefersTo:=Range("A1:A5")
'this line changes what it's pointing to
thisworkbook.Names("exampleRange").RefersTo = Range("A1:A10")