Cannot subtract value from VBA property - ms-access

I have the following code, I am trying to subtract .5 from the text53 object if the date value is higher than 15, but I keep getting the error "Invalid Use of property" error
Private Sub Report_Load()
Dim Maxdate As Integer, LValue As Integer, LValue2 As Integer
Dim Mvalue As Integer, Dvalue As Date, RateVal As Integer
LValue2 = 0.5
RateVal = Me.Text31.Value * Me.Text27.Value
Dvalue = Me.Text43
Mvalue = DateDiff("m", Me.Text41, Me.Text43)
If Format(Dvalue, "DD") >= 15 Then Me.Text53 - LValue2
Me.Text53 = Mvalue
Me.Text51 = Me.Text53 * RateVal
End Sub

Try this:
Private Sub Report_Load()
Dim Maxdate As Integer
Dim LValue As Integer
Dim LValue2 As Single
Dim Mvalue As Integer
Dim Dvalue As Date
Dim RateVal As Integer
LValue2 = 0.5
RateVal = Me.Text31.Value * Me.Text27.Value
Dvalue = Me.Text43
Mvalue = DateDiff("m", Me.Text41, Me.Text43)
Me.Text53 = Mvalue
If Format(Dvalue, "DD") >= 15 Then
Me.Text53 = Me.Text53 - LValue2
End If
Me.Text51 = Me.Text53 * RateVal
End Sub
I think your main problem is this: Me.Text53 - LValue2
You need to assign that value to something. By itself it will only produce errors. Changing that line to Me.Text53 = Me.Text53 - LValue2 or Me.Text53 = Mvalue - LValue2 would fit the bill.
Other things of note: you can't assign a decimal to an integer datatype, it'll round it to a whole number. Also, assigning Mvalue to Text53 needs to happen before your conditional subtraction of 0.5 or that part will just get overwritten.

Related

Access VBA recordCount returning 0 when records exist

I'm attempting to create a function to add n workdays to a date. This obviously needs to take into account weekends and holidays. The weekend part works fine, but I used a table to list all of the holidays and I can't get my query to pull the accurate recordCount. It insists the count is always zero. Here is my code:
Public Function dateAddNoWeekends(dt1 As Date, genDate As Integer)
Dim i As Integer
Dim date1 As Date
Dim date2 As Date
Dim holidays As Boolean
Dim isWeekday As Boolean
Dim dayOfWeek As Integer
Dim numDays As Integer
Dim db As Database
Dim rs As DAO.Recordset
Dim sql As String
Set db = CurrentDb
date1 = dt1
date2 = date1
i = 0
numDays = genDate
sql = "SELECT * FROM Holidays WHERE holidayDate = " & date2
Set rs = db.OpenRecordset(sql)
Debug.Print date2
Do While i < numDays
If Not isWeekday Then date2 = date2 + 1
dayOfWeek = Weekday(date2)
If rs.RecordCount > 0 Then
Debug.Print rs.RecordCount
holidays = True
Else
holidays = False
Debug.Print rs.RecordCount
End If
If dayOfWeek > 1 And dayOfWeek < 7 And holidays = False Then
If i < numDays - 1 Then date2 = (date2 + 1)
isWeekday = True
i = i + 1
Else: isWeekday = False
End If
Loop
rs.Close
Debug.Print date2
To solve this, I declared a variable at the top of the loop (so that it would update correctly each time) and assigned a Dcount function to count from date2 to date2.

Moving through the Recordset in Access VBA

I have a simple function using Excel VBA for calculating volatility. It takes as inputs a column of numbers (Zeros) and two dates. The code is:
Function EWMA(Zeros As Range, Lambda As Double, MarkDate As Date, MaturityDate As Date) As Double
Dim vZeros() As Variant
Dim Price1 As Double, Price2 As Double
Dim SumWtdRtn As Double
Dim I As Long
Dim m As Double
Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double
vZeros = Zeros
m = Month(MaturityDate) - Month(MarkDate)
For I = 2 To UBound(vZeros, 1)
Price1 = Exp(-vZeros(I - 1, 1) * (m / 12))
Price2 = Exp(-vZeros(I, 1) * (m / 12))
LogRtn = Log(Price1 / Price2)
RtnSQ = LogRtn ^ 2
WT = (1 - Lambda) * Lambda ^ (I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Next I
EWMA = SumWtdRtn ^ (1 / 2)
End Function
The main feature enabling the function to work is the For loop. I want to re-create this in Access VBA using recordset objects. The recordset has the same fields as the Excel spreadsheet. I'm not exactly sure how to convert the code over, though. Here is what I have so far:
Function EWMA(rsCurve As Recordset, InterpRate As Double, Lambda As Double) As Double
Dim vZeros() As Variant
Dim Price1 As Double, Price2 As Double
Dim SumWtdRtn As Double
Dim I As Long
Dim mat As Date
Dim mark As Date
Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double
CurveInterpolateRecordset = Rnd()
If rsCurve.RecordCount <> 0 Then
vZeros = CVar(rsCurve.Fields("CurveInterpolateRecordset"))
mat = CDate(rsCurve.Fields("MaturityDate"))
mark = CDate(rsCurve.Fields("MarkDate"))
m = Month(mat) - Month(mark)
For I = 2 To UBound(vZeros, 1)
Price1 = Exp(-vZeros(I - 1, 1) * (m / 12))
Price2 = Exp(-vZeros(I, 1) * (m / 12))
LogRtn = Log(Price1 / Price2)
RtnSQ = LogRtn ^ 2
WT = (1 - Lambda) * Lambda ^ (I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Next I
EWMA = SumWtdRtn ^ (1 / 2)
End If
Debug.Print EWMA
End Function
The function is called in an earlier subroutine in Access. What am I missing in order to move through the recordset in Access, similar to looping through the spreadsheet in Excel VBA?
The easiest method would be to use GetRows to pull an array from your recordset:
Recordset.GetRows Method
Then the new code would be nearly a copy-n-paste of your proven code starting with basically this:
vZeros = rsCurve.GetRows(rsCurve.RecordCount)
As a side note you wouldn't need CDate here:
mat = rsCurve.Fields("MaturityDate").Value
Here are some basics about using a recordset.
Dim rs As New ADODB.Recordset
'Add fields to your recordset for storing data.
With rs
.Fields.Append "Row", adInteger
.Fields.Append "ColumnName2", adChar, 30
.Fields.Append "ColumnName3", adInteger
.Open
End With
Add records to it manually
rs.AddNew
rs.Fields("Row").Value = 1
rs.Fields("ColumnName2").Value = "Put some value in"
rs.Update
rs.AddNew
rs.Fields("Row").Value = 2
rs.Fields("ColumnName2").Value = "Put another value in"
rs.Update
You can also populate it with a query of a table.
Move to the begining of the recordset
If rs.EOF = False Then
rs.MoveFirst
End If
Loop through the recordset
Do While rs.EOF = False
msgbox(rs.Fields("ColumnName2").Value)
rs.MoveNext
Loop

Number in sequence in Ms Access or Excel in one field

I am trying to create a query which can give me a list of numbers in one field when I provide the range as Min and Max.
E.g Min = 30
Max = 35
Result: 30,31,32,33,34,35
The result should be in one field.
Farrukh Khan
I think the answer provided by Gustav, is a start. This is how it needs to be modified to get what you need.
First, create a VBA user defined function in a standard module. Like so,
Public Function ListOfNumbers(FirstValue As Long, LastValue As Long) As String
Dim Index As Integer, tmpStr As String
If LastValue < FirstValue Then
ListOfNumbers = vbNullString
Exit Function
End If
For Index = FirstValue To LastValue
tmpStr = tmpStr & Index & ", "
Next
ListOfNumbers = Left(tmpStr, Len(tmpStr) - 2)
End Function
Remember the Module name should not be the same as the Function name. Then the SQL would be something like,
PARAMETERS
MinVal Long,
MaxVal Long;
SELECT
ListOfNumbers(MinVal, MaxVal);
You can use a function like this:
Public Function ListOfNumbers(ByVal FirstValue As Integer, ByVal LastValue As Integer) As String
Dim NumberList() As String
Dim Index As Integer
ReDim NumberList(FirstValue To LastValue)
For Index = FirstValue To LastValue
NumberList(Index) = CStr(Index)
Next
ListOfNumbers = Join(NumberList, ",")
End Function

Invalid cast from Datetime to Decimal

I am trying to sum a column of Times for total hours as shown below:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If DataGridView1.RowCount > 1 Then
Dim IntTotalHours As Decimal = 0
Dim IntPricePerhour As Integer = 0
For Index As Integer = 0 To DataGridView1.RowCount - 1
IntTotalHours += Convert.ToDecimal(DataGridView1.Rows(Index).Cells(2).Value)
Next
TextBox1.Text = IntTotalHours
TextBox3.Text = FormatCurrency(IntTotalHours * 15)
End If
End Sub
But I get an error on the line:
IntTotalHours += Convert.ToDecimal(DataGridView1.Rows(Index).Cells(2).Value)
How do I convert Time to decimal using datagridview?

Assigning Value of a formula to a cell

I have a data chart with many products.
I want to filter each type of product, calculate the total quantity of that type as well as the number of product inside that type. And finally put the value of that function into a column in Sheet 2.
Here is the code. The quantity column is column U. It gets error 1004: Argument not optional, and it highlights the Set .... = FunctionR1C1 = .... part
Function T_Quantity()
ActiveSheet.Range("U").Select
Total = FunctionR1C1 = "=subtotal(9,C[0])"
End Function
Function T_Count(ref_column)
ActiveSheet.Range("U").Select
Total = FunctionR1C1 = "=subtotal(2,C[0])"
End Function
Sub Total_Count()
Dim my_array() As String
Dim iLoop As Integer
Dim iCount As Integer
iCount = 1
ReDim my_array(3)
my_array(0) = "=M1747B"
my_array(1) = "=M1747C"
my_array(2) = "=M1766B"
For iLoop = LBound(my_array) To UBound(my_array)
ActiveSheet.Range("A:BB").Select
Selection.AutoFilter Field:=15, Criteria1:=my_array
Application.CutCopyMode = False
'Calculate the quantity and no of lot, put in colum A,B in sheet 2'
Set Worksheets("Sheet2").Cells(iCount, 1) = T_Quantity()
Set Worksheets("Sheet2").Cells(iCount, 2) = T_Count()
Application.CutCopyMode = False
iCount = iCount + 1
Next iLoop
End Sub
Let's start with this and see if that gets you any closer to your desired results:
Sub Total_Count()
Dim my_array() As String
Dim iLoop As Integer
Dim iCount As Integer
iCount = 1
ReDim my_array(3)
my_array(0) = "=M1747B"
my_array(1) = "=M1747C"
my_array(2) = "=M1766B"
For iLoop = LBound(my_array) To UBound(my_array)
ActiveSheet.Range("A:BB").Select
Selection.AutoFilter Field:=15, Criteria1:=my_array
Application.CutCopyMode = False
'Calculate the quantity and no of lot, put in colum A,B in sheet 2'
Worksheets("Sheet2").Cells(iCount, 1).FormulaR1C1 = "=subtotal(9,C[0])"
Worksheets("Sheet2").Cells(iCount, 2).FormulaR1C1 = "=subtotal(2,C[0])"
Application.CutCopyMode = False
iCount = iCount + 1
Next iLoop
End Sub
What I changed:
Eliminate the Set keyword when working with cell objects on the Worksheet. Set is used to assign object variables.
Since the functions you call appear to be simply setting the cell's FormulaR1C1 property, I add the .FormulaR1C1 property to those lines, and then, instead of using a Function, I simply put the function's R1C1 notation directly in this subroutine.