Access bring me random records from a selected column - ms-access

I want access give me the the first value from the selected table and column.
But access are given to me random value from the selected table and column.
Question
Have someway to access give to me like this example:
My table is "tblExample" and have 2 columns the header of each is [Column1] and [Column2] inside each header contains this values
+---------+----------+
| Column1 | Column2 |
+---------+----------+
| 5 | mark |
| 3 | stewie |
| 2 | stack |
| 16 | overflow |
+---------+----------+
I want read the first value in loop of the [Column1] from the table "tblExample" and bring to me in sequence.
example value = 5/ after 3 / 2 / 16 ...
But my code is showning this values random like 16/5/3/2
This is my code
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim VarA As String, varFR, varLR
Set db = CurrentDb
Set rs = db.OpenRecordset("tblExample")
If rs.EOF Then
FindRecordCount = 0
Else
rs.MoveLast
FindRecordCount = rs.RecordCount
End If
varLR = FindRecordCount
Dim i As Long
For i = 0 To rs.Fields.Count - 1
rs.MoveFirst
varFR = 1
Do While varFR < varLR
If IsNull(rs.Fields(i).Value) = True Then
GoTo pula1
End If
VarA = rs.Fields(i).Value
Debug.Print VarA
pula1:
rs.MoveNext
varFR = varFR + 1
Loop
Next

Tables without primary key don't have an inbuilt sort order. So the result of a recordset loop can be random.
You can either provide the sort order when opening the recordset
Set rs = db.OpenRecordset("SELECT * FROM tblExample ORDER BY Column1")
(but the result can still be random if Column1 contains duplicate values!)
or if you want the order, in which the records were inserted, add a AutoNumber primary key column to your table.
For readability you should still specify the order -
Set rs = db.OpenRecordset("SELECT * FROM tblExample ORDER BY ID")

you can loop trough like this, after you set the Recordset:
rs.MoveFirst
Do Until rs.EOF
--- Stuff happens
rs.MoveNext
Loop
So its looping through the records like they are in the table. If you want another sequence you can sort the recordset before:
Set rs = db.OpenRecordset("SELECT * FROM tblExample ORDER BY Column1 ASC")

Related

Create a number of records equal to the value of a table field

I have a table with ID, product number, product description, qty fields.
Now I want to create a new table containing a quantity of records given by the qty field of the parent table.
For example, if the parent table has a record with qty = 6 then in the child table it should create 6 records with serial numbers from 1 to 6.
You can use a simple loop like this:
Dim rs As DAO.Recordset
Dim Record As Integer
Dim Records As Integer
Set rs = CurrentDb.OpenRecordset("Select * From YourTable")
' Count of records - use value from your quantity field:
Records = 5
For Record = 1 To Records
rs.AddNew
rs!SomeID.Value = Record
rs!Field1.Value = SomeValue
rs!Field2.Value = SomeOtherValue
rs!Field3.Value = YetAnotherValue
rs.Update
Next
rs.Close
Set rs = Nothing
You can use the code below.
Dim rsTable1 as Recordset
Dim rsTable2 as Recordset
Dim Table1qty as integer
Dim i as integer
set rsTable1 = CurrentDb.openrecordset("SELECT qty FROM Table1")
set rsTable2 = CurrentDB.openRecordSet("SELECT * From Table2")
if rsTable1.RecordCount > 0 then
while not rsTable1.EOF
Table1qty = rsTable("qty")
for i = 1 to Table1qty
rsTable2.Addnew
rsTable2!SerialNumber.Value = i
rsTable2!SomeField.Value = SomeValue
rsTable2.Update
next
rsTable1.movenext
wend
end

Load arrays into recordset to loop through to increment value vba access

I'm trying to load values from two tables of an access database (in the same database file as the VBA code) into arrays to loop through and increment the value in EQP_POS_CD field when the PART FIND NO matches the previous PART FIND NO. The query:
SELECT CTOL.ID, CTOL.BOM_PART_NAME, CTOL.CII, CTOL.[PART FIND NO], CTOL.CSN,
CTOL.AFS, CTOL.EQP_POS_CD, CTOL.LCN, CTOL.POS_CT, CTOL.SERIAL_NO,
CTOL.PART_NO_LLP, [CTOL_Asbuilt].[PART-SN], [CTOL_Asbuilt].[PART-ATA-NO],
[CTOL_Asbuilt].[PW-PART-NO]
FROM CTOL LEFT JOIN [CTOL_Asbuilt] ON CTOL.[PART FIND NO] = [CTOL_Asbuilt].[PART-ATA-NO];
Code:
Option Compare Database
Option Explicit
'Const adOpenStatic = 3
'Const adLockOptimistic = 3
Function queryDatabase()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim qdf As QueryDef
'Dim rsQuery As DAO.Recordset
Dim rows As Variant
Dim part_find_no() As String
Dim eqp_pos_no() As Integer
'Dim strSQL As String
Dim i As Integer
Dim j As Integer
'Set objConnection = CurrentDb.OpenRecordset("CTOL")
Set db = CurrentDb
Set qdf = db.QueryDefs("SicrProcess")
Set rs = qdf.OpenRecordset(dbOpenDynaset)
If rs.EOF Then GoTo Leave
rs.MoveLast
rs.MoveFirst
For i = 0 To rs.RecordCount
part_find_no() = rs("PART FIND NO")
eqp_pos_no() = rs("EQP_POS_CD")
If part_find_no(i) = part_find_no(i - 1) Then
eqp_pos_no(i) = eqp_pos_no(i) + 1
End If
Debug.Print rs.Fields("PART FIND NO") & " " & rs.Fields("EQP_POS_CD")
rs.MoveNext
Next i
Leave:
On Error Resume Next
rs.Close
Set rs = Nothing
qdf.Close
Set qdf = Nothing
Set db = Nothing
db.Close
On Error GoTo 0
Exit Function
ErrProc:
MsgBox Err.Description, vbCritical
Resume Leave
End Function
I'm not sure what's wrong here. It's expecting arrays, but do I have to initialize those arrays somehow? How would I set those fields to an array from the results generated by the query? I want the arrays to be loaded with the results from that query but just those fields: PART FIND NO and EQP_POS_CD. Then it should loop through the rows in the two fields to increment EQP_POS_CD when the current PART FIND NO is the same as the previous PART FIND NO. Any advice on how to clean this up? Thanks.
I don't think array objects are needed. Consider:
Sub SetSeq()
Dim rs As DAO.Recordset, x As Integer, strPart As String, intSeq As Integer
Set rs = CurrentDb.OpenRecordset("SELECT [Part Find No], EQP_POS_CD FROM CTOL ORDER BY [Part Find No], SERIAL_NO;")
If rs.EOF Then GoTo Leave
rs.MoveLast
rs.MoveFirst
strPart = rs![Part Find No]
For x = 1 To rs.RecordCount
If rs![Part Find No] <> strPart Then
intSeq = 0
strPart = rs![Part Find No]
End If
intSeq = intSeq + 1
rs.Edit
rs!EQP_POS_CD = intSeq
rs.Update
rs.MoveNext
Next x
Leave:
On Error Resume Next
rs.Close
Set rs = Nothing
On Error GoTo 0
Exit Sub
ErrProc:
MsgBox Err.Description, vbCritical
Resume Leave
End Sub
The table after running code:
+------------+--------------+-----------+
| EQP_POS_CD | Part Find No | SERIAL_NO |
+------------+--------------+-----------+
| 1 | a | abc1 |
| 2 | a | abc2 |
| 3 | a | abc3 |
| 1 | b | abc4 |
| 2 | b | abc5 |
| 1 | c | abc6 |
| 2 | c | abc7 |
| 3 | c | abc8 |
+------------+--------------+-----------+

Find Lowest Value in Columns Access 2010

I have a table in Access 2010 that has 3 separate priority fields. I have a sub that looks through the columns, finds the smallest number, and puts it in an Overall Priority field.
Ex.
SubProjNo | GOPri | StrPri | SOPri
--------+-----------+----------+------------------
1234-12-01 | 100 | 7 | 61
1234-12-02 | | 18 | 2
1234-12-03 | 51 | |
ProjNo: 1234-12-00 Overall_Priority:2
I originally had the code under Private Sub Form_Current() but it slowed the program down way too much, so I moved it to an AfterUpdate for the subform that the table is in.
Private Sub MFWorkProjectssubform_AfterUpdate()
Dim MinGOPri As Variant
Dim MinStrPri As Variant
Dim MinSOPri As Variant
MinGOPri = DMin("[GOPri]", "[WorkProjects]", "WorkProjects.PROJNO = Activity.PROJNO")
MinStrPri = DMin("[StrPri]", "[WorkProjects]", "WorkProjects.PROJNO = Activity.PROJNO")
MinSOPri = DMin("[SOPri]", "[WorkProjects]", "WorkProjects.PROJNO = Activity.PROJNO")
Overall_Priority = IIf(((IIf([MinGOPri] < [MinStrPri], [MinGOPri], [MinStrPri])))
< [MinSOPri], ((IIf([MinGOPri] < [MinStrPri], [MinGOPri], [MinStrPri]))), [MinSOPri])
End Sub
The problem is, now, all the columns are cleared and only the largest value is left. Any suggestions for how to get this to work, or how to speed it up if I put it back in Form_Current would be really appreciated.
You don't need all this. For the Overall_Priority textbox use this expression as ControlSource:
=IIf(((IIf([GOPri]<[StrPri],[GOPri],[StrPri])))<[SOPri],((IIf([GOPri]<[StrPri],[GOPri],[StrPri]))),[SOPri])
Edit for Null and reduced:
=IIf(IIf(Nz([GOPri],9999)<Nz([StrPri],9999),Nz([GOPri],9999),Nz([StrPri],9999))<Nz([SOPri],9999),IIf(Nz([GOPri],9999)<Nz([StrPri],9999),Nz([GOPri],9999),Nz([StrPri],9999)),Nz([SOPri],9999))
Use this as a fourth column; name it, say, RowMin.
Then, in the footer, use =Min([RowMin]) as the controlsource for your totals box.
How about using recordsets, is this an option ?
Dim rst As Object
Dim minValue As Integer
Dim fieldCounter As Long
Dim minPriority as Long
minPriority = 9999
Set rst = Me.recordsetclone
With rst
.MoveFirst
While Not .EOF
For fieldCounter = 0 To .Fields.Count-1
if(.Fields(fieldcounter).name = "GOPri" or .Fields(fieldcounter).name = "StrPri" or .Fields(fieldcounter).name = "SOPri" ) then
Debug.print "Now you are checking : " &.Fields(fieldcounter).Name & " with value : " & .Fields(fieldcounter) & " Current minPriority = " & minPriority
If len(Nz(.Fields(fieldCounter),"")) > 0 Then
If .Fields(fieldCounter) < minPriority Then minPriority = .Fields(fieldCounter)
End If
End if
Next
.MoveNext
Wend
End With
Set rst = Nothing
Overall_Priority = minPriority
Maybe you need to adjust the fieldCounter to match your Table structure
The fields are counted from 0 -->.... according to your question.
Fields(0) = SubProjNo
Field(1) = GoPRi
If you want this column to always be a function of the other three fields, then you could create a calculated field to the table. The help documents can show you how; also this article gives directions:
https://support.office.com/en-us/article/Add-a-calculated-field-to-a-table-14a60733-2580-48c2-b402-6de54fafbde3
Generally you would define a new field on the table and set it's formula to the maximum of the other three fields. Then any time the calculated field is referenced it will always give you the maximum of them.
The other option is to just not worry about saving the field at all at the time of data entry and simply create a view that adds a field defined to be the maximum of the three values.

Only show column that has a value

I'm trying to show columns in a query where the value is not null in Ms Access (2010).
I have a query that now gives me this, where name, field1,... are the column headers:
Name | field1 | field2 | field 3 | field 4 | field5
mike | x | | x | x |
So now I don't want to see Field2 and Field5 in that query. I have a lot more fields then 5, and I only want to see the one with a value.
It's also fine If you can tell me a way to get the column names ( ex field1, field3,field4)
Thanks
You'll have to use a simple WHERE statement in your SQL. For example:
SELECT tbl.*, tbl.field2, tbl.field5
FROM tbl
WHERE tbl.field2 Is Not NULL AND tbl.field5 Is Not Null;
This will return all fields and all rows, where field2 and field5 are not Null.
EDIT: Since I am more familiar with vba, I would use the following approach to reach the desired output as stated in the comments.
Start by creating the query.
SELECT tbl.*
FROM tbl
WHERE tbl.ID = 12345;
Let's say you name it "qry_record". Afterwards, I would loop through the fields with a recorset, and create a new dynamic sql statement with the fields that have a value.
Dim rs As Recordset
Dim fld As Field
Dim sqlstatement As String: sqlstatement = "SELECT "
Set rs = CurrentDb.OpenRecordset("qry_record")
With rs
.MoveFirst
For Each fld In .Fields
If IsNull(fld.value) = False Then
Debug.Print fld.Name
sqlstatement = sqlstatement & "tbl." & fld.Name & ", "
End If
Next
End With
rs.Close
Set rs = Nothing
sqlstatement = sqlstatement & "FROM tbl"
DoCmd.RunSQL sqlstatement
EDIT: I have tested the code, and made a minor adjustment. Should work fine now on any table in your access database.

MS Access counting duplicate row entries and returning value to column

Just started using Access so I'm not sure of the best way to do this. My table looks something like this:
UNIQUE_ID EVT_ID (DESIRED COLUMN)
1 1000 6
2 1000 6
3 1000 6
4 1000 6
5 1000 6
6 1000 6
7 1001 3
8 1001 3
9 1001 3
Each instance of EVT_ID can contain anything from 2-30 UNIQUE_IDs.
I would like to create a new column in the database which contains the number of UNIQUE_IDs in a given EVT_ID. I'd ideally like to do this using VBA as that's where I'm more comfortable but would be happy with any solution.
In Access, open the table in Design View and add the field that will hold the new values. Save the changes and close the table, and then you can use the following VBA code to update the values
Option Compare Database
Option Explicit
Sub UpdateDesiredColumn()
Dim cdb As DAO.Database, rst As DAO.Recordset, qdf As DAO.QueryDef
Set cdb = CurrentDb
Set rst = cdb.OpenRecordset( _
"SELECT EVT_ID, COUNT(*) AS n FROM MyTable GROUP BY EVT_ID", _
dbOpenSnapshot)
Set qdf = cdb.CreateQueryDef("", _
"PARAMETERS [prmCount] Long, [prmEVT_ID] Long;" & _
"UPDATE MyTable SET DESIRED_COLUMN=[prmCount] WHERE EVT_ID=[prmEVT_ID]")
Do Until rst.EOF
qdf!prmCount = rst!n
qdf!prmEVT_ID = rst!EVT_ID
qdf.Execute dbFailOnError
rst.MoveNext
Loop
Set qdf = Nothing
rst.Close
Set rst = Nothing
Set cdb = Nothing
End Sub