Microsoft Access VBA Tutorials for self-paced learning, Class Modules, SQL Techniques, and AI Integration Guides.

Showing posts with label Records. Show all posts
Showing posts with label Records. Show all posts

Top N Records in Query

Top N Records in a Query.

We have seen the usage of different types of complicated Queries like the following:

Today, we will learn how to define and extract the top 100 records, or a certain percentage of the total records, based on the values in a particular Column.

Review of Rules of Queries.

You need to know only a few rules to work with this type of Query.

  1. You can select several Columns of data from the source for output.

  2. You must sort one or more columns of data in ascending or descending Order, and the leftmost sorted column will pick the top valuation records.

  3. If the output contains duplicate records (i.e., two or more records with identical values in all columns), you can set the Unique Values property to Yes, which is equivalent to using a DISTINCT clause in the SQL SELECT statement, to suppress the duplicates.

  4. If the query has more than one Table/Query as the source, and duplicate records are found in the output, set the Unique Records Property to Yes (DISTINCTROW clause in the SELECT statement) to suppress duplicates.

Create a Sample Query.

  1. Create a new database or one of your existing databases.

  2. Import the Order Details and Products Table from the Northwind.mdb sample Database. There is a Combobox in the Order Details Table that retrieves the Product Name from the Products Table. The Product Code in the Order Details Table is linked to the Product Code in the Products Table. Open a new Query in SQL View (without selecting a Table/Query from the displayed list).

  3. Copy and paste the following SQL String into the SQL window, and save the Query as Order_DetailsQ.

    SELECT TOP 100 [Order Details].ProductID, [Order Details].UnitPrice
    FROM [Order Details]
    WHERE ((([Order Details].OrderID) Between 10248 And 10300))
    ORDER BY [Order Details].UnitPrice DESC;
  4. Open the Query in Design View and check the order of field placement and the Sort Field.

  5. Right-click an empty area above the column grid to display the Query Shortcut Menu, select the Properties… option to display the Property Sheet. Check the image below:

  6. Ensure that the Top Values Property is set to 100 to filter the Query to 100 records with the highest Unit Price values.

  7. Change the Query View to Datasheet View to display the output records.  See the image given below:

    The Order Details table contains multiple records of the same product under different OrderIDs. In this example, we have intentionally excluded the OrderID field from the data columns, using it only in the criteria to select records with OrderIDs between 10248 and 102300, which also results in some duplicate records. As shown in the image above, several duplicate product records appear in the output. This scenario provides an opportunity to experiment with the Unique Values property settings to remove duplicates.

    Eliminating Duplicate Records.

  8. Change the Top Values property to All, and the Query to Datasheet View. The output will be about 150 records for OrderID Range between 10248 and 102300.

  9. Change the Query in Design View and display its Property Sheet.

  10. Set the Top Values property to 100 and the Unique Values property to Yes.

  11. Change the Query in the Datasheet View and inspect the output.

    Now the duplicate records are suppressed (29 records removed), leaving only 71 records in the output. The next property, Unique Records, can be set to Yes to achieve the same result when fields from two or more tables or queries are joined in a query design. This is useful when the output contains duplicate records due to a one-to-many relationship between the tables.

    We have specified 100 records in the Top Values Property, but the Unique Values property setting reduced the number of records to 71 after suppressing duplicates. 

  12. Change the Top Values Property setting from 100 to 25% and change the View to Datasheet.

Using the Percentage setting, the output returns only one-fourth of the total records. With Unique Values set to Yes, this yields 18 records, out of a total of 71. With Unique Values set to No, it returns 39 records, which is approximately one-fourth of the total 150 records.

The Top Values Property setting can be a specific number or a percentage of Total Records.

Share:

GetRows Function and Exporting Data

GetRows Function and Exporting Data.

We will create a useful data export utility with the GetRows() method of the Recordset Object. The GetRows method loads the entire data set from the table into memory as a two-dimensional Variant Array in a single statement. Let us try it with an example to see how this is done. An image of a sample table is given below, and we will see what this will look like in memory when loaded with the help of the GetRows() method of the Recordset Object:

Table: Employees
ID Name Birthdate Height Weight
1 Nancy 12/10/1980 164 58
2 Peter 05/07/1975 180 80
3 Linda 17/11/1982 170 60

The VBA Code.

The following sample VBA Routine loads the above data into memory, and a listing is dumped in the Debug Window:

Public Function Test(ByVal tblName As String)
Dim db As Database, rst As Recordset, varData As Variant
Dim intFields As Integer, intRecords As Integer, j As Integer, k As Integer
Dim rec As String, fld_type As Integer

Set db = CurrentDb
Set rst = db.OpenRecordset(tblName, dbOpenTable)
j = rst.RecordCount - 1
k = rst.Fields.Count - 1

varData = rst.GetRows(j + 1)

For intRecords = 0 To j
    rec = ""
    For intFields = 0 To k
    fld_type = rst.Fields(intFields).Type

    If fld_type = 11 Or fld_type = 12 Then
      GoTo nextField
    End If
      rec = rec & varData(intFields, intRecords) & ","
nextField:
    Next
    rec = Left(rec, Len(rec) - 1)
    Debug.Print rec
Next
rst.Close
Set rst = Nothing
Set db = Nothing
End Function

The arrangement of records in memory in a two-dimensional array looks like the following:

1 2 3
Nancy Peter Linda
12/10/1980 05/07/1975 17/11/1982
164 180 170
58 80 60

The Memory Image of the Data.

The records are not stored in the same row-wise order as they appear in Datasheet view; instead, they are loaded into memory in columns. Once the data is in memory, it is important to understand how to reference the two-dimensional array correctly to access and output each record in the proper order. In the Debug window, you can see that each field value is separated by a comma in the listing.

In a typical two-dimensional array, the first index represents the row number, and the second index represents the column number. However, in this case, the structure is reversed: the first index corresponds to the field order number, and the second index represents the record number. You can confirm this by examining the sample memory arrangement shown above.

Export Data in Text Format

We will write a small utility program to export any MS Access Table to a comma-delimited Text/CSV File, so that the data can be transported through the internet or imported into other applications.

The VBA code of the program is given below:

Public Function CreateDelimited(ByVal xtableName As String, ByVal txtFilePath As String)
'-----------------------------------------------------
'Utility: CreateDelimited()
'Author : a.p.r.pillai
'Date   : Dec. 2010
'Purpose: Create Comma Delimited Text File from Table 
'Rights : All Rights Reserved by www.msaccesstips.com
'-----------------------------------------------------
Dim db As Database, rst As Recordset
Dim varTable() As Variant, j As Long, k As Long
Dim rec As String, fld_type As Integer
Dim intRecords As Integer, intFields As Integer

Set db = CurrentDb
Set rst = db.OpenRecordset(xtableName, dbOpenTable)
varTable = rst.GetRows(rst.RecordCount)
k = rst.Fields.Count - 1
j = rst.RecordCount - 1

Open txtFilePath For Output As #1
rec = ""
For intFields = 0 To k
   fld_type = rst.Fields(intFields).Type
        If fld_type = 11 Or fld_type = 12 Then GoTo nextField
   rec = rec & Chr$(34) & rst.Fields(intFields).Name & Chr$(34) & ","
nextField:
Next
rec = Left(rec, Len(rec) - 1)
Print #1, rec
For intRecords = 0 To j
    rec = ""
    For intFields = 0 To k
        fld_type = rst.Fields(intFields).Type
        If fld_type = 11 Or fld_type = 12 Then GoTo Next_Field
        rec = rec & IIf(fld_type = 10, Chr$(34) & varTable(intFields, intRecords) & Chr$(34), varTable(intFields, intRecords)) & ","
Next_Field:
        Next: rec = Left(rec, Len(rec) - 1)
        Print #1, rec
Next
Close #1
rst.Close

Set rst = Nothing
Set db = Nothing

End Function

The Utility can be called from a CommandButton Click Event procedure after setting the Table name and the target file pathname in text boxes.  You can test the utility by calling it from the Debug Window (Immediate Window) directly as given below:

CreateDelimited "Products", "C:\Temp\Products.txt"

NB: If MEMO or Photo Fields are present in the Table, they are excluded from the output file.

The target file extension can be either .TXT or .CSV.

Earlier Post Link References:

Share:

PRESENTATION: ACCESS USER GROUPS (EUROPE)

Translate

PageRank

Post Feed


Search

Popular Posts

Blog Archive

Powered by Blogger.

Labels

Forms Functions How Tos MS-Access Security Reports msaccess forms Animations msaccess animation Utilities msaccess controls Access and Internet MS-Access Scurity MS-Access and Internet External Links Queries Array Class Module msaccess reports Accesstips msaccess tips WithEvents Downloads Objects Menus and Toolbars MsaccessLinks Process Controls Art Work Collection Object Property msaccess How Tos Combo Boxes ListView Control Query VBA msaccessQuery Calculation Dictionary Object Event Graph Charts ImageList Control List Boxes TreeView Control Command Buttons Controls Data Emails and Alerts Form Custom Functions Custom Wizards DOS Commands Data Type Key Object Reference ms-access functions msaccess functions msaccess graphs msaccess reporttricks Command Button Report msaccess menus msaccessprocess security advanced Access Security Add Auto-Number Field Type Form Instances ImageList Item Macros Menus Nodes Recordset Top Values Variables msaccess email progressmeter Access2007 Copy Excel Expression Fields Join Methods Microsoft Numbering System RaiseEvent Records Security Split SubForm Table Tables Time Difference Utility WScript Workgroup Wrapper Classes database function msaccess wizards tutorial Access Emails and Alerts Access Fields Access How Tos Access Mail Merge Access2003 Accounting Year Action Animation Attachment Binary Numbers Bookmarks Budgeting ChDir Color Palette Common Controls Conditional Formatting Data Filtering Database Records Defining Pages Desktop Shortcuts Diagram Disk Dynamic Lookup Error Handler Export External Filter Formatting Groups Hexadecimal Numbers Import Labels List Logo Macro Mail Merge Main Form Memo Message Box Monitoring Octal Numbers Operating System Paste Primary-Key Product Rank Reading Remove Rich Text Sequence SetFocus Summary Tab-Page Union Query User Users Water-Mark Word automatically commands hyperlinks iSeries Date iif ms-access msaccess msaccess alerts pdf files reference restore switch text toolbar updating upload vba code