Dlookup function in access? - vba

I'm trying to look up some values with my dlookup function in Access. I'm going into queries and pulling data with 2 different criteria. So I pull data from a query then I'm inserting it into a temp table. I'm having a hard time avoiding NULL values.
With rs2
While Not .EOF
lngVendorID = rs2("CompanyID")
lngUnitPrice = rs2("UnitPrice")
'Beginning Count
lngBegCount = (DLookup("BegCount", "qryBegInv", "UnitPrice = " & [lngUnitPrice] & " AND CompanyID = " & [lngCompanyID] & ""))
If IsNull(lngBegCount) Or lngBegCount = "" Then
lngBegCount = 0
End If
.Edit
rs2("BegInvCount") = lngBegCount
.Update
rs2.MoveNext
Wend
I keep getting a variety of errors. Basically I want to see if DLOOKUP value is null, if it is, then use a 0 and insert that into the rs2("BegInvCount"), if it isn't null, then insert the lngBegCount into rs2("BegInvCount").

Use the Nz() function to handle NULL values:
lngBegCount = Nz(DLookup("BegCount", "qryBegInv", _
"UnitPrice = " & lngUnitPrice & " AND CompanyID = " & lngCompanyID & ""), 0)
You don't need brackets around variables.

Related

Setting Max ID criteria in Ms Access SQL

This query does not run at the beginning. Could someone please help look at what is wrong?
If there is any other way to achieve this kindly suggest.
strSQL1 = "SELECT * FROM PharmSales WHERE HospitalNo='" & Me.txtRegNo &
"' And TDate = #" & Format(Me.txtTDate, "M\/dd\/yyyy") &
"# AND SalesItem1 = '" & Me.txtSalesItem1 & "' And
PharmSalesID=
(SELECT MAX(PharmSalesID) FROM PharmSales)"
Set pr = db.OpenRecordset(strSQL1)
With pr
If Not .BOF And Not .EOF Then 'Ensure that the recordset contains records
.MoveLast
.MoveFirst
If .Updatable Then 'To ensure record is not locked by another user
.Edit 'Must start an update with the edit statement
If IsNull(![TotalPaid]) = True And Me.txtGrand_TotalPay.Value >= Me.txtSalesAmt1.Value Then
![DispQty1] = Nz(![DispQty1] + Me.txtSalesQty1.Value, 0)
.Update
ElseIf IsNull(![TotalPaid]) = False And (Me.txtGrand_TotalPay.Value - Me.txtSalesAmt1.Value) >= (txtGrand_TotalFee - Me.txtGrand_TotalPay.Value + Me.txtSalesAmt1.Value) Then
![DispQty1] = Nz(![DispQty1] + Me.txtSalesQty1.Value, 0)
.Update
Else: MsgBox ("Insufficient balance!")
End If
End If
End If
pr.Close
Set pr = Nothing
Set db = Nothing
End With
End Sub
Your SQL checks multiple criteria, but your subquery doesn't have any of these criteria, so it will probably select a record that doesn't conform to your other criteria, causing your recordset to always be empty.
You need to add these criteria to the subquery, not the main query.
Since the subquery will just return one record, you don't have to add them to both.
strSQL1 = "SELECT * FROM PharmSales" & _
" WHERE PharmSalesID=" & _
" (SELECT MAX(PharmSalesID) FROM PharmSales" & _
" WHERE HospitalNo='" & Me.txtRegNo & _
"' And TDate = #" & Format(Me.txtTDate, "M\/dd\/yyyy") & _
"# AND SalesItem1 = '" & Me.txtSalesItem1 & "')"

Access SELECT statements giving me errors

I'm trying to populated a Temp Table with some data from my queries. The problem I came across is trying to SELECT certain data using 2 WHERE criteria. As long as I have one, it pulls up the correct data and populates it as such. However, when I try to filter by two criteria (which I need to do in order to pupulate info in correct rows), it gives me an error "TYPE MISMATCH". What happens is, after my first criteria WHERE = " & lngCompanyID - There is no quote at the end of it, however, when I add another criteria... WHERE CompanyID = " & lngCompanyID and UnitPrice = " & lngUnitPrice " <--- there is a double quote at end of it and I think it's stopping it from passing the value. This is what the code looks like
With rs2
While Not .EOF
rs2.Edit
lngCompanyID = rs2("CompanyID")
lngUnitPrice = rs2("UnitPrice")
strSQL2 = "SELECT SumOfInvQty from qryAddx WHERE InvValue = " & lngUnitPrice And CompanyId = " & lngCompanyID"
Set rs3 = CurrentDb.OpenRecordset(strSQL2)
If rs3.recordCount > 0 Then
rs2("Added") = rs3("sumofinvqty")
rs2.Update
End If
rs2.MoveNext
Set rs3 = Nothing
Wend
End With
You're not continuing you're concatenation of the string correctly. Try this instead:
With rs2
While Not .EOF
rs2.Edit
lngCompanyID = rs2("CompanyID")
lngUnitPrice = rs2("UnitPrice")
strSQL2 = "SELECT SumOfInvQty from qryAddx WHERE InvValue = " & lngUnitPrice & " And CompanyId = " & lngCompanyID
Set rs3 = CurrentDb.OpenRecordset(strSQL2)
If rs3.recordCount > 0 Then
rs2("Added") = rs3("sumofinvqty")
rs2.Update
End If
rs2.MoveNext
Set rs3 = Nothing
Wend
End With

Performing adding/subtracting in Access table with VBA?

I'm populating a TempTable in Access using data from the queries. I have populated 3 columns (Add, Delete, Buy) so far and I'm trying to find the total of the three of them. Thing is, a lot of don't have values, and some of them are negative values. How would I go about addnig them? I have data in rs2("Add"), rs2("Delete"), and rs2("Buy"). So all ADD values (if there are any are positive), all DELETE are negative (if any) and all BUY are positive.
I'd like to go in a loop possibly...
I took the count of records as intRsCount = 25
With rs2
While Not .EOF
lngCompanyID = rs2("CompanyID")
lngUnitPrice = rs2("UnitPrice")
strSQL2 = "SELECT AddQty from qryAddx WHERE InvValue = " & lngUnitPrice & " And CompanyId = " & lngCompanyId
strSQL3 = "SELECT DeleteQty from qryUsedx where UnitValue=" & lngUnitPrice & " And CompanyId = " & lngCompanyId
strSQL4 = "SELECT BuyQty from qryVoidx where InvValue =" & lngUnitPrice & " And CompanyId = " & lngCompanyId
Set rs3 = CurrentDb.OpenRecordset(strSQL2)
Set rs4 = CurrentDb.OpenRecordset(strSQL3)
Set rs5 = CurrentDb.OpenRecordset(strSQL4)
If rs3.recordCount > 0 Then
rs2.Edit
rs2("Added") = rs3("Addqty")
rs2.Update
End If
If rs4.recordCount > 0 Then
rs2.Edit
rs2("Delete") = rs4("DelQty")
rs2.Update
End If
If rs5.recordCount > 0 Then
rs2.Edit
rs2("Buy") = rs5("BuyQty")
rs2.Update
End If
rs2.MoveNext
Set rs3 = Nothing
Set rs4 = Nothing
Set rs5 = Nothing
Wend
End With
This is my code. I'm trying to add the SUM of ADDED, DELETED and BUY and place it in rs2("Subtotal") and doing this for all 25 rows. I'm not really familiar with ACCESS and how it deals with NULL values, and negative values (all DELETE values are negative). Thanks.
Dim strCriteria as String
With rs2
While Not .EOF
strCriteria = "InvValue = " & !UnitPrice & " And CompanyId = " & !CompanyID
.Edit
!Added = Nz(DSum("Addqty", "qryAddx", strCriteria), 0)
!Delete = Nz(DSum("DeleteQty", "qryUsedx", strCriteria), 0)
!Buy = Nz(DSum("BuyQty", "qryVoidx", strCriteria), 0)
.Update
Wend
End With
DSum() is inefficient. If you are running many operations, it may be slow, but otherwise it is fine.
Nz() converts a Null value to zero.
If rs2 is a recordset, you would refer to the columns like this: rs2.fields("Add").Value
Do loop through the rows, go with
if rs2.recordcount > 0 then
rs2.movefirst
while not rs2.eof
'put your commands here
wend
end if

Multiple parameter values in one string in access SQL

I have an array which can have a different amount of values, depending on the situation. I want to put these values as a parameter in a query in ms access.
The problem is, if I use the following code to generate a parameter, it sends the whole string as one value to the query, which obviously does not return any rows.
Do Until i = size + 1
If Not IsEmpty(gvaruocat(i)) Then
If Not IsEmpty(DLookup("uo_cat_id", "tbl_uo_cat", "[uo_cat_id] = " & CInt(gvaruocat(i)))) Then
If IsEmpty(get_uocat_param) Then
get_uocat_param = CInt(gvaruocat(i))
Else
get_uocat_param = get_uocat_param & " OR tbl_uo_step.uo_step_cat = " & CInt(gvaruocat(i))
End If
End If
End If
i = i + 1
Loop
At the moment I have 'Fixed' it by generating an SQL string and leaving the query out all together.
get_uocat = "SELECT tbl_product.prod_descr, tbl_uo_cat.uo_cat_descr, tbl_uo_step.uo_step_descr" & vbCrLf _
& "FROM (tbl_product INNER JOIN tbl_uo_cat ON tbl_product.prod_id = tbl_uo_cat.uo_cat_prod) INNER JOIN tbl_uo_step ON tbl_uo_cat.uo_cat_id = tbl_uo_step.uo_step_cat" & vbCrLf _
& "WHERE (((tbl_uo_step.uo_step_cat) = " & get_uocat_param & ")) " & vbCrLf _
& "ORDER BY tbl_product.prod_descr, tbl_uo_cat.uo_cat_descr, tbl_uo_step.uo_step_descr;"
This is however not very friendly to many changes. So my question is, how do I get the array to send each value as a separate parameter to the query?
Note: IsEmpty() is a custom function which checks for empty variables in case you were wondering.
You can still use a parameterized query in this case, despite your comment to the question. You just need to build the SQL string to include as many parameters as required, something like this:
Dim cdb As DAO.Database, qdf As DAO.QueryDef, rst As DAO.Recordset
Dim sql As String, i As Long
' test data
Dim idArray(1) As Long
idArray(0) = 1
idArray(1) = 3
Set cdb = CurrentDb
sql = "SELECT [LastName] FROM [People] WHERE [ID] IN ("
' add parameters to IN clause
For i = 0 To UBound(idArray)
sql = sql & "[param" & i & "],"
Next
sql = Left(sql, Len(sql) - 1) ' trim trailing comma
sql = sql & ")"
Debug.Print sql ' verify SQL statement
Set qdf = cdb.CreateQueryDef("", sql)
For i = 0 To UBound(idArray)
qdf.Parameters("param" & i).Value = idArray(i)
Next
Set rst = qdf.OpenRecordset(dbOpenSnapshot)
' check results
Do Until rst.EOF
Debug.Print rst!LastName
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
Set qdf = Nothing
Set cdb = Nothing
When I run this on my test database I get
SELECT [LastName] FROM [People] WHERE [ID] IN ([param0],[param1])
Thompson
Simpson
you could make use of the IN Clause, instead. Which would work out better.
Do Until i = size + 1
If Not IsEmpty(gvaruocat(i)) Then
If Not IsEmpty(DLookup("uo_cat_id", "tbl_uo_cat", "[uo_cat_id] = " & CInt(gvaruocat(i)))) Then
If IsEmpty(get_uocat_param) Then
get_uocat_param = CInt(gvaruocat(i))
Else
get_uocat_param = get_uocat_param & ", " & CInt(gvaruocat(i))
End If
End If
End If
i = i + 1
Loop
Then your Query build could use,
get_uocat = "SELECT tbl_product.prod_descr, tbl_uo_cat.uo_cat_descr, tbl_uo_step.uo_step_descr" & vbCrLf _
& "FROM (tbl_product INNER JOIN tbl_uo_cat ON tbl_product.prod_id = tbl_uo_cat.uo_cat_prod) INNER JOIN tbl_uo_step ON tbl_uo_cat.uo_cat_id = tbl_uo_step.uo_step_cat" & vbCrLf _
& "WHERE ((tbl_uo_step.uo_step_cat IN (" & get_uocat_param & "))) " & vbCrLf _
& "ORDER BY tbl_product.prod_descr, tbl_uo_cat.uo_cat_descr, tbl_uo_step.uo_step_descr;"

Inserting every OTHER ROW from one table to another (VBA MS Access 2010)

I am working with manually created empty copy of table Products, which I named Products_Backup. What I want to do is to insert every other row from "Spices" category of products into this empty Products_Backup table, since there would be only 6 rows from total of 12 rows, that are in Products table under "Spices" category. The problem is that I don't know how to do that. I tried to use MOD operator for newly created ProductID, but my mentor told me that it is not a proper solution, since he could easily change this ProductID's value and I would get odd rows instead of even.
Private Sub CommandButton0_Click()
Dim db As Database, rst As Recordset
Dim I As Integer, s, s1 As String
Set db = CurrentDb
s = "SELECT Products.* FROM Products WHERE (((Products.CategoryNumber)=2));" ' This value is for Spices
Set rst = db.OpenRecordset(s)
I = 1
While Not rst.EOF
s1 = "INSERT INTO Products_Backup (ProductName, ProductID, CategoryNumber, OrderedUnits) VALUES ('" & rst!ProductName & "', " & I & " , '" & rst!CategoryNumber & "', '" & rst!OrderedUnits & "');"
MsgBox ("Record inserted")
db.Execute s1
I = I + 1
rst.MoveNext
If I Mod 10 = 0 Then
MsgBox ("Inserted " & I & ".record")
End If
Wend
rst.Close
db.Close
End Sub
So with this I can insert all 12 records into Products_Backup, with MsgBox telling me when 10th record was inserted.
But I still have no idea what to do to insert every other row into Products_Backup to get 6 records.
Dim booEveryOther as Boolean
booEveryOther = False
While Not rst.EOF
If booEveryOther Then
s1 = "INSERT INTO ...
End If
booEveryOther = Not booEveryOther
Just use a Boolean value that is set to Not itself with every new record.
i think this should do it better
While Not rst.EOF
s1 = " INSERT INTO Products_Backup (ProductName, ProductID, CategoryNumber, OrderedUnits) " & _
" VALUES ('" & rst!ProductName & "', " & I & " , '" & rst!CategoryNumber & "', '" & rst!OrderedUnits & "');"
db.Execute s1
If I Mod 10 = 0 Then
MsgBox ("Inserted " & I & ".record")
Else
MsgBox ("Record inserted")
End If
I = I + 1
rst.MoveNext
Wend