VBA assign a range of cells a specific set of values - vba

At the beginning of my macro I need to have a certain range of cells in column R filled with the numbers 0, 1, 2, 3, 4... up to 40. Hence 0 to 40 in increments of 1. This is the simple code I propose to use but what formula after the = sign can I use to do this?
With ThisWorkbook.Sheets("Sheet1")
.Range("R17:R57") =
End With

You can use a for loop, which will increment a variable by 1. For example,
For i = 0 To 39
Worksheets("Sheet1").Cells(i+17, 18).Value = i
Next i
This will fill R17 through R57 with values 0 through 40.

Related

Random number with VBA

I am trying to create random numbers in within normal distribution given random probabilities in a range. My code is the following:
Range(Cells(2, 1), Cells(RandomNumbers + 1, 1)) = WorksheetFunction.Norm_S_Inv(Rnd)
Where RandomNumbers is just a value in another cell. The problem is that if RandomNumbers is equal to, lets say, 10 then VBA fills the same random number in all 10 cells. How do I make every number different in every cell?
Make it a loop:
Dim cell as Range
For Each cell In Range(Cells(2, 1), Cells(RandomNumbers + 1, 1))
cell.Value = WorksheetFunction.Norm_S_Inv(Rnd)
Next

Showing Numbers inbetween two numbers on the same row

What I'm trying to achieve is there are 2 whole numbers in column A & B on the same row. I want to fill the row from Column C to show the whole numbers increments of one between the two numbers.
i.e.
A B C D E F G H I J K L
1 10 1 2 3 4 5 6 7 8 9 10
any help would be appreciated.
Assuming this is Excel and you can open the VBE Editor to use VBA
Here's a macro you can run or call via a button
See the comments in the code to understand what it's doing with the Dataseries fill function
Sub FillData()
Dim intStopAt As Integer
' Set to cell indicated low end of range
Cells(1, 1).Select
' Fill in "Start At" Number
ActiveCell.Offset(0, 2).Value = ActiveCell.Value
' Retrieve and use stop number to fill in series
intStopAt = ActiveCell.Offset(0, 1).Value
ActiveCell.Offset(0, 2).DataSeries Rowcol:=xlRows, Type:=xlLinear, Date:=xlDay, Step:=1, Stop:=intStopAt
End Sub
The below code assumes you have no header and that your value in A1 is always 1, and your value in B1 is the number you want to count to.
This can be modified to be more dynamic, but taking your question as is, this should work for you.
1) Check number to count to (CountTo)
2) Run loop for 1 to CountTo and auto-populate your column headers
To run: Open VBE and paste this code on the sheet where you wish to run it.
Sub Counter()
Dim CountTo As Integer
CountTo = Range("B1").Value
For i = 1 To CountTo
Cells(1, i + 2) = i
Next i
End Sub
This can be done without VBA, perhaps not as neat initially as #dbmitch's answer because the formula has to go across to the maximum possible number.
A1 is start number, > 0
B1 is end number (> A1)
In Cell C1 enter =A1
In Cell D1 enter =IF(AND(C1<$B1,C1>=$A1),C1+1,"") and then
drag/fill right as far as you need to.
I have formulated the code so that you can now select the filled rows (A through to wherever) and fill down.
A simple explanation:
C1 sets the start of the list
The AND formula in D1 onwards checks that the immediate left cell (for D1 this is C1, for E1 this is D1 etc.) is less than the end number and greater than the start number.
If the conditions are true, use the immediate left cell value + 1 as the result.
If the conditions are false, insert a blank.
Further checking can be done, I have assumed in the above solution that the numbers are positive and increasing.
You can use helper columns to indicate if you should increase or decrease (i.e. +1 or -1 as required.
Using a blank as the other answer falls down if the numbers go from -ve to +ve. In this case, you could use another symbol (e.g. x) and check for that in the AND function as well.
you could use this:
Sub main()
Dim cell As Range
With Range("A1", Cells(Rows.Count, 1).End(xlUp)).SpecialCells(xlCellTypeConstants, xlNumbers) ' reference column A cells from row 1 down to last not empty one with a "constant" (i.e. not a formula result) numeric content
For Each cell In .Cells 'loop through referenced range
cell.Offset(, 2).Resize(, cell.Offset(, 1).Value - cell.Value + 1).FormulaR1C1 = "=COLUMN()-COLUMN(C3)+RC1" 'write proper formula in current cell adjacent cells
Next
.CurrentRegion.Value = .CurrentRegion.Value ' get rid of formulas and leave values only
End With
End Sub

Auto-Numbering depending upon Row or Column being hidden

I want the cell to number itself in an incremental order depending upon the filters. I found the easiest way is to check for the above Row if it is hidden or not then number itself from 1 if hidden and previous cell value+1 if not hidden.
I've tried to achieve this using the Formula
=IF(COUNTA(ADDR)>SUBTOTAL(103, ADDR), 1, ADDR+1)
Where ADDR is defined as follows:
=ADDRESS(ROW()-1,COLUMN(), 4, TRUE)
SUBTOTAL function returns #VALUE as it cannot contain 3-D References.
Tried replacing SUBTOTAL() function with AGGREGATE(), same issue.
Tried to use VALUE() function to convert the ADDR string to value.
I tried to use VBA
Public Function IsHid(i As Integer)
Dim re As Range, x As Integer
Set re = Range("A" & i)
If re.EntireRow.Hidden Then
Set re = Range("A" & i + 1)
re = 1
Else
x = re.Value + 1
Set re = Range("A" & i + 1)
re = x
End If
End Function
The above function returns #VALUE.
The below function also returns #VALUE.
Public Function IsHid(i As Integer)
If Excel.ThisWorkbook.ActiveSheet.Rows(i).Hidden Then
Cells(i + 1, 1).Value = 1
Else
Cells(i + 1, 1).Value = Cells(i, 1).Value + 1
End If
End Function
Very much appreciated if this functionality can be obtained by means of FORMULAS rather than the VBA
Use Subtotal combined with Count(A):
=SUBTOTAL(3,B$2:B2) and paste down.
This can be in column A and will number only visible rows when you filter on B, C, etc.
You might want to take a look here as well, for additional explanation.
Edit:
Let's say you have Sheet1 and you fill up Range A:G. In column A you want the numbering described in the question. Then Range A1 will hold a header (e.g. FilteredID) and Range B:G will hold your other values.
In range A2 all the way down, you put the formula =Subtotal(3, B$2:B2), in Range A3 this will be =Subtotal(3, B$2:B3), in A4 =Subtotal(3, B$2:B4), etc.
Now, when you filter on column B, C, D etc. so you'll have invisible rows, the numbering in column A will show the visible Row number.
For example, assuming you want to start numbering in row 2 and in column A and you have Excel 2010 or later:
=AGGREGATE(4,5,A$1:A1)+1
Just adjust the start cell as required.

Excel VBA Cells Value is not returning a value

I am simply trying to get several values from a range of cells. It is not returning any value. What am I doing wrong?
I have various numbers in cells B2 to B15.
Dim num As String
For n = 5 To 16
num = Worksheets("Info").Cells(2, n).Value
Debug.Print num
Worksheets("Info").Cells(4, n).Value = num
Next n
Thanks.
As per the Microsoft documentation, the parameters for cell indexes are row then column, not column then row. The example on that linked page illustrates this by using 5, 3 for cell C5:
This example sets the font size for cell C5 on Sheet1 to 14 points:
Worksheets("Sheet1").Cells(5, 3).Font.Size = 14
Hence your arguments to Cells should be n, 2 and n, 4 respectively.

Range based on cell value

I need code to change the range based on a cell value:
I can get it to work where the row number is dependent on the cell value as shown below, but I need the column value to be variable:
For Nassets = 1 To ws_data.Range("d2")
ws_data.Range("B" & Nassets).Value = 3
Next Nassets
If "d2" have the value 4, range B1:B4 = 3, however I want range B4:E4 = 3
Thanks in advance!
Based on the comments below, it look like you need to change the code so that the value in D2 represents the column within your loop, not the row - In which case:
For Nassets = 1 To ws_data.Range("d2")
ws_data.Cells(4, Nassets).Value = 3 '// Where 4 is the row number
Next Nassets
This can be re-written to exlude the loop altogether like so:
ws_data.Range(Cells(4, 2), Cells(4, ws_data.Range("D2").Value)).Value = 3