NZ Invalid Use of Null - ms-access

I have a form that opens with on OnOpen event. Part of the event contains this code:
nid = Val(DMax("id2", "claims", "yr =" & yr) + 1)
nid = Val(Nz([nid], 1))
But, I get an "Invalid Use of Null" error when it runs.
Any ideas?
EDIT BELOW
Here is the full code:
Private Sub Form_Open(Cancel As Integer)
If Not IsNull(Me.OpenArgs) Then
Dim lngID As Long
Dim rs As Object
Set rs = Me.Recordset.Clone
lngID = Val(Me.OpenArgs)
rs.FindFirst "[ID] = " & lngID
If Not rs.EOF Then Me.Bookmark = rs.Bookmark
End If
Me.LOGID.SetFocus
'Display Suggested ID Numbers
Dim yr As Long
Dim nid As Long
yr = Format(Date, "yy")
nid = Val(DMax("id2", "claims", "yr =" & yr) + 1)
nid = Val(Nz([nid], 1))
Me.SugID = yr & "-" & nid
End Sub

Double-check the value returned by the DMax expression. If no rows match the criteria option ("yr =" & yr), DMax will return Null. Or if id2 is Null in all rows which match the criteria, DMax will return Null.
If the DMax expression returns Null, the Val() expression is equivalent to this:
Val(Null + 1)
But Null + 1 yields Null, so that is the same as asking for Val(Null) which triggers error #94, 'Invalid use of Null'.
I'm unsure what you want instead. If claims.id2 is a numeric data type, maybe this will work:
nid = Nz(DMax("id2", "claims", "yr =" & yr), 0) + 1

Related

Replacing Column Name in Query with VBA Parameter MS Access

I am trying to open form X through form Y, where docid = docid
form X's table has a primary key column named "abcid" (the matching id)
I am trying to pass the label name of form Y's textbox's label "abcid" as string "abcid", the idea is to pass the column name dynamically whatever the used form is ==> in VBA OpenForm WHERE condition, but it doesn't execute properly or opens a blank form. code below:
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim checklistformName As String
Dim viewdocformName As String
Dim currentformName As String
currentformName = Screen.ActiveForm.Name
'Debug.Print currentformName
Dim docidcolumnName As String
docidcolumnName = Forms(currentformName).Controls(docid).Caption
Debug.Print docidcolumnName
Set rs1 = CurrentDb.OpenRecordset("SELECT DISTINCT checklistformname FROM CyclesDefinitions WHERE cycledefid = " & Forms(currentformName)![cycledefid])
Do Until rs1.EOF = True
checklistformName = rs1(0)
rs1.MoveNext
Loop
rs1.Close
Set rs1 = Nothing
Set rs2 = CurrentDb.OpenRecordset("SELECT DISTINCT viewdocformname FROM CyclesDefinitions WHERE cycledefid = " & Forms(currentformName)![cycledefid])
Do Until rs2.EOF = True
viewdocformName = rs2(0)
rs2.MoveNext
Loop
rs2.Close
Set rs2 = Nothing
Debug.Print currentformName & " - " & checklistformName & " - " & viewdocformName
DoCmd.OpenForm viewdocformName, , , " & docidcolumnname & " = " & Forms(checklistformName)![docid], acFormReadOnly
alright, I solved the OpenForm with string dilemma with the following solution after testing a statically predefined string:
DoCmd.OpenForm viewdocformName, , , "" & docidcolumnName & " = " & Forms(checklistformName)![docid], acFormReadOnly
it just needed the proper concatenation, and instead of messing with the forms!frmname syntax, because I can't find the proper return value, I set the label name on form to pkcolname and recalled it in VBA like this:
docidcolumnName = Me.pkcolname.Caption:
now everything is working as expected and required.

Variable not working inside IN clause

This code is written in Excel2010 VBA and queries PostGreSQL tables
I have the following code in VBA that creates a variable that I would like to use in my SQL query, but I cannot get the SQL query to accept the VBA variable using the IN clause
This code creates the variable I want to use and works fine. It allows me to select specific cells I need to query
Dim StaffID As Range
Dim ID As Range
Dim LR As Long
Dim SelectedID As String
'Count number of rows to search
LR = Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
On Error Resume Next 'if only 1 row
'Store Data from here
Set StaffID = ThisWorkbook.Sheets("Sheet1").Range("B2:B" & LR)
'Loop through each cell in Range and look for any character in column A
'then store offset cell value using comma delimiter
For Each ID In Worksheets("Sheet1").Range("A2:A" & LR).Cells
If ID.Value > 0 Then
SelectedID = SelectedID & "," & ID.Offset(, 1).Value
End If
Next ID
'Remove first delimiter from string (,)
SelectedID = Right(SelectedID, Len(SelectedID) - 1)
OUTPUT EXAMPLE of SelectedID = 6,7,8,6452
I now want to add this to my query using the IN clause, but it just doesn't work. Does anyone have a solution or workaround.
Sheets("Sheet2").Select
Range("A1").Select
Dim rs As Recordset
Dim t As String
t = "SELECT DISTINCT s.entity_id, u.login_name, s.role " _
& "FROM staff s INNER JOIN user u ON s.entity_id=u.staff_id " _
& "WHERE u.staff_id IN (SelectedID) " _
Set rs = conn.Execute(t)
With ActiveSheet.QueryTables.Add(Connection:=rs, Destination:=Range("A1"))
.Refresh
End With
rs.Close
At the moment you're putting the string 'SelectedID' directly into your query. You'll need something like this in your VBA:
t = "SELECT DISTINCT s.entity_id, u.login_name, s.role " _
& "FROM staff s INNER JOIN user u ON s.entity_id=u.staff_id " _
& "WHERE u.staff_id IN (" & SelectedID & ")"
Rows.Count should be fully qualified and With ThisWorkbook.Worksheets("Sheet1") and fully qualifying will make your code read better.
Function getSelectedIDSQL() As String
Dim ID As Range, StaffID As Range
Dim SelectedID As String
With ThisWorkbook.Worksheets("Sheet1")
For Each ID In .Range("A2" & .Range("A" & .Rows.Count).End(xlUp))
If ID.Value > 0 Then SelectedID = SelectedID & "," & ID.Offset(, 1).Value
Next
End With
If Len(SelectedID) Then getSelectedIDSQL = Right(SelectedID, Len(SelectedID) - 1)
End Function

How to accommodate insertion of new line of code

I have the following code below which builds/creates a description based on the Value field (where contains data) in sequential order. For example, I have a table which has the following fields...
Item
Classification
Attribute Name
Value
UOM
Status
What I'm trying to do is insert a line of code that will only build the description from the Value field (where contains data) where the Status field = Active. The Status field info is either "Active" Or "Foreign". Currently, if the Status field shows "Foreign" the code will also build the description for these records which I just learned should not be included.
Any help would be greatly appreciated! Again, below is the code...
Sub SD()
DoCmd.SetWarnings False
Dim db As DAO.Database
Dim rsMara, rs_cou As DAO.Recordset
Dim rs, rs2, x As DAO.Recordset
Dim SD, strAttribute, strValue, sdvalue As String
Dim seq, d, count1 As Integer
Set db = CurrentDb
db.Execute ("UPDATE Item_Template SET Description = '', Long_Description = '';")
Set rsMara = db.OpenRecordset("select * from [Item_Template] order by [Item]")
While Not rsMara.EOF
If rsMara.Fields("Classification") & "" <> "" Then
SD = UCase(rsMara.Fields("Classification")) & ": "
seq = 1
Set rs = db.OpenRecordset("select * from All_Item_Attributes where [Item] = '" & rsMara.Fields("Item") & "' and [Value] & '' <> '' order by [Item],[Sequence (Cls Attribute Mapping)]")
While Not rs.EOF
If (rs.Fields("UOM") Like "IN*" Or rs.Fields("UOM") Like "O*") Then
SD = SD & rs.Fields("Value") & " " & UCase(rs.Fields("UOM")) & ", "
Else
SD = SD & rs.Fields("Value") & " " & UCase(rs.Fields("UOM")) & ", "
End If
rs.MoveNext
Wend
SD = Trim(SD)
rsMara.Edit
SD = Trim(Mid(SD, 1, Len(SD) - 1))
rsMara.Fields("Description") = Trim(SD)
rsMara.Fields("Description") = Replace(rsMara.Fields("Description"), " ,", ", ")
rsMara.Fields("Description") = Replace(rsMara.Fields("Description"), " ", " ")
rsMara.Update
End If
DoEvents
rsMara.MoveNext
Wend
End Sub
You don't say which table the field Status is in.
You have two lines of code opening recordsets so it will be one of these lines of code:
Set rsMara = db.OpenRecordset("select * from [Item_Template] WHERE Status='Active' order by [Item]")
or
Set rs = db.OpenRecordset("select * from All_Item_Attributes where [Item] = '" & rsMara.Fields("Item") & "' and [Value] & '' <> '' AND Status='Active' order by [Item],[Sequence (Cls Attribute Mapping)]")
Basically adding Status='Active' into the WHERE clause. This won't work if your Status field is a lookup field in which case you'd need to use the Foreign Key value that links it to your Status type table. Status=1 for example.

Access - Filter by date with a checkbox

I would like to have a check-box that, when ticked, filters the loaded data to only include data where it has been at least one month until the "Expected pair maturation" date. Here is my attempt:
Private Sub LockFilter1Chk_Click()
If Me!LockFilter1Chk = True Then
Me.RecordSource = "SELECT * FROM staff " & _
WHERE DateDiff("m", Me![Expected pair maturation], Now()) > 1 "
End If
If Me!LockFilter1Chk = Not True Then
Me.RecordSource = "SELECT * FROM Staff "
End If
End Sub
It might be simple to set the Filter:
Private Sub LockFilter1Chk_Click()
If Me!LockFilter1Chk = True Then
Me.Filter = "[Expected pair maturation] < DateAdd("m", -1, Date())"
Me.FilterOn = True
Else
Me.FilterOn = False
End If
End Sub
After a string and line concatenation & _ you need a new double quote to start the new string.
If you have " inside a string, you must mask it as "".
In a SQL SELECT recordsource, don't refer to Me!. You are comparing the value from the table, so only use the field name.
Some indentation helps a lot with readability.
This should be closer (not sure if it already does what you want).
Private Sub LockFilter1Chk_Click()
If Me!LockFilter1Chk = True Then
Me.RecordSource = "SELECT * FROM staff " & _
"WHERE DateDiff(""m"", [Expected pair maturation], Now()) > 1 "
Else
Me.RecordSource = "SELECT * FROM Staff "
End If
End Sub
You did not mention what was your problem.
You can do it the way you did, but I would use an if then else construct:
Private Sub LockFilter1Chk_Click()
If Me!LockFilter1Chk = True Then
Me.RecordSource = "SELECT * FROM staff " & _
"WHERE [Expected pair maturation] < DateAdd('m', -1, Date())"
else
Me.RecordSource = "Staff"
End If
End Sub
Alternatively you could leave the record Source unchanged and use a filter:
If Me!LockFilter1Chk = True Then
docmd.applyfilter , "[Expected pair maturation] < DateAdd('m', -1, Date())"
else
me.filterOn = false
end if
Note: If you have quotes within quotes, you can also use single quotes inside:
"DateDiff('m', Me![Expected pair maturation], Now()) > 1 "

MS Access 2003 - Concatenating Field Types of Same ID on a Form

Ok so a guy at work has a little access database he uses to keep track of things. He has this form that he uses that already queries what he needs and produces the results on a form and that is really all he needs.
One thing is that he has duplicates for every record that comes up with a different "Type" as a field "indentifier" (what I call it)...here is an example:
ID Name Price Type
1 Prodcut A $10 A1
1 Product A $10 A2
1 Product A $10 A3
2 Product B $12 A1
etc
naturally this is supposed to occur and he wants to see all the types but given it ends up being a mile long, he asked me if there was a way to concatenate the "types" so the following would be displayed:
ID Name Price Type
1 Prodcut A $10 A1, A2, A3
1 Product B $12 A1, A2, A3
1 Product C $14 A1, A2, A3
2 Product D $7 A1, A2, A3
...on the form. Can anyone please help me with this? Thanks!
OK, i found a function created in the VBA, which can be used in the query to retrieve the data for the form.
function is
Public Function ConcatRelated(strField As String, _
strTable As String, _
Optional strWhere As String, _
Optional strOrderBy As String, _
Optional strSeparator = ", ") As Variant
On Error GoTo Err_Handler
'Purpose: Generate a concatenated string of related records.
'Return: String variant, or Null if no matches.
'Arguments: strField = name of field to get results from and concatenate.
' strTable = name of a table or query.
' strWhere = WHERE clause to choose the right values.
' strOrderBy = ORDER BY clause, for sorting the values.
' strSeparator = characters to use between the concatenated values.
'Notes: 1. Use square brackets around field/table names with spaces or odd characters.
' 2. strField can be a Multi-valued field (A2007 and later), but strOrderBy cannot.
' 3. Nulls are omitted, zero-length strings (ZLSs) are returned as ZLSs.
' 4. Returning more than 255 characters to a recordset triggers this Access bug:
' http://allenbrowne.com/bug-16.html
Dim rs As DAO.Recordset 'Related records
Dim rsMV As DAO.Recordset 'Multi-valued field recordset
Dim strSql As String 'SQL statement
Dim strOut As String 'Output string to concatenate to.
Dim lngLen As Long 'Length of string.
Dim bIsMultiValue As Boolean 'Flag if strField is a multi-valued field.
'Initialize to Null
ConcatRelated = Null
'Build SQL string, and get the records.
strSql = "SELECT " & strField & " FROM " & strTable
If strWhere <> vbNullString Then
strSql = strSql & " WHERE " & strWhere
End If
If strOrderBy <> vbNullString Then
strSql = strSql & " ORDER BY " & strOrderBy
End If
Set rs = DBEngine(0)(0).OpenRecordset(strSql, dbOpenDynaset)
'Determine if the requested field is multi-valued (Type is above 100.)
bIsMultiValue = (rs(0).Type > 100)
'Loop through the matching records
Do While Not rs.EOF
If bIsMultiValue Then
'For multi-valued field, loop through the values
Set rsMV = rs(0).Value
Do While Not rsMV.EOF
If Not IsNull(rsMV(0)) Then
strOut = strOut & rsMV(0) & strSeparator
End If
rsMV.MoveNext
Loop
Set rsMV = Nothing
ElseIf Not IsNull(rs(0)) Then
strOut = strOut & rs(0) & strSeparator
End If
rs.MoveNext
Loop
rs.Close
'Return the string without the trailing separator.
lngLen = Len(strOut) - Len(strSeparator)
If lngLen > 0 Then
ConcatRelated = Left(strOut, lngLen)
End If
Exit_Handler:
'Clean up
Set rsMV = Nothing
Set rs = Nothing
Exit Function
Err_Handler:
MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "ConcatRelated()"
Resume Exit_Handler
End Function
and is used in the query as
SELECT Table1.ID, Table1.ProductName, Table1.ProductPrice, ConcatRelated("Type","Table1","ID = " & [Table1]![ID] & " AND ProductName = """ & [Table1]![ProductName] & """ AND ProductPrice = " & [Table1]![ProductPrice]) AS Expr1
FROM Table1
GROUP BY Table1.ID, Table1.ProductName, Table1.ProductPrice, ConcatRelated("Type","Table1","ID = " & [Table1]![ID] & " AND ProductName = """ & [Table1]![ProductName] & """ AND ProductPrice = " & [Table1]![ProductPrice]);
I found an example (here) that seems to be exactly what you are looking for:
Concatenate Column Values from Multiple Rows into a Single Column with Access
From the above link:
The Problem
Coming up with a meaningful title for
this article was the hardest part. The
issue is one that I have seen a couple
times in the Access newsgroups, but it
is hard to describe without a specific
example. One post to
comp.databases.ms-access some years
ago put it this way:
I would like to combine a field's values from multiple records in a single field. For example:
Last First Code
------- --------- ----
Lesand Danny 1
Lesand Danny 2
Lesand Danny 3
Benedi Eric 7
Benedi Eric 14
Result should look like:
Last First Codes
------- --------- -----
Lesand Danny 1,2,3
Benedi Eric 7,14
Something on these lines may suit, but concatenating is usually not a good idea:
Function ConcatList(strSQL As String, strDelim, _
ParamArray NameList() As Variant)
''Reference: Microsoft DAO x.x Object Library
Dim db As Database
Dim rs As DAO.Recordset
Dim strList As String
Set db = CurrentDb
If strSQL <> "" Then
Set rs = db.OpenRecordset(strSQL)
Do While Not rs.EOF
strList = strList & strDelim & rs.Fields(0)
rs.MoveNext
Loop
strList = Mid(strList, Len(strDelim) + 1)
Else
strList = Join(NameList, strDelim)
End If
ConcatList = strList
End Function
FROM: http://wiki.lessthandot.com/index.php/Concatenate_a_List_into_a_Single_Field_(Column)
Why don't you try the "crosstab query" solution?