Iterated EMA formula VBA - vba

I am working on VBA macro, manipulating data on an excel sheet. I have closes of stocks and need to make a collection of EMA (exponential moving average) series. I need to iterate the same couple of formulas over 100 times, but respective to the cells. For example, the first iteration will be =AVERAGE(D153:D164) , then immediately beneath that will be =(2/13)*D165+(11/13)*E164, which will be format copied down (I'll do that). I need to perform these calculations every 70 rows, ending with =AVERAGE(D8973:D8984) & (2/13)*D8985+(11/13)*E8984. Can someone help me derive a functioning macro? Your help is sincerely appreciated.
EDIT: To be more specific, I need to pass the row number as a variable to use in the formulas. If I see how to do so with one variable, I can use that as a foundation. The above 2 formulae are models, yet each instance of each formula will be unique.
Again, thank You.

Assuming the first formulas are the same, and you are always incrementing the same number of rows (70), this code should work. You can change some of my initial assumptions such as the starting cell, number of iterations, etc.
Sub EMAmakeAFunction()
'''''These can be changed as you need
Dim numberOrRowsToSkip As Integer: numberOFRowsToSkip = 70
Dim TrialsToExecute As Integer: TrialsToExecute = 1000
Dim firstFormula As Range: Set firstFormula = Range("D165")
Dim secondFormula As Range: Set secondFormula = Range("D166")
''''Rest of code should be pretty stable of above assumptions are correct.
Dim i As Integer
For i = 1 To TrialsToExecute
firstFormula.Offset(i * numberOFRowsToSkip).FormulaR1C1 = _
firstFormula.FormulaR1C1
secondFormula.Offset(i * numberOFRowsToSkip).FormulaR1C1 = _
secondFormula.FormulaR1C1
Next i
End Sub

Related

VBA extend range of chart by a variable stored in a cell

This is proper basic but I'm struggling here. I need the range of rows of a data source in a graph to extend or retract by a value I have in "J5". "J5" changes dynamically and I can use a call function for it to work in the graph. Because of the way the charts are set up it has to be this way. My code so far is:
Sub Updatecodelengh()
Dim i As Integer
Dim G As Worksheet
Set G = Sheet1
i = G.Range("J5")
ActiveSheet.ChartObjects("GanttChart").Activate
ActiveChart.SeriesCollection(16).Values = "='Gantt'!$L$3:$L$4"
End Sub
Where it says "='Gantt'!$L$3:$L$4" I need the range of the chart data to start on $L$3 and extend downwards by the value obtained in J5. Thanks for any help
Do you mean simply
ActiveChart.SeriesCollection(16).Values = "='Gantt'!$L$3:$L$" & i
However, you should check if J5 contains a valid number to prevent runtime errors.
A small hint: When dealing with row and column numbers in VBA, always use datatype long.

Random 8 digit Values generating with either VBA or Formula BUT copy and special paste over it to keep the value

i'm quite new to Excel VBA and formulas but i need to have a cell with random values on the form that i had created to create like a unique id (I know that there might be chances of getting duplicate numbers but it is slim) to send it to people to fill up a form but the thing is that if im using the RandBetween(00000000,99999999), hiding and unhiding just keep activating the formula which is hard for me to keep track if i were to send this template for others to fill up. So is there any way where when i have the formula and when the user opens the Excel form, it will randomize a 8 digit number and copy and special pasting the value overwriting it to freeze the value.
(Other ways are also gladly welcomed, thanks in advance guys)
I'm not sure what you're actually trying to do here, but if you wanted to generate a random number and store its value in a cell, you can use this code in 'ThisWorkbook' in VBA:
Option Explicit
Const MySheetName As String = "Sheet1" ' Change this to your sheet name
Private Sub Workbook_Open()
' Called every time you open the excel document
Dim myRandNumber As Long
Randomize
myRandNumber = CLng(Rnd() * 999999999) ' CLng converts the floating point number to a long integer
Dim rowNum As Integer
Dim colNum As Integer
rowNum = 3
colNum = 5
ThisWorkbook.Sheets(MySheetName).Cells(rowNum, colNum).Value = myRandNumber
End Sub
If you wanted to make sure this number was unique, which is probably what you really want to do, you can store these values in a separate hidden sheet and check these values each time you want to generate a new number.
You could also just timestamp the number using this line of code instead of the random number:
ThisWorkbook.Sheets(MySheetName).Cells(rowNum, colNum).Value = CDbl(Now() * 100000)
This will create a new unique number every 1 second, based on the system time.
If I understand correctly, you want to generate this number once. There are a couple ways I can think of to do this:
Generate the number only if the cell is blank
Set a flag in a hidden sheet
In both cases, if you wanted to generate the number again, you just need to clear the cell containing the number (option 1) or clear the flag in the sheet (option 2)
Option 1 can be done by replacing this part of the above code:
ThisWorkbook.Sheets(MySheetName).Cells(rowNum, colNum).Value = myRandNumber
with this:
With ThisWorkbook.Sheets(MySheetName).Cells(rowNum, colNum)
If (.Value = "") Then
.Value = myRandNumber
End If
End With
Hope this helps

VBA creating formulas referencing a range

After several hours of research, I still can't solve what seems to be a pretty simple issue. I'm new to VBA, so I will be as specific as possible in my question.
I'm working with a DDE link to get stock quotes. I have managed to work out most of the table, but I need a VBA to create a finished formula (i.e., without cell referencing) in order to the DDE link to work properly.
My first code is as follows:
Sub Create_Formulas()
Range("J1").Formula = "=Trade|Strike!" & Range("A1").Value
End Sub
Where J2 is the blank cell and A2 contains the stock ticker. It works fine, but when I try to fill out the rows 2 and bellow, it still uses A1 as a static value.
Sub Create_Formulas()
Dim test As Variant
ticker = Range("A1").Value
'Test to make variable change with each row
'Range("J1:J35").Formula = "=Trade|Strike!" & Range("A1:A35").Value
'not working
Range("J1:J35").Formula = "=Trade|Strike!" & ticker
'not working
End Sub
I couldn't find a way to solve that, and now I'm out of search queries to use, so I'm only opening a new topic after running out of ways to sort it by myself. Sorry if it is too simple.
You are referencing absolute cell adresses here. Like you would do when using $A$1 in a normal excel formula.
What you want to do is:
Dim row as Integer
For row = 1 to 35
Cells(row,10).Formula = "=Trade|Strike!" & Cells(row,1).Value
Next row
This will fill the range J1 to J35 with the formula. Since (row,10) indicates the intersection of row and column 10 (J)
Firstly, in your second set of code, you define a variable "test", but never give it a value.
You assign a value to the variable "ticker", and then never reference it.
Secondly, the value you have assigned to ticker is a static value, and will not change when it is entered in a different row.
Thirdly, I think your issue could be solved with a formula in Excel rather than VBA.
The "INDIRECT" function can be quite useful in situations like this.
Try inserting the formula
=INDIRECT("'Trade|Strike'!"&A1)
into cell A1, then copy down.
Note the ' ' marks around "Trade|Strike". This is Excels syntax for referencing other sheets.

Excel VBA: Insheet function code can not access other cells on sheet

I'm having some issues with an insheet function that I am writing in VBA for Excel. What I eventually am trying to achieve is an excel function which is called from within a cell on your worksheet, that outputs a range of data points underneath the cell from which it is called (like the excel function =BDP() of financial data provider Bloomberg). I cannot specify the output range beforehand because I don't know how many data points it is going to output.
The issue seems to be that excel does not allow you to edit cells on a sheet from within a function, apart from the cell from which the function is called.
I have created a simple program to isolate the problem, for the sake of this question.
The following function, when called from within an excel sheet via =test(10), should produce a list of integers from 1 to 10 underneath the cell from which it is called.
Function test(number As Integer)
For i = 1 To number
Application.Caller.Offset(i, 0) = i
Next i
End Function
The code is very simple, yet nothing happens on the worksheet from which this formula is called (except a #Value error sometimes). I have tried several other specifications of the code, like for instance:
Function test(number As Integer)
Dim tempRange As Range
Set tempRange = Worksheets("Sheet1").Range(Application.Caller.Address)
For i = 1 To number
tempRange.Offset(i, 0) = i
Next i
End Function
Strangely enough, in this last piece of code, the command "debug.print tempRange.address" does print out the address from which the function is called.
The problem seems to be updating values on the worksheet from within an insheet function. Could anybody please give some guidance as to whether it is possible to achieve this via a different method?
Thanks a lot, J
User defined functions are only allowed to alter the values of the cells they are entered into, because Excel's calculation method is built on that assumption.
Methods of bypassing this limitation usually involve scary things like caching the results and locations you want to change and then rewriting them in an after calculate event, whilst taking care of any possible circularity or infinite loops.
The simplest solution is to enter a multi-cell array formula into more cells than you will ever need.
But if you really need to do this I would recommend looking at Govert's Excel DNA which has some array resizer function.
Resizing Excel UDF results
Consider:
Public Function test(number As Integer)
Dim i As Long, ary()
ReDim ary(1 To number, 1 To 1)
For i = 1 To number
ary(i, 1) = i
Next i
test = ary
End Function
Select a block of cells (in this case from C1 through C10), and array enter:
=test(10)
Array formulas must be entered with Ctrl + Shift + Enter rather than just the Enter key.

Excel VBA for hiding cells in one sheet if they match cells in another sheet

I am new to VBA and am having problems learning the rules of variables (I think that's the problem here).
I have two worksheets in a spreadsheet. I need to make code that automatically hides a row on worksheet 2 if that same value in column a is on worksheet 1, column a.
Here's one of the variations of code I've tried:
Dim Sheet2Value As Variant
Dim Sheet1Value As Variant
'
Sheet2Value = Sheets("Sheet2").Range("A:A").Value
Sheet1Value = Sheets("Sheet1").Range("A:A").Value
'
If Sheet2Value = Sheet1Value Then
Sheets("BMAC=N").EntireRow.Hidden = False
Else
Sheets("BMAC=N").EntireRow.Hidden = True
End If
I get a type mismatch error but I'm not sure exactly why. I chose variant because I don't know what I'm doing, but both columns in excel will be set to "General".
Can anyone help with this? What concept am I missing?
Thanks so much for your time.
Few things:
you cannot compare entire column:
Sheet2Value = Sheets("Sheet2").Range("A:A").Value
you need to loop through the collection of cells, see this: Fast compare method of 2 columns
you cannot hide row without defining a range to hide
Sheets("BMAC=N").Range("Some_address").EntireRow.Hidden
Finally, i'd suggest to change your code to shortest way:
Sheets("BMAC=N").Range("A1").EntireRow.Hidden = (value1<>value2)
Good luck!