How to convert currency into double in VBA? - ms-access

I have three textboxes and I get their value like this:
Dim X, Y, W As Double
X = DLookup("Summ", "tblPlatej", "ID= " & Form_frmPlatej!ID)
Y = DLookup("Deposit_before", "tblPlatej", "ID= " & Form_frmPlatej!ID)
W = DLookup("Monthly_payment", "tblPlatej", "ID= " & Form_frmPlatej!ID)
But when I change the value of textbox like this
Form_frmPlatej.Deposit_before = X - W + Y
I get a Type mismatch error. All textboxes are currency. How do I calculate new record and put that number in the "Deposit_before" textbox?
Summ, Deposit_before, Monthly_payment are currency data type in my table. Deposit_before is mostly negative.
Here is my whole code for button click
Private Sub Command13_Click()
a1 = DLookup("Inhabitant", "tblClient", "ID = " & Form_frmMain!ID)
B1 = DLookup("PriceTBO", "tblPrice")
c1 = DLookup("Republican", "tblClient", "ID = " & Form_frmMain!ID)
d1 = DLookup("Regional", "tblClient", "ID = " & Form_frmMain!ID)
e1 = DLookup("Local", "tblClient", "ID = " & Form_frmMain!ID)
A = DLookup("IDP", "tblPlatej", "ID= " & Form_frmPlatej!ID)
B = DLookup("Type_of_payment", "tblPlatej", "ID= " & Form_frmPlatej!ID)
C = DLookup("Year", "tblPlatej", "ID= " & Form_frmPlatej!ID)
D = DLookup("Month", "tblPlatej", "ID= " & Form_frmPlatej!ID)
Y = DLookup("Deposit_before", "tblPlatej", "ID= " & Form_frmPlatej!ID) // Problem here
W = DLookup("Monthly_payment", "tblPlatej", "ID= " & Form_frmPlatej!ID) //Problem here
X = DLookup("Summ", "tblPlatej", "ID= " & Form_frmPlatej!ID)
i = Form_frmPlatej.Month.ListIndex
j = Form_frmPlatej.Year.ListIndex
den = DLookup("Date", "tblPlatej", "IDP = " & Form_frmPlatej!IDP)
If X <> " " Then
With Me.Recordset
If Me.Recordset.BOF = False And Me.Recordset.EOF = False Then
.MoveFirst
End If
.AddNew
.Edit
Form_frmPlatej.Deposit_before = X - W + Y //Problem here
Form_frmPlatej.IDP = A + 1
Form_frmPlatej.Type_of_payment = B
If i = 11 Then
Form_frmPlatej.Year = Year.ItemData(j + 1)
i = -1
Else
Form_frmPlatej.Year = Year.ItemData(j)
End If
Form_frmPlatej.Month = Month.ItemData(i + 1)
Form_frmPlatej.Date = DateAdd("m", 1, den)
If c1 <> 0 Then
Form_frmPlatej.Monthly_payment = (a1 * B1) - (c1 * (a1 * B1)) / 100
ElseIf d1 <> 0 Then
Form_frmPlatej.Monthly_payment = (a1 * B1) - (d1 * (a1 * B1)) / 100
ElseIf e1 <> 0 Then
Form_frmPlatej.Monthly_payment = (a1 * B1) - (e1 * (a1 * B1)) / 100
Else
Form_frmPlatej.Monthly_payment = a1 * B1
End If
.Update
End With
Else
MsgBox ("Please enter number")
End If
End Sub
I am completely confused.

I bet your problem is the following. When you say this:
Dim X, Y, W As Double
you think you've done this:
Dim X As Double, Y As Double, W As Double
but what you've really done is this:
Dim X
Dim Y
Dim W As Double
This is a classic VBA mistake. Most VBA programmers have made it, and that's why most VBA programmers fall back on declaring only one variable per Dim statement (i.e. one per line). Otherwise it's way too easy to make that mistake, and difficult to spot it afterwards.
So with Dim X and Dim Y you've implicitly declared X and Y as Variant type (equivalent to Dim X As Variant and Dim Y As Variant).
Why does this matter? When you then say this:
X = DLookup("Summ", "tblPlatej", "ID= " & Form_frmPlatej!ID)
Y = DLookup("Deposit_before", "tblPlatej", "ID= " & Form_frmPlatej!ID)
maybe one of those two DLookup unexpectedly returns something that isn't a number, for example a string. Your variant X or Y will accept this without complaining; the Variant acquires the type of the thing on the right hand side of the assignment.
However, when you try to do math with these values, X - W + Y will throw a type mismatch error if X and/or Y is a string.
See also this earlier answer of mine, from which I reused some of the wording: https://stackoverflow.com/a/11089684/119775

Related

Guidance, VBA - SELECT CASE clean up

This SELECT CASE scenario is working for me but I think the code can be more friendly ... any advice would be very helpful.
Select Case True 'select case where worker name and action is true then in each case RSworkhours.addnew
Case Me.Worker1.Value <> "" And Me.fw1a1 = 1
With RsWorkHours
.AddNew
!WorkerID = Me.Worker1
!Date = Me.TxtDate
!StandardTime = Me.w1a1s
!Overtime = Me.w1a1o
!Doubletime = Me.w1a1d
!ScaffoldID = Me.cboScaffnum
.Update
End With
Me.fw1a1 = 0
GoTo WorkerHours
Case Me.Worker1.Value <> "" And Me.fw1a2 = 1
With RsWorkHours
.AddNew
!WorkerID = Me.Worker1
!Date = Me.TxtDate
!StandardTime = Me.w1a2s
!Overtime = Me.w1a2o
!Doubletime = Me.w1a2d
!ScaffoldID = Me.cboScaffnum
.Update
End With
Me.fw1a2 = 0
GoTo WorkerHours
The Code iterates through this Select Case 80 times, if there are 16 workers and each have 5 actions.
I was thinking maybe having a loop that modifies the number within the arguments like:
for each x to 16
for each y to 5
If Me.worker & x & .Value <> "" And Me.fw & x & a & y Then
With Recordset
.AddNew
'insert stuff
.Update
End With
End If
Next y
Next x
Does anyone have any insight?
Thank you in advance.
-Matt
You can access all controls by their name from the Controls collection.
Just pass the name of a control and you will get to that control - the name is a string and can of course be dynamic.
Dim x As Long, y As Long
Dim WorkerX As Control, wXaYs As Control, wXaYo As Control, wXaYd As Control
For x = 1 To 16
For y = 1 To 5
Set WorkerX = Me.Controls("Worker" & x)
Set wXaYs = Me.Controls("w" & x & "a" & y & "s")
Set wXaYo = Me.Controls("w" & x & "a" & y & "o")
Set wXaYd = Me.Controls("w" & x & "a" & y & "d")
If WorkerX.Value > "" And wXaYs.Value > "" Then
With Recordset
.AddNew
!WorkerID = WorkerX.Value
!Date = Me.TxtDate
!StandardTime = wXaYs.Value
!Overtime = wXaYo.Value
!Doubletime = wXaYd.Value
!ScaffoldID = Me.cboScaffnum
.Update
End With
End If
Next y
Next x

Access vba random function not working

I have a sub that is supposed to take a number of assignments (this number changes daily) and assign them to 7 associates. There are some conditions to this:
If the # of assignment is less than 7, it assigns all of them to a random associate.
If the # is divisible by 7, it assigns an equal number to each.
If it is not divisible by 7, it assigns equally and then gives the remainder to a random associate.
The problem is the random part. I really don't understand how random works in vba, or at least it seems like it should be super easy, but it's not (maybe). But I have this written and it's not working. (Associates(Int(Rnd() * 7) + 1)). Here is my relevant code:
Earlier in the sub I create an array of the associates and I use some dcounts to get the total assignments for that day:
Dim Associates(6) As Integer
Associates(0) = 4687 'Anita
Associates(1) = 4247 'Alberto
Associates(2) = 2167 'Jeff
Associates(3) = 4334 'Lisa
Associates(4) = 4441 'Carrie
Associates(5) = 2052 'Bobby
Associates(6) = 4657 'Simona
'
Dim Person As Variant
'
TotalPop = DCount("LNo", "qry_PT_Assign")
FractionPop = Int(TotalPop / 7)
LeftPop = TotalPop - (FractionPop * 7)
'
and then I try to actually assign them.
'Assign to Associates
If TotalPop < 7 Then
DoCmd.RunSQL "UPDATE tbl_Assignments SET AudTellerID = " & (Associates(Int(Rnd() * 7) + 1)) & " WHERE AudTellerID IS NULL"
ElseIf LeftPop = 0 Then
For Each Person In Associates
DoCmd.RunSQL "UPDATE tbl_Assignments SET AudTellerID = " & Person & " WHERE LNo IN (SELECT TOP " & FractionPop & " LNo FROM tbl_Assignments WHERE AudTellerID Is Null)"
Next
Else
For Each Person In Associates
DoCmd.RunSQL "UPDATE tbl_Assignments SET AudTellerID = " & Person & " WHERE LNo IN (SELECT TOP " & FractionPop & " LNo FROM tbl_Assignments WHERE AudTellerID Is Null)"
Next
DoCmd.RunSQL "UPDATE tbl_Assignments SET AudTellerID = " & (Associates(Int(Rnd() * 7) + 1)) & " WHERE AudTellerID IS NULL"
End If
As per my comment, try generating the random number first, assign it to a variable, and then pass the variable into Associates().
Dim rndInt as Integer
rndInt = Int(Rnd() * 7) + 1
Associates(rndInt)
Then as #Chips said, you can use
Debug.print rndInt
Or
Msgbox rndInt
to check its value
That way you'll be able to see what number is actually being generated
The trick is to use a negative seed that changes constantly.
So add a time dependant seed to Rnd which changes for every unique id like in this sample select query:
SELECT
Table1.ID,
Table1.SomeField,
Table1.AnotherField,
Rnd(-Timer()*[ID]) AS RandomIndex
FROM
Table1
ORDER BY
Rnd(-Timer()*[ID]);
In your code, the expression could be something like this:
.. " & (Associates(Int(Rnd(-Timer()*" & [ID] & ") * 7) + 1)) & " ..

timer triggered mysql with while statement - not fetching all data

I have developed a winform which requires constant contact with a mysql database to make sure all "calls" are fetched and up to date - the problem I have run into is that my listview is only being populated with 1 line per timer click. this timer should activate a while statement that should process all data and in fact should also be clearing the listview to receive updated data. why is my listview only populating 1 item per tick?
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
ListView2.Items.Clear()
con.ConnectionString = "server=localhost;" _
& "user id=username;" _
& "password=password;" _
& "database=DMT"
adptr = New MySqlDataAdapter("SELECT * , s.fid AS sfid, s.name AS sname, s.faddress AS sfaddress, s.fcity AS sfcity, s.fstate AS sfstate, s.fcontnumb AS sfcontnumb, s.fcontname AS sfcontname, s.fcontract AS sfcontract, d.fid AS dfid, d.name AS dname, d.faddress AS dfaddress, d.fcity AS dfcity, d.fstate AS dfstate, d.fcontnumb AS dfcontnumb, d.fcontname AS dfcontname, d.fcontract AS dfcontract FROM calls c LEFT JOIN facilities s ON c.Scene = s.fid LEFT JOIN facilities d ON c.Dest = d.fid WHERE putime < now( ) + INTERVAL 12 HOUR && Rdisp IS NULL ORDER BY putime desc", con)
Try
adptr.Fill(pendrun)
Catch err As Exception
Dim strError As String = "Exception: & err.ToString()"
End Try
If pendrun.Rows.Count > 0 Then
While pop < pendrun.Rows.Count - 1
TempStr(0) = pendrun.Rows(pop)("RID")
Select Case pendrun.Rows(pop)("Utype")
Case 1
TempStr(1) = "BLS Ambulance"
Case 2
TempStr(1) = "ALS Ambulance"
Case 3
TempStr(1) = "SCT Ambulance"
Case 4
TempStr(1) = "Wheelchair Van"
Case 5
TempStr(1) = "Taxi"
End Select
Select Case pendrun.Rows(pop)("Curgency")
Case 1
TempStr(2) = "Scheduled"
Case 2
TempStr(2) = "Non-Scheduled"
Case 3
TempStr(2) = "ASAP"
Case 4
TempStr(2) = "STAT"
End Select
TempStr(3) = pendrun.Rows(pop)("Pname")
TempStr(4) = pendrun.Rows(pop)("Texttime")
TempStr(5) = pendrun.Rows(pop)("sname") & " - " & pendrun.Rows(pop)("sfaddress") & ", " & pendrun.Rows(pop)("sfcity") & ", " & pendrun.Rows(pop)("sfstate")
TempStr(6) = pendrun.Rows(pop)("dname") & " - " & pendrun.Rows(pop)("dfaddress") & ", " & pendrun.Rows(pop)("dfcity") & ", " & pendrun.Rows(pop)("dfstate")
TempNode = New ListViewItem(TempStr)
ListView2.Items.Add(TempNode)
pop += 1
End While
End If
End Sub
I have verified it is in fact linked to the timer directly (1 item per tick) by varying the timer from 1 second to 30 seconds and it does directly change this.
Your code never resets "pop"'s value. That's what's causing trouble, I'm pretty sure. It keeps incrementing 1 value every tick, never able to do all of them because pop is set to one less than the while's max.

MS Access / VBA Code: How to combine these 2 procedures

I'm a VBA novice trying to combine these two sub procedures into a single procedure - can anyone provide how to do this?
Basically, I'm trying to add an image to an Access report (in the 2nd code block - it's checking/creating the image path) - where there is already a check for other information from the database product record.
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim x$, y$, i%
x = ""
For i = 1 To 10
y = Me("txtOp" & i) & ""
If y > "" Then
If x > "" Then x = x & " "
x = x & "Option " & i & ": " & y
End If
Next
If x > "" Then x = CR & x
Me.txtProduct = Me.txtItem & "" & x
If Me.Adjustment Then
Me.txtShowSKU = ""
Else
Me.txtShowSKU = Me.txtSKU
End If
Dim x, y, OK%
OK = False
x = Me.txtImage & ""
If x > "" Then
y = getparm("ImagePath")
If y > "" Then
If Right$(y, 1) <> "\" Then y = y & "\"
If Left$(x, 1) = "\" And Len(x) > 1 Then x = Mid$(x, 2)
If FileExists(y & x) Then OK = True: x = y & x
End If
If OK Then
Me.imgProd.visible = True
Me.imgProd.Picture = x
Else
Me.imgProd.visible = False
End If
End If
End Sub
I think this should work:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim x as String
Dim y as String
Dim i as Integer
For i = 1 To 10
y = Me("txtOp" & i) & ""
If y > "" Then
If x > "" Then x = x & " "
x = x & "Option " & i & ": " & y
End If
Next
If x > "" Then x = CR & x
Me.txtProduct = Me.txtItem & "" & x
If Me.Adjustment Then
Me.txtShowSKU = ""
Else
Me.txtShowSKU = Me.txtSKU
End If
Dim OK as Boolean
y = ""
x = Me.txtImage & ""
If x > "" Then
y = getparm("ImagePath")
If y > "" Then
If Right$(y, 1) <> "\" Then y = y & "\"
If Left$(x, 1) = "\" And Len(x) > 1 Then x = Mid$(x, 2)
If FileExists(y & x) Then OK = True: x = y & x
End If
If OK Then
Me.imgProd.visible = True
Me.imgProd.Picture = x
Else
Me.imgProd.visible = False
End If
End If
End Sub

all possible combinations

i need to get a list of all possible combinations, not permutations.
to make sure i have the right name, 123 and 321 to me are the same thing and should only be listed once.
the code below does what i need but i can't convert it into MS Access vba.
i'm sorry, i know this is basic and it has been asked a million times but i can't find anything for MS Access that works for me.
Sub test_print_nCr()
print_nCr 7, 3, Range("A1")
End Sub
2.
Public Function print_nCr(n As Integer, r As Integer, p As Range)
c = 1
internal_print_nCr n, r, p, 1, 1
End Function
3.
Public Function internal_print_nCr(n As Integer, r As Integer, ByVal p As Range, Optional i As Integer, Optional l As Integer) As Integer
' n is the number of items we are choosing from
' r is the number of items to choose
' p is the upper corner of the output range
' i is the minimum item we are allowed to pick
' l is how many levels we are in to the choosing
' c is the complete set we are working on
If n < 1 Or r > n Or r < 0 Then Err.Raise 1
If i < 1 Then i = 1
If l < 1 Then l = 1
If c < 1 Then c = 1
If r = 0 Then
p = 1
Exit Function
End If
Dim x As Integer
Dim y As Integer
For x = i To n - r + 1
If r = 1 Then
If c > 1 Then
For y = 0 To l - 2
If p.Offset(c - 1, y) = "" Then p.Offset(c - 1, y) = p.Offset(c - 2, y)
Next
End If
p.Offset(c - 1, l - 1) = x
c = c + 1
Else
p.Offset(c - 1, l - 1) = x
internal_print_nCr n, r - 1, p, x + 1, l + 1
End If
Next
End Function
thank you again
I am not sure if this is the best method to do this, but I would use a kind of binary representation. For instance, consider the word "boy" with the number of letters n=3. This word has three letters, so you can use something like this:
001 = y,
010 = o,
011 = oy,
100 = b,
101 = by,
110 = bo,
111 = boy.
The left side can be done with a loop from i=1 to power(2,n)-1 and transforming i to a number in the binary basis. So, the only thing you have to do is to use the non null positions to build your combinations.
Probably there is something more interesting than this in Knuth.
i found this code here, and it gives me exactly what i need. you just have to create a table with numbers from 1-100. instructions at the link below
enter link description here
thank you everyone
Public Sub buildquery(strN As String, K As Integer)
Dim qd As DAO.QueryDef
Dim intI As Integer
Dim strsql As String
Dim strSelect As String
Dim strFrom As String
Dim strWhere As String
Set qd = CurrentDb.QueryDefs("QN")
qd.sql = "SELECT N FROM tblN WHERE N IN (" & strN & ")"
Set qd = Nothing
strSelect = "SELECT QN.N "
strFrom = "FROM QN "
strWhere = "WHERE QN_1.N > QN.N "
For intI = 1 To K - 1
strSelect = strSelect & ", QN_" & intI & ".N AS N" & intI & " "
strFrom = strFrom & ", QN AS QN_" & intI & " "
If intI < K - 1 Then
strWhere = strWhere & " AND QN_" & intI + 1 & ".N > QN_" & intI & ".N "
End If
Next
strsql = strSelect & " INTO tblCombinations " & strFrom & strWhere
DoCmd.SetWarnings False
DoCmd.RunSQL strsql
DoCmd.SetWarnings True
End Sub
then test
Public Sub testbuildquery()
buildquery "1,2,3,4,5,6,7", 3
End Sub