I'd like to create an If/Then statement in VBA where if there are multiple records in the recordset one message populates, and if there is only record another message populates.
Right now I'm using
If rst.EOF = False Then...
Else ...
End If
This is only returning the first condition regardless of how many records are in the recordset though.
Is there something else I'm missing?
You are missing to count the records:
If rst.EOF = False Then
rst.MoveLast
rst.MoveFirst
If rst.RecordCount = 1 Then
' One record.
Else
' More records.
End If
Else
' No records.
End If
Depending on the size of your recordset, .MoveLast can severely impact on performance and since .RecordCount will not yield the total number of records, but rather the number of accessed records, a call to .MoveLast is required.
To offer an alternative, consider the following:
If rst.EOF Then
' No records
Else
rst.MoveFirst
rst.MoveNext
If rst.EOF Then
' 1 record
Else
' More than 1 record
End If
End If
This first tests whether the recordset is already at .EOF, and if so, there are no records in the recordset.
If we have some records, it moves the cursor to the first record (.MoveFirst), and then to the next record (.MoveNext) if it exists.
If we have now reached .EOF, there must be only one record in the recordset; else, there are more records.
Since you only need to branch for the case there is a single record, this method means you are accessing the minimum number of records to determine this condition.
Related
I have the following case statement, the AppointmentDate isn’t always populated and therefore require to pull from other date fields - looking to have one appointment date (populated from many fields)
When running this statement, doesn’t return full results.
,Case=Appointment
When AppointmentDate Is Null Then ChaseDate
When ChaseDate Is Null Then DueDate
Else AppointmentDate
End
Any thoughts on where I’ve went wrong?
Thanking you in advance.
You haven't stated if this is supposed to be an expression in SSRS or this is part of your dataset query.
Assuming SQL Server here...
If this is part of your dataset query then you can do something like
SELECT
FieldA, FieldB,
myAppointmentDate = COALESCE(AppointmentDate, ChaseDate, DueDate)
FROM myTable
COALESCE will return the first non-null value
If you are trying to do this in an SSRS expression then you need to use the SWITCH() statement.
=SWITCH(
Fields!AppointmentDate.Value <> Nothing, Fields!AppointmentDate.Value,
Fields!ChaseDate.Value <> Nothing, Fields!ChaseDate.Value,
Fields!DueDate.Value <> Nothing, Fields!DueDate.Value,
True, Fields!AppointmentDate.Value
)
This will return the first expression that is true, if non of the first three exression return true, the final True acts like an else (which in your case would return Nothing anyway)
This is the situation:
I’m attempting to build a query with criteria based on a form. A particular form field can be empty or have a specific value. If the form field is empty, I need to return all records. If the form field is not empty, I need to return only the records that match. However, there are Null values in this field in the database, and I don’t want them returned when the field is not empty but I do want them returned when the form field is empty.
I’ve been attempting to use “[FormField] Or Like [FormField] Is Null” which almost works but when the form field is not null, I get all the null records too.
Many of my attempts thus far have led either to the Null field records not being returned ever or the "This expression is typed wrong or too complex" error.
What criteria would get these results?
Thank you
How about:
SELECT Table1.ID, [AText] & "" AS ATextNotNull
FROM Table1
WHERE [AText] & "" Like [Forms]![Form1]![SomeText]
& IIf([Forms]![Form1]![SomeText] Is Null,"*","")
Define a special field entry that means "empty", like "-", "_", "null", "empty" or "x". An empty form field means "all records".
Another approach is to have three radio buttons
(o) All records
( ) Records with empty field xy
( ) Records containing: [ search field here ]
The advantage is that the user does not need to learn special conventions.
You can then define your query accordingly and do not have to mix the different situations in one single query
Dim cond As String
Select Case option
Case 1
cond = ""
Case 2
cond = "field IS NULL"
Case 3
cond = "field Like '*" & Me!txtSearch & "*'"
End Select
Try to use IIF function:
...WHERE [TableColumn] LIKE IIF([FormField] IS NULL, '*', [FormField])...
Why would the second criterion in this WHERE clause be ignored?
$old = time() - 2592000;
$sql_deleteold = ("DELETE FROM todolist WHERE status='done' AND stamp < $old");
mysql_query($sql_deleteold);
I want to delete data from the database older than 30 days with the status "done".
Instead it will go deleting all rows with the status "done".
I think that your question is referring to the "second statement" in the SQL query?
With this assumption, the problem with all rows being deleted with the status "done" is because the WHERE filters are similar to conditional statements like the ones used in "If" statements.
If the first statement, or WHERE filter is true, then execute.
Try doing the following:
$old = time() - 2592000;
$sql_deleteold = ("DELETE FROM todolist WHERE (status='done' AND stamp < $old)");
mysql_query($sql_deleteold);
You also might want to verify the value of $old and compare it to the values in the 'stamp' field of your table, to be sure that there are some rows that have a value in the 'stamp' field that are greater than the value of $old.
Have you tried debugging your query? Rather than deleting the query try selecting the values:
SELECT * FROM todolist WHERE status = 'done' AND stamp < $old
Does it select the results you expect? If it doesn't keep tweaking it till it does, then attempt to delete the records.
You may have a quoting issue. To be sure, try:
$sql_deleteold = "DELETE FROM `todolist` WHERE `status`='done' AND `stamp` < '".$old."';";
Also when you insert fields, do you set the stamp field with php $time()$ function, or is it set by SQL functions? Because the time representation may be different depending on the type of the stamp field.
Try issuing SELECT stamp FROM todolist and see what you get. Presumably, they will be values less than time() = 2592000.
I have 12 colomns in my Access 2010 form, now I want to remove all the filters on the columns so that user is not able to filter records. I want user to only filter from combo box,
how can i do this?
Seems two me there are two parts to your question:
Discard or ignore any existing filters
Prevent the user from any filtering
For the first, you can use this to ignore any existing filters.
Me.FilterOn = False
For the second, you can set the form's Allow Filters property to No.
Then you can accomplish your filtering by using the combo's after update event to revise the form's Record Source.
Dim strSql As String
strSql = "SELECT field1, field2, field3 FROM YourTable WHERE some_field = " & _
Me.YourComboName
Me.RecordSource = strSql
Re-assigning the RecordSource will automatically force a requery.
That would work if the bound value of YourComboName is numeric. If its text data, you will have to enclose its values with quotes when you build strSql.
strSql = "SELECT field1, field2, field3 FROM YourTable WHERE some_field = """ & _
Me.YourComboName & """"
in an ms-access database i have a table
num weight
1 12
4 13
2 13
6 9
7 13
how can i write a query which will sort the table according to weight in descending order . but the numbers 4, 2 and 7 have same weight (13) , so they must be sorted randomly each time query is run.
any help appreciated.
Normally, your SQL would contain a random function of some sort (it looks like Access has the rnd() function for this).
So you could use:
select num, weight, rnd(num)
from tbl
order by weight desc, 3
This will let you see r for testing purposes. In a real query, you might just want to use something like:
select num, weight
from tbl
order by weight desc, rnd(num)
From this page:
When value is greater than 0, Rnd() returns the next random number.
When value is less than 0, Rnd() returns the same random number, based on value. If value occurs only once, you won’t notice this behavior. Access also resets seed, which means the sequence starts all over again.
When value is equal to 0, Rnd() returns the most recently generated random number
Update 1: I'm unsure as to whether rnd() is executed once in the following queries or once per row - the docs aren't clear. Comments seem to indicate the same results are being received for all rows which indicates it may be the latter. It may be that changing it to rnd(num) or rnd(abs(num)+1) will fix that problem. I'll have to check when I get to a box with Access installed.
Update 2: I've now tested this in Access 2007 and it does indeed give the same random value for every row when you use rnd(1). It does give a different value for rnd(num) each time you run the query and the individual rows get different values. So the query you need is:
select num, weight from tbl order by weight desc, rnd(num);
If you create a table with two Number fields and then run that query over it, you'll see that continual refreshing (with F5) will swap around the 2, 7 and 4 rows at random but leave the 1 and 6 rows in the same place since the weights of the first three are all 13 and the weights of the last two are 12 and 9 respectively.
I've updated the queries above to match this new information.
I think this will do the trick...
ORDER BY weight, Rnd()
When using RND() in Access Database Engine SQL from outside of the Access UI, the same sequence of random numbers will be used by each session (there is no native support for VBA's Randomize).
For example, connect to the source then execute SELECT RND(); three times in succession, you will get the following values:
0.705547511577606
0.533424019813538
0.579518616199493
Close the connection, connect to the source again then execute the same query again three times you will get the same three values as above in the same order.
In the knowledge that these values are predictable, we can demonstrate that a different value for RND() is used each time it is referenced. Consider this query:
SELECT RND()
FROM T
WHERE RND() > CDBL(0.6);
We know the first value in a new session will be 0.705547511577606, therefore the expression
RND() > CDBL(0.6)
will evaluate TRUE. However, the value 0.533424019813538 is repeated for every row in table T, a value which does not satisfy the WHERE clause! So it is clear that the value of RND() in the WHERE clause is different from the value in the SELECT clause. The full code is posted below.
Note I wondered if it may be possible to use the least significant portion of CURRENT_TIMESTAMP value generate a random number that could be used consistently through the scope of a single query and not be predictable for a session as RND() is. However, the Access Database Engine does not support it and its closest analogy, the NOW() function, does not have enough granularity to be useful :(
Sub jmgirpjpo()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
.Execute "CREATE TABLE T (T INT);"
.Execute "INSERT INTO T VALUES (1);"
.Execute "INSERT INTO T VALUES (2);"
.Execute "INSERT INTO T VALUES (3);"
Dim rs
Set rs = .Execute("SELECT RND() FROM T WHERE RND() > CDBL(0.6);")
MsgBox rs.GetString
End With
End With
End Sub