I'm a R programmer but am attempting VBA for the first time. I have a pretty simple population projection based on a series of randomly selected birth and survival values. I have predicted population values for years 1 to 20 in cells BC4:BC23 in Sheet1. Every time I refresh, the values change. I would like to refresh 100 times and store each of the population values into Sheet2 (100 columns with 20 values).
Based on my internet searching, it seems that a combination of a loop and EnableCalculation is a viable VBA approach for this. I've tried different coding approaches (Application.EnableEvents, CalculateManyTimes, etc) with no luck. Surely this kind of question has been asked before but I could not find it. Any tips would be appreciated. Thank you.
The key is Application.CalculateFull so the code could be:
Sub CalculateAndSave()
Dim Ws As Worksheet
Set Ws = Worksheets(2)
For i = 1 To 100
Application.CalculateFull
Ws.Range(Ws.Cells(4, i), Ws.Cells(23, i)) = Sheets(1).Range("BC4:BC23").Value
Next i
End Sub
Related
I am working with a file which includes an automated calculation for given inputs. Using [Sub:Other_Sub_Calc].
The aim of this code is to get all combinations of the 3 different variables (listed in 'sheet4' columns a:c) along with the corresponding result [Cell: b61]copied on to a separate sheet(rather than running each combination individually).
The code seems to work with just the two variables in places but I've messed up somewhere adding the third.
I'm sorry for my very bad vba knowledge, I'd imagine someone with better knowledge may be able to spot my mistake in this simple code relatively quickly.
Thank you in advance if anyone can help.
Sub Expected_results()
Dim age, town, studylength As Range
Dim lastrow As Integer
'Variables
Set age = Sheets("Sheet4").Range("a2:a5")
Set town = Sheets("Sheet4").Range("b2:b6")
Set studylength = Sheets("Sheet4").Range("c2:c6")
For Each Year In age
Sheets("Summary").Range("B28").Value = volume
For Each Location In town
Sheets("Summary").Range("B34").Value = Ratio
For Each duration In studylength
Sheets("Summary").Range("B29").Value = Ratio
Other_Sub_Calc 'Example Sub to be ran for each combination of variables
'copy and append each generated result
Worksheets("Summary").Range("b61").Copy
Worksheets("Sheet5").Range("d2" & lastrow + 1).PasteSpecial
Next age
Next Location
Next duration
End Sub
I am looking at somewhat of a problem when trying to program a macro in Excel that is meant to add the number values from 2 tables and display the updated total in the second of the two.
I have just started learning how to program macros, so my knowledge is a little basic, but I am sure that there has to be a way to set this up in a more convenient way than what I am doing right now.
I have two tables, table 1 contains the data of the current week, which is entered manually, while table 2 is supposed to contain the total, which is calculated when clicking the macro button "Add".
I was able to fully set this up myself, using very basic code, which is why I am asking for help. At the moment the macro code is very messy and absolutely massive, I am looking at 242 declared variable values and a total of 925 lines of code.
The below is simplified and shortened, but basically how everything is working right now:
Each table contains up to 11 columns of data, with 11 rows each, so the macro is adding cells B2 to L12 to cells B29 to L39. The results are then being displayed as the total in cells B29 to L39.
The code right now:
Sub Add()
Dim Add As Integer
Dim var1 As Integer
Dim var2 As Integer
var1 = Range("B2").Value
var12 = Range("B29").Value
Add = var1 + var12
Range("B29").Select
ActiveCell.FormulaR1C1 = Add
Like I said, this does work and does exactly what I need, but this involves a lot of code and a huge potential for mistakes, as well as hours of writing it all out. Doesn't look very good either, and is even harder to follow/work through.
Can anybody help me streamline this, make it shorter? Is there any option to sum the whole thing up in fewer lines of code, fewer arguments?
Thanks in advance for any help.
UPDATE:
As mentioned before, the code I currently have does work as intended, but I would like to cut it down volume wise. There's just too much of it and I know it is possible to do the exact same with a lot less, I just don't know how.
I have structured the code to make it a little easier to read, the first section declaring the variables, the next chunk declaring the values (separated into blocks per row in the table) and lastly the calculating action of adding table A to table B and displaying the result in table B (again, separated into blocks per row in the table).
Thank again everyone for your help.
This is the complete code currently written
Try this out:
Dim cell as Range
For each cell in Range("B29:L39")
cell.Value = cell + cell.offset(-27).Value
Next
you could use PasteSpecial() method with xlPasteSpecialOperationAdd value for its Operation parameter
Range("B2:L12").Copy
Range("B29:L39").PasteSpecial Operation:=xlPasteSpecialOperationAdd
Application.CutCopyMode = False
or you could use arrays
Dim i As Long, j As Long
Dim var1 As Variant, var2 As Variant
var1 = Range("B2:L12").Value
var2 = Range("B29:L39").Value
For i = 1 To UBound(var1, 1)
For j = 1 To UBound(var1, 2)
var2(i, j) = var2(i, j) + var1(i, j)
Next
Next
Range("B29:L39").Value = var2
I feel like this is extremely simple, but for some reason, this is not an easy thing to do in Excel. Basically I have a vertical set of values running down a column ranging from 1 to 3, but they are random. However this same sequence will repeat every 60 rows. I need the sequence to just repeat itself every 60 rows, as the data file I'm working on is tens of thousands of rows and I don't feel like copying and pasting that many times. The values run from M2:M61.
Is there a simple VBA code to loop this column?
Alternatively, is there an equation that can do this? I tried using Index, but don't think I was specifying the row or columns correctly
=INDEX($M$122:$M$181,ROUNDUP(ROWS(I$122:I132)/60,0),13)
If you wanted some code to do it, maybe this will give you some ideas. It assumes that your first lot of 60 values have been entered in A1:A60 and reads them into an array, and then loops up to the number of loops (I used 12000) copying the values in by steps of 60.
Sub Repeat60Rows()
Dim ListArray As Variant
Dim Loopcounter As Long
Dim MyRange As String
ListArray = Worksheets("Sheet2").Range("A1:A60").Value
For Loopcounter = 1 To 12000 Step 60
MyRange = "A" & Loopcounter & ":A" & Loopcounter + 59
Worksheets("Sheet2").Range(MyRange) = ListArray
Next Loopcounter
End Sub
I learned a little more and realized, because this is a repeating set of 60 numbers, I could just use a simple =OFFSET(M62, -60, 0) formula and I could just paste down. I'm sure there's probably an easier way to automate this with VBA, but I'm unsure as to how to do that.
In M182
=OFFSET(M$121,MOD(ROW()-2,60)+1,0)
and fill down
In Excel I've got sequential box numbers in column B, and each box has a couple dozen files that need sequential-by-box place numbers in column C. The way I usually do this is to Fill Series down a selection (selected by hand) of all the cells for that box in Column C, which is fine if you've got a few boxes to do, but now I have several hundred.
[I've got a 394x290 example screenshot I was going to include to show what I mean, but since this is my first post I don't have enough rep, sorry -- link to it on g+ here.]
I thought I could put some VBA code into a macro to select the contiguous cells with the same box number, offset one column right [Offset (0, 1), yeah?], fill series those cells from 1, and go on to the next box. But I haven't had any luck finding anything similar that's been done, nor have I been able to get anything I've looked up to work for this. (Not surprising since I rarely try VBA, hopefully my question's not too noobish for this site.)
From what I can tell, you want the Plc column to fill up series starting from 1 for the same Box Num.
There may exist a fast and quick way but simple method is to go through the rows. Try below:
Sub FillUpPlc()
Dim oRng As Range, n As Long ' n used for series filling
Application.ScreenUpdating = False
n = 1
Set oRng = Range("B2")
Do Until IsEmpty(oRng)
' Increment n if it's same as cell above, otherwise reset to 1
If oRng.Value = oRng.Offset(-1, 0).Value Then
n = n + 1
Else
n = 1
End If
oRng.Offset(0, 1).Value = n ' Store n to next column
Set oRng = oRng.Offset(1, 0) ' Move to next row
Loop
Set oRng = Nothing
Application.ScreenUpdating = True
End Sub
No need to break out the VBA. This can be done with a formula. Starting in C2 and copied down
=IF(B2<>B1,1,C1+1)
Much, much faster than VBA looping through thousands of rows.
I have sheet1 full of football results.
Season------Home-------Away---------Score
2009--------Albion------Burton--------0-1
2011--------Albion------Burton--------2-1
2012--------Albion------Burton--------4-0
I want to produce sheet2 same workbook, for each teams history.
Each cell (r1,c1) must be referenced for it's data value, then manipulated into sheet2 by placing the score into the correct season column. Then looped for the next teams history Etc.
Sheet2
Home--------Away----2000-2001-2002-2003-2004-2005-2006-2007-2008-2009-2010-2011-2012
Albion------Burton------------------------------------------------0-1-------2-1--4-0
Can someone start me off using Excel2010 vba please.
Yes, I can help you get started.
With Sheet.Cells(Row, Col) you can access any cell you like.
With For... Next loop you can loop trough the rows and columns using nested loops.
You can access both sheets by their name, by default Sheet1 and Sheet2.
You can also use Range objects to find data in sheets more efficiently;
Dim r As Range
Dim m As Range
Set r = Sheet2.Range("A1:G1") ' For the row with all your years
Set m = r.Find(Value1) ' Value1 could be the year
If Not m Is Nothing Then
' It was found and m.Column tells which column it is, yay!
End If
Etc... stackoverflow is also littered with basic questions like how to do stuff like this, feel free to search. Who knows you might encounter a problem with question never encountered before!