I need Evaluate a function and I'm using (as posted in another question):
Function Eval(aFunction As String)
Application.Volatile
Eval = Evaluate(aFunction)
End Function
This works well when the cell reference is like "B15", for example aFormula = "B15*10".
But, I'm working inside a table and I wish to use references like "[#X]", where X is a column header, for example aFormula = "[#X]*10". This returns a error (#VALUE!).
There are a solution? Thanks
Related
I wrote a VBA script/macro which runs when a change is detected in a specific range (n x m) of cells. Then, it changes the values in another range (n x 1) based on what is detected in the first range.
This bit works perfectly ... but then comes the age old erased undo stack problem. Unfortunately, the ability for the user to undo their last ~10 or so actions is required.
My understanding is that the undo stack is only cleared when VBA directly edits something on the sheet - but it is preserved if the VBA is just running in the back without editing the sheet.
So my question is: Is it possible to use an in cell formula (something like below) to pull values from a VBA array?
'sample of in-cell function in cell A3
=function_to_get_value_from_vba_array(vba_array, index_of_desired_value)
Essentially, VBA would store a 1D array of strings with the values needed for the range. And by using a formula to grab the value from the array: I might be able to get around the issue of the undo stack being erased.
Thanks!
Solution
You need to do something like the following: your argument for the function should be calling the array bulding; I created one dummy function that creates some sample arrays to demonstrate it. In your case, likely you will need to store the changes on the worksheet event in a global array variable instead, and as you stated, do nothing on the worksheet (whenever a change happens, just redim or appended it on your global array as needed). However, a new problem may arise and that is when you close/reopen, or by some reason the array is lost, so you need to keep track of it, I would suggest to catch before close event and then convert the formulas to static values.
Function vba_array(TxtCase As String)
Dim ArrDummy(1) As Variant
Select Case TxtCase
Case "Txt": ArrDummy(0) = "Hi": ArrDummy(1) = "Hey"
Case "Long": ArrDummy(0) = 0: ArrDummy(1) = 1
Case "Boolean": ArrDummy(0) = True: ArrDummy(1) = False
End Select
vba_array = ArrDummy
End Function
In your calling function, do the following
Function get_value_from_vba_array(vba_array() As Variant, index_of_desired_value As Long) As Variant
'when parsing, even with option base 0 it starts at 1, so we need to add 1 up
get_value_from_vba_array = vba_array(index_of_desired_value + 1)
End Function
In your book, your formula should be something like:
=get_value_from_vba_array(vba_array("Txt"),1)
Demo
I did some actions before, so you are able to see that the "undo" works
The problem that I'm facing is that I have an entire column that has text separated by _ that contains pixel size that I want to be able to extract but currently can't. For example:
A
Example_Number_320x50_fifty_five
Example_Number_One_300x250_hundred
Example_Number_two_fifty_728x49
I have tried using Substitute function to grab the numbers which works but only grabs the numbers when I need something like: 320x50 instead I'm getting 0, as I'm not sure how to exactly extract something like this. If it was consistent I could easily do LEFT or RIGHT formula's to grab it but as you can see the data varies.
The result that I'm looking for is something along the lines of:
A | B
Example_Number_320x50_fifty_five | 320x50
Example_Number_One_300x250_hundred | 300x200
Example_Number_two_fifty_728x49 | 728x49
Any help would be much appreciated! If any further clarification is needed please let me know and I'll try to explain as best as I can!
-Maykid
I would probably use a Regular Expressions UDF to accomplish this.
First, open up the VBE by pressing Alt + F11.
Right-Click on VBAProject > Insert > Module
Then you can paste the following code in your module:
Option Explicit
Public Function getPixelDim(RawTextValue As String) As String
With CreateObject("VBScript.RegExp")
.Pattern = "\d+x\d+"
If .Test(RawTextValue) Then
getPixelDim = .Execute(RawTextValue)(0)
End If
End With
End Function
Back to your worksheet, you would use the following formula:
=getPixelDim(A1)
Looking at the pattern \d+x\d+, an escaped d (\d) refers to any digit, a + means one or more of \d, and the x is just a literal letter x. This is the pattern you want to capture as your function's return value.
Gosh, K Davis was just so fast! Here's an alternate method with similar concept.
Create a module and create a user defined function like so.
Public Function GetPixels(mycell As Range) As String
Dim Splitter As Variant
Dim ReturnValue As String
Splitter = Split(mycell.Text, "_")
For i = 0 To UBound(Splitter)
If IsNumeric(Mid(Splitter(i), 1, 1)) Then
ReturnValue = Splitter(i)
Exit For
End If
Next
GetPixels = ReturnValue
End Function
In your excel sheet, type in B1 the formula =GetPixels(A1) and you will get 320x50.
How do you create a user defined function?
Developer tab
Use this URL to add Developer tab if you don't have it: https://www.addintools.com/documents/excel/how-to-add-developer-tab.html
Click on the highlighted areas to get to Visual Basic for Applications (VBA) window.
Create module
Click Insert > Module and then type in the code.
Use the user defined function
Note how the user defined function is called.
I tried to create a file with decimal numbers on cells (F1:F4), but when i am going to insert a formula to the cell, it's show it like a string.
Code:
s1("F5").Formula = "=SUMME(F1:F4)"
s1("F5").Value = s1("F5").Formula
i tried:
s1("F5").Formula = "=SUMME(F1:F4)"
s1("F5").Formatting.HiddenFormula = False
s1("F5").Value = s1("F5").Formula
i tried:
s1("F5").Formula = "=SUMME(F1:F4)"
The result its the same, on cell F5, =SUMME(F1:F4)
always on string format.
Note : s1 = Sheet1
Try this:
s1.Cells("F5").Formula = "=SUM(F1:F4)"
You didn't set the range of the sheet. Also changed the SUMME to SUM, unless you have a User Defined Function (UDF) which is called SUMME or you are using Excel in a language where Summe = Sum.
EDIT:
After looking into the library you are using, I would try the following:
s1["F5"].Value = "=SUMME(F1:F4)";
I found the solution. With that library, it's not possible.
I used another library just to make the formula. Nix library it's good to add data to the cells.
I need help to change the following function into VBA code. This will be part of a larger code.
IF((WEEKDAY($B12)=7),$I12,"")
There are probably more than 5 ways to do what you want, depending on what exactly do you need. One of these ways is to build a simple custom formula like this:
Public Function changingIfAndWeekday() As Variant
Application.Volatile
If Weekday(Range("B12")) = 7 Then
changingIfAndWeekday = Range("I12")
Else
changingIfAndWeekday = ""
End If
End Function
You could also do it like so (if you want the result on cell C12):
Sheet1.range("C12").value = "=IF(Weekday(Sheet1.range("B12").value = 7),Sheet1.range("I12").value,"")
You could also do it like so (if you want the result on a variable):
Variable = "=IF(Weekday(Sheet1.range("B12").value = 7),Sheet1.range("I12").value,"")
I originally had a VBA function that returned a two dimensional variant array:
Public Function SplitIntoCells(some_data As String) As Variant()
End Function
I used the Formula array syntax to call it from another vba function:
Public Function MyWrapper() as Variant
MyWrapper = SplitIntoCells("somestring")
End Function
From Excel, if I select a big enough range and then do:
=MyWrapper()
followed by CTRL+SHIFT+ENTER, the data is nicely split into every individual cell in that range.
However in order to automate that, if I change MyWrapper to:
Public Function MyWrapper()
ActiveSheet.Range("A1:E20").Select
Selection.FormulaArray = SplitIntoCells("somestring")
End Function
The above doesn't work. I see nothing being displayed in Excel.
What am I doing wrong?
Update:
Just for testing, if I slightly modify MyWrapper() to:
Public Function MyWrapper()
Dim variant_temp() as Variant
variant_temp = SplitIntoCells("somestring")
ActiveSheet.Range("A1:E20").Select
Selection.FormulaArray = variant_temp
End Function
variant_temp predictably has the 2-d array after returning from SplitIntoCells but the subsequent Selection.FormulaArray still has nothing in it even after the assignment. I am sure I am missing something blindingly obvious.
A VBA user-defined function cannot modify the cell or range it's being called from: it can only return a value.