selecting max value excel using Cells(x,y) as input - excel

How do you call the Max function in VBA using a range of Cells (x,y) as input?
E.g., I have two variables, m & n, where n > m
I try to find the Max value within a range of cells using the following code:
Cells(Count, 4) = Application.WorksheetFunction.Max(Cells(m, 1): Cells(n, 1))
Using that code I keep getting an error "Expected: list separator or )"
Edit, here is the entire code
Sub convertFNIRStoCandlesticks()
'Variable declarations
Dim rowCount As Integer 'The total number of rows in use
Dim Count As Integer
Dim Period As Integer
Dim totalPeriods As Integer
Dim PeriodStart As Integer
Dim PeriodEnd As Integer
rowCount = ActiveSheet.UsedRange.Rows.Count
totalPeriods = rowCount / 6
Sheets("Sheet1").Activate
For Count = 1 To totalPeriods
Period = Count - 1
PeriodStart = (Period * 6) + 1
m = (Period * 6) + 1
PeriodEnd = (Period * 6) + 6
n = PeriodEnd
Cells(Count, 2) = Cells(PeriodStart, 1)
Cells(Count, 4) = Application.WorksheetFunction.Min(Range(Cells(PeriodStart, 1), Cells(PeriodEnd, 1)))
Cells(Count, 5) = Cells(PeriodEnd, 1)
Next Count
End Sub

You can use the function Max on Application.WorksheetFunction where you use a Range from Cells(m, 1) to Cells(n, 1):
Cells(Count, 4)=Application.WorksheetFunction.Max(Range(Cells(m, 1),Cells(n, 1)))
This will return max into Cells(Count, 4)

Related

Excel return #Value! error for user defined function

I have written a function and when I call it in Excel, it returns me #value! error.
Function interpolator(maturities As Variant, rates As Variant, currencies As Variant, ccy As String, t_end As Double)
Dim xArr() As Double
Dim yArr() As Double
Dim xLen As Integer, currLen As Integer
xLen = UBound(maturities) - LBound(maturities) + 1
currLen = UBound(currencies) - LBound(currencies) + 1
ReDim xArr(1 To xLen, 1)
ReDim yArr(1 To xLen, 1)
'defining and filling the arrays with inputs
Dim m As Integer, k As Integer
m = 1
For k = 1 To currLen
If currencies(k, 1) = ccy Then
xArr(m, 1) = CInt(maturities(m, 1))
yArr(m, 1) = CDbl(rates(k, 1))
m = m + 1
End If
Next
' Check tenor is within range, then execute
If t_end = xArr(LBound(xArr), 1) Then
interpolator = yArr(LBound(yArr), 1)
Else
Dim n As Integer
For n = 1 To xLen
If xArr(n, 1) >= t_end Then
interpolator = yArr(n - 1, 1) + ((t_end - xArr(n - 1, 1)) * (yArr(n, 1) - yArr(n - 1, 1)) / (xArr(n, 1) - xArr(n - 1, 1)))
Exit For
End If
Next
End If
End Function
Sub test()
Dim maturities As Variant, rates As Variant, currencies As Variant
maturities = Worksheets("Static Data").ListObjects("Table_TenorTable").ListColumns("days").DataBodyRange.Value2
rates = Worksheets("Static Data").ListObjects("Table_TenorTable20").ListColumns("CCYYield").DataBodyRange.Value
currencies = Worksheets("Static Data").ListObjects("Table_TenorTable20").ListColumns("Currency").DataBodyRange.Value
MsgBox interpolator(maturities, rates, currencies, "USD", 31)
End Sub
interpolator(maturities, rates, currencies, "USD", 31) works fine but when I call it via Excel, it give me error.
I am calling in Excel like this:
=interpolator(Table_TenorTable[days],Table_TenorTable20[CCYYield],Table_TenorTable20[Currency],LEFT([#[Commodity_Group]],3),[#[T (in Tenors)]])
Need some guidance in solving this.

How to split values separated by comma and keep its row correspondence in excel

In Excel 365, I have data in this format:
Or, in text:
1,2,3,7 A
4 B
5 C
6, 8 D
And I'm trying to split the data so it becomes this:
Or, in text
1 A
2 A
3 A
4 B
5 C
6 D
7 A
8 D
The leftmost row is always composed by numbers separated by comma or a single number. The right row can be any data.
The following VBA code will do most of what you want:
Sub ExpandRows()
Dim R As Range
Dim Rw As Range
Dim I As Integer
Dim J As Integer
Dim K As Integer
Dim S As String
Dim Tokens(1 To 1000) As String
Dim NTokens As Integer
Const Delim As String = ","
Dim StartSize As Integer
Dim TopCell As Range
Dim BotCell As Range
Set R = Selection
Set TopCell = R.Cells(1, 1)
Set BotCell = R.Cells(R.Rows.Count, 1)
StartSize = R.Rows.Count
For I = StartSize To 1 Step -1
S = R(I, 1)
If (S <> "") Then
J = 0
NTokens = 0
Do
K = InStr(J + 1, S, Delim)
If (K = 0) Then
NTokens = NTokens + 1
Tokens(NTokens) = Mid$(S, J + 1, Len(S) - J)
Else
NTokens = NTokens + 1
Tokens(NTokens) = Mid$(S, J + 1, (K - J - 1))
J = K
End If
Loop Until (K = 0)
End If
If (NTokens > 1) Then
For J = NTokens To 2 Step -1
If (Tokens(J) <> "") Then
Set Rw = R.Cells(I, 1).EntireRow
Call Rw.Select
Call Rw.Copy
Call R.Cells(I + 1, 1).EntireRow.Select
Call Rw.Insert(xlDown)
If (I = 1) Then
Set TopCell = TopCell.Cells(0, 1)
Set R = Range(TopCell, BotCell)
End If
Call R.Select
Call R.Cells(I + 1, 1).Select
R(I + 1, 1) = Tokens(J)
End If
Next J
R(I, 1) = Tokens(1)
End If
Next I
End Sub
This code will split the cells and create new rows with a single entry.
To use it, select the first column and execute the method.
After that, all you have to do is sort on the first column.

VBA - How to tell 13 combinatios by randomize to remain under 100?

I would like to randomize 13 variables which in sum have to be 100%.
For a better understanding I show you what I mean by a snippet. From column F to column R all variables have to understand that in sum (column S) these are not allowed to be over 100.
Each row shall be another scenario, so the rows by itself are independent.
My approach was like the following but unfortunately nothing happens. Anyone an idea? Thanks a lot.
Sub Zufall()
Dim k As Integer
Application.ScreenUpdating = False
Range("F11:R55").ClearContents
DoEvents
Do Until WorksheetFunction.Sum(Range("S11:S55")) = 100
Randomize
For k = Columns(19) To Columns(6) Step -1
Cells(11, k).Formula = Int(Rnd() * 100)
Next k
Range("R55:F11").Value = WorksheetFunction.Sum(Range("S11:S55"))
DoEvents
Loop
Application.ScreenUpdating = True
End Sub
The following code shows how to generate a set of n random single precision numbers between 0 and 1 which sum to 1.
' Returns an array of random numbers (0 <= n < 1) which sum to 1.
' Size is the size of the array to return.
Function GenerateRandomNumbers(ByVal size As Integer) As Variant
ReDim vals(1 To size) As Single
Dim idx As Integer
Dim sum As Single
For idx = 1 To size
vals(idx) = Rnd
sum = sum + vals(idx)
Next idx
For idx = 1 To size
vals(idx) = vals(idx) / sum
Next idx
GenerateRandomNumbers = vals
End Function
You use it like this.
Sub Randomm()
Dim row As Long
Dim col As Long
Dim thirteenRandomNumbersWhichSumToOne As Variant
With Worksheets("Sheet1")
For row = 6 To 50
thirteenRandomNumbersWhichSumToOne = GenerateRandomNumbers(13)
For col = 6 To 18 ' F to R
.Cells(row, col).Value = thirteenRandomNumbersWhichSumToOne(col - 5)
.Cells(row, col).NumberFormat = "0%"
Next col
.Cells(row, 19).FormulaR1C1 = "=SUM(RC6:RC18)"
.Cells(row, 19).NumberFormat = "0%"
Next row
End With
End Sub
This will generate 13 values from A1 through A13:
Sub Randomm()
Dim wf As WorksheetFunction, rng As Range
Set wf = Application.WorksheetFunction
Set rng = Range("A1:A13")
rng.Formula = "=RAND()"
rng.Value = rng.Value
zum = wf.Sum(rng)
For i = 1 To 13
Cells(i, 1).Value = Cells(i, 1).Value / zum
Next i
rng.NumberFormat = "0.00%"
End Sub
this is the current and last code. Missing:
idx values in sum do not limit up to 100% in column S
Changed:
column S was implied by using the easy sum calcluation in Excel
the % wasnt shown right this is why i used it by Format in Excel
Sub Randomm()
Dim wf As WorksheetFunction, rng As Range, zum As Single, i As Integer
Set wf = Application.WorksheetFunction
Set rng = Range("F6:R50")
Dim totalRow As Single
rng.Formula = "=RANDBETWEEN(5,25)/100"
rng.Value = rng.Value
zum = wf.sum(rng)
For i = 6 To 50
Cells(i, 6).Value = Cells(i, 13).Value
Next i
End Sub
Function GenerateRandomNumbers(ByVal size As Integer) As Variant
ReDim vals(1 To size) As Single
Dim idx As Integer
Dim sum As Single
For idx = 1 To size
vals(idx) = Rnd
Next idx
For idx = 1 To size
vals(idx) = vals(idx)
Next idx
GenerateRandomNumbers = vals
End Function

CountIFs in Excel with VBA is not counting decimal values

I have a problem with the function CountIF when used with decimals.
Below the code I have:
Sub Compair()
Dim I As Double
Row = 3
For I = 139.5 To 141.5 Step 0.25
Cells(Row, 3) = I
Cells(Row, 4) = Application.WorksheetFunction.CountIf(Range("A:A"), "<" & Cells(Row, 3))
Row = Row + 1
Next I
End Sub
And below the output:
It seems that the code functions good when it is compairing integer value and not with decimals.
PS: I do not want to loop on column A cells, as there could be more than 100k values and it will be so slowly
You can pull everything into variant arrays, which will be quicker on larger datasets than COUNTIFS:
Sub Compair()
With ActiveSheet
Dim rngArr As Variant
rngArr = Intersect(.UsedRange, .Range("A2", .Cells(.Rows.Count, 1))).Value2
Dim outArr() As Variant
ReDim outArr(1 To Int((141.5 - 139.5) / 0.25) + 1, 1 To 2)
Dim I As Double
Row = 1
For I = 139.5 To 141.5 Step 0.25
outArr(Row, 1) = I
outArr(Row, 2) = 0
Dim j As Long
For j = 1 To UBound(rngArr, 1)
If rngArr(j, 1) < I Then outArr(Row, 2) = outArr(Row, 2) + 1
Next j
Row = Row + 1
Next I
.Range("C3").Resize(UBound(outArr, 1), 2).Value = outArr
End With
End Sub
Your code is correct
just confirm your region, if you need the comas as decimal separatos configure your Windows format, and your excel format
Windows Format
https://www.windowscentral.com/how-change-date-and-time-formats-windows-10
Excel Format
https://edu.gcfglobal.org/en/excel2013/formatting-cells/1/
Sub Compair()
Range("A16").Select
Dim I As Double
Row = 16
For I = 139.5 To 141.5 Step 0.25
Cells(Row, 3) = I
Cells(Row, 4) = Application.WorksheetFunction.CountIf(Range("A:A"), "<" & Cells(Row, 3))
Row = Row + 1
Next I
End Sub

Parsing excel string of numbers using vba

I am trying parse a number string and create rows accordingly. On the left of the Example Data picture is an example of the input data with the right being my desired output. I am wanting to insert a unique row of data for each digit within the brackets for each number combination.
Here is an example of the code I used to try to solve the problem.
Option Explicit
Sub example()
Dim num As Variant
Dim x As Variant
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim m As Integer
Dim test As Variant
Dim test2 As Variant
Dim count As Integer
m = 0
For i = 1 To 3
num = Range("C" & 5 + i + m).Value
For j = 1 To Len(num)
test = Mid(num, j)
If Left(Mid(num, j), 1) = "[" Then
For k = 1 To Len(num) - (j + 1)
m = m + 1
Range("C" & 5 + m + i - 1).EntireRow.Insert
test2 = Left(Mid(num, j + k), 1)
Range("C" & 5 + m + i - 1).Value = Left(num, j - 1) + test2
Next k
End If
Next j
Next i
End Sub
Please consider using the following script:
Sub splitcombinations()
Dim rngCell As Range
Set rngCell = ThisWorkbook.Sheets(1).Range("A2")
Dim strCombinationDigits As String, strBaseDigits As String
Dim intCombinationDigitsLen As Integer
Dim x As Integer
Do While rngCell.Value2 <> ""
If InStr(rngCell.Value2, "[") > 0 Then
strCombinationDigits = Mid(rngCell.Value2, InStr(rngCell.Value2, "[") + 1, InStr(rngCell.Value2, "]") - InStr(rngCell.Value2, "[") - 1)
intCombinationDigitsLen = Len(strCombinationDigits)
strBaseDigits = Left(rngCell.Value2, InStr(rngCell.Value2, "[") - 1)
ActiveSheet.Range(rngCell.Offset(1, 0), rngCell.Offset(intCombinationDigitsLen - 1, 0)).EntireRow.Insert
For x = 1 To intCombinationDigitsLen
rngCell.Offset(x - 1, 0).Value2 = strBaseDigits & Mid(strCombinationDigits, x, 1)
rngCell.Offset(x - 1, 1).Value2 = rngCell.Offset(0, 1).Value2
rngCell.Offset(x - 1, 2).Value2 = rngCell.Offset(0, 2).Value2
Next
End If
Set rngCell = rngCell.Offset(intCombinationDigitsLen , 0)
Loop
End Sub

Resources