Sort not working using dbOpenDynaset in vba - vba

How can I sort the name of the wine in asc order using dbOpenDynaset
Here is my vba code
Dim critère As String
Dim strFormateDesNomVins As String
Dim maBase As Database
Dim tblVins As Recordset
Set maBase = CurrentDb()
Set tblVins = maBase.OpenRecordset("tblVins", dbOpenDynaset)
critère = "[NoTypeVin]=" & typeVin
tblVins.Sort = "NomVin ASC"
tblVins.FindFirst critère
Do Until tblVins.NoMatch
strFormateDesNomVins = strFormateDesNomVins & tblVins!NomVin & vbCrLf
tblVins.FindNext critère
Loop
This part of the code does not work
tblVins.Sort = "NomVin ASC"
I want to sort the name of wine in asc order How can I do this using dbOpenDynaset Thank you for your help.

It works, but you must assign the sorted recordset to a (new) recordset and then use that:
tblVins.Sort = "NomVin ASC"
Set tblVins = tblVins.OpenRecordset()
or:
Set tblVinsSorted = tblVins.OpenRecordset()
or create it sorted initially:
Set tblVins = maBase.OpenRecordset("Select * From tblVins Order By NomVin", dbOpenDynaset)

Rather than trying to use .Sort and .FindFirst/.FindNext, it is better to open a recordset that is already filtered and ordered as you want:
Sub sWine()
Dim db As DAO.Database
Dim rsData As DAO.Recordset
Dim strSQL As String
Dim strFormateDesNomVins As String
Dim typeVin As Long
typeVin = 1
Set db = DBEngine(0)(0)
strSQL = "SELECT NomVin FROM tblVins WHERE NoTypeVin=" & typeVin & " ORDER BY NomVin ASC;"
Set rsData = db.OpenRecordset(strSQL, dbOpenDynaset)
If Not (rsData.BOF And rsData.EOF) Then
Do
strFormateDesNomVins = strFormateDesNomVins & rsData!NomVin & vbCrLf
rsData.MoveNext
Loop Until rsData.EOF
End If
Debug.Print strFormateDesNomVins
rsData.Close
Set rsData = Nothing
Set db = Nothing
End Sub
In the example above, I am creating a recordset that is based on tblVins, sorted by NomVin, and only having records where NoTypeVin is equal to typeVin (in this case 1).
Regards

Related

Any Other Way To Speed Up Code For INSERT INTO STATEMENTS for N Rows?

Im making Codes Inserting Data into a autonumber Columns to a table that composes of Two COlumns.
My Table is Access and Front End is Excel. My Access Table contains ID (which is AutoNumber) and Paycode which is base on a cell. I need this codes to use it as Unique IDs in which later on will post it back to Ms Access separate Table.
Sub ImportJEData()
Dim cnn As ADODB.Connection 'dim the ADO collection class
Dim rst As ADODB.Recordset 'dim the ADO recordset class
Dim dbPath
Dim x As Long
Dim var
Dim PayIDnxtRow As Long
'add error handling
On Error GoTo errHandler:
'Variables for file path and last row of data
dbPath = Sheets("Update Version").Range("b1").Value
Set var = Sheets("JE FORM").Range("F14")
PayIDnxtRow = Sheets("MAX").Range("c1").Value
'Initialise the collection class variable
Set cnn = New ADODB.Connection
'Create the ADODB recordset object.
'Set rst = New ADODB.Recordset 'assign memory to the recordset
'Connection class is equipped with a —method— named Open
'—-4 aguments—- ConnectionString, UserID, Password, Options
'ConnectionString formula—-Key1=Value1;Key2=Value2;Key_n=Value_n;
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
'two primary providers used in ADO SQLOLEDB —-Microsoft.JET.OLEDB.4.0 —-Microsoft.ACE.OLEDB.12.0
'OLE stands for Object Linking and Embedding, Database
Do
On Error Resume Next 'reset Err.obj.
'Get the Max ID +1
Set rst = Nothing
Set rst = New ADODB.Recordset 'assign memory to the recordset
SQL = "SELECT Max(ApNumber)+1 FROM PayVoucherID "
rst.Open SQL, cnn
'Check if the recordset is empty.
If rst.EOF And rst.BOF Then
'Close the recordet and the connection.
Sheets("Max").Range("A2") = 1
Else
'Copy Recordset to the Temporary Cell
Sheets("MAX").Range("A2").CopyFromRecordset rst
End If
'Insert the Data to Database And Check If no Errors
Sql2 = "INSERT INTO PayVoucherID(ApNumber)Values('" & Sheets("MAX").Range("A2") & "') "
cnn.Execute Sql2
Loop Until (Err.Number = 0)
'And if No errors COpy temporary to NEw Sub Temporary Data for Reference
Sheets("LEDGERTEMPFORM").Range("D1").Value = Sheets("MAX").Range("A2").Value
'Securing ChckID Seq Number
'ADO library is equipped with a class named Recordset
For x = 1 To PayIDnxtRow
Set rst = Nothing
Set rst = New ADODB.Recordset 'assign memory to the recordset
rst.AddNew
'Insert the Data to Database And Check If no Errors
Sql2 = "INSERT INTO PayPaymentID(ApNumber)Values('" & Sheets("LEDGERTEMPFORM").Range("B2") & "') "
cnn.Execute Sql2
Next x
Set rst = Nothing
Set rst = New ADODB.Recordset 'assign memory to the recordset
SQL = "Select PayID From PayPaymentID where APNumber = " & Sheets("LEDGERTEMPFORM").Range("B2") & " order by PayID "
rst.Open SQL, cnn
Sheets("PaySeries").Range("B2").CopyFromRecordset rst
Set rst = Nothing
rst.Close
' Close the connection
cnn.Close
'clear memory
Set rst = Nothing
Set cnn = Nothing
'communicate with the user
'MsgBox " The data has been successfully sent to the access database"
'Update the sheet
Application.ScreenUpdating = True
On Error GoTo 0
Exit Sub
errHandler:
'clear memory
Set rst = Nothing
Set cnn = Nothing
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Export_Data"
End Sub
In this section Below Would like to know if theres another way without using or even faster type of loop.
'Securing ChckID Seq Number
'ADO library is equipped with a class named Recordset
For x = 1 To PayIDnxtRow
Set rst = Nothing
Set rst = New ADODB.Recordset 'assign memory to the recordset
rst.AddNew
'Insert the Data to Database And Check If no Errors
Sql2 = "INSERT INTO PayPaymentID(ApNumber)Values('" & Sheets("LEDGERTEMPFORM").Range("B2") & "') "
cnn.Execute Sql2
Next x
Set rst = Nothing
Set rst = New ADODB.Recordset 'assign memory to the recordset
SQL = "Select PayID From PayPaymentID where APNumber = " & Sheets("LEDGERTEMPFORM").Range("B2") & " order by PayID "
rst.Open SQL, cnn
Sheets("PaySeries").Range("B2").CopyFromRecordset rst
Finally Ive figured it Out it went better from 40 to 19s Thanks to the idea of #miki180.
Heres my code below starting from DO...
Do
On Error Resume Next 'reset Err.obj.
'Get the Max ID +1
Set rst = Nothing
Set rst = New ADODB.Recordset 'assign memory to the recordset
SQL = "SELECT Max(ApNumber)+1 FROM PayVoucherID "
rst.Open SQL, cnn
'Check if the recordset is empty.
'Copy Recordset to the Temporary Cell
Sheets("MAX").Range("A2").CopyFromRecordset rst
'Insert the Data to Database And Check If no Errors
Sql2 = "INSERT INTO PayVoucherID(ApNumber)Values('" & Sheets("MAX").Range("A2") & "') "
cnn.Execute Sql2
Loop Until (Err.Number = 0)
xlFilepath = Application.ThisWorkbook.FullName
SSql = "INSERT INTO PaypaymentID(Apnumber) " & _
"SELECT * FROM [Excel 12.0 Macro;HDR=YES;DATABASE=" & xlFilepath & "].[MAX$G1:G15000] where APNumber > 1"
cnn.Execute SSql
Set rst = Nothing
Set rst = New ADODB.Recordset 'assign memory to the recordset
SQL = "Select PayID From PayPaymentID where APNumber = " & _
Sheets("LEDGERTEMPFORM").Range("B8") & " order by PayID "
rst.Open SQL, cnn
Sheets("PaySeries").Range("B2").CopyFromRecordset rst

Run a excel macro with sql quicker?

This code do the work but takes 10 minutes to run. There is maybe a way in the sql part to make it faster. There is not a lot of data so I uspect the sql part.
Dim noCsf As String
Dim cel As Range
Dim rng As Range
Dim noRow As Integer
Set rng = Sheets("CS_A").Range("D5:D68")
Dim targetRng1 As Range
Dim targetRng2 As Range
Dim bd As String
Dim cn As Object
Dim rs1 As Object
Dim rs2 As Object
Dim strSql As String
Dim strConnection As String
Set cn = CreateObject("ADODB.Connection")
Set rs1 = CreateObject("ADODB.Recordset")
Set rs2 = CreateObject("ADODB.Recordset")
bd = "U:\BD\Data_512_P.accdb"
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & bd
For Each cel In rng
If Len(cel.Address) = 4 Then
noRow = Right(cel.Address, 1)
Else
noRow = Right(cel.Address, 2)
End If
noCsf = cel.Value
rs1.Open "SELECT SommeDetotal_euaii FROM Rqt_CS_Anglo WHERE Expr1 LIKE '" & noCsf & "' ", cn, , , adCmdText
Set targetRng1 = Sheets("CS_A").Range("E" & noRow)
targetRng1.CopyFromRecordset rs1
rs1.Close
rs2.Open "SELECT SommeDeeua_apres_exemption FROM Rqt_CS_Anglo WHERE Expr1 LIKE '" & noCsf & "' ", cn, , , adCmdText
Set targetRng2 = Sheets("CS_A").Range("F" & noRow)
targetRng2.CopyFromRecordset rs2
rs2.Close
noRow = noRow + 1
Next
Debug.Print "DONE"
Set rs1 = Nothing
Set rs2 = Nothing
cn.Close
Set cn = Nothing
I expect a quicker running time maybe the sql part could be improve the fact in take data from a access request
Using a single query per line:
Const BD As String = "U:\BD\Data_512_P.accdb"
Dim cel As Range
Dim cn As Object
Dim rs As Object
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & BD
For Each cel In Sheets("CS_A").Range("D5:D68").Cells
rs.Open "SELECT SommeDetotal_euaii, SommeDeeua_apres_exemption FROM " & _
"Rqt_CS_Anglo WHERE Expr1 LIKE '" & cel.Value & "' ", cn, , , adCmdText
If Not rs.EOF Then
With cel.EntireRow
.Cells(5).Value = rs.Fields("SommeDetotal_euaii").Value
.Cells(6).Value = rs.Fields("SommeDeeua_apres_exemption").Value
End With
End If
rs.Close
Next cel
Depending on the size of the source table it may be quicker to build (eg) a lookup table using a scripting dictionary than to make repeated queries to the database.
If the database is on a mapped drive then creating a [temporary] local copy will likely speed things up.
If that still doesn't help then you can add more details about how many rows you're processing, are there any duplicates, and what's the size of your source DB table.

DLOOKUP from a query on current recordset

I am trying to do a dlookup where the criteria should be the current recordset and the textbox number (eg text13) should update to the next textbox number (eg text14):
'Count MasterList Items
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rsCount As Integer
Dim queryNameOrSQL As String
queryNameOrSQL = "qryMasterList"
Set db = CurrentDb
Set rs = db.OpenRecordset(queryNameOrSQL)
rsCount = rs.RecordCount
i = 1
textBoxIndex = 13
Do While i <= rsCount
Me.Text & textBoxIndex = DLookup("[Item]", "MasterList", "WHERE RECORDSET = " & i)
i = i + 1
textBoxIndex = textBoxIndex + 1
Loop
There is no need to count the records - just loop along:
Const textBoxIndex As Long = 12
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim queryNameOrSQL As String
Dim recorditem As Long
queryNameOrSQL = "qryMasterList"
Set db = CurrentDb
Set rs = db.OpenRecordset(queryNameOrSQL)
While Not rs.EOF
recorditem = recorditem + 1
Me("Text" & CStr(textBoxIndex + recorditem) & "").Value = DLookup("[Item]", "MasterList", "WHERE RECORDSET = " & recorditem & "")
rs.MoveNext
Wend
rs.Close

How to use variable initiated in SQL query?

I made a query to get Max value of a certain column
sSQLmax = "SELECT MAX([tablename]!rowname) as MaxNum FROM [tablename]"
I want to use MaxNum value. I tried it in a Msgbox and gave me a blank value. I tried all these:
MsgBox "MaxNum" & MaxNum
MsgBox "MaxNum" & sSQLMAX.MaxNum
MsgBox "MaxNum" & sSQLMAX!MaxNum
More of the code
Dim db As DAO.Database, rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset(sSQLmax)
but none works, Im sure its simple but it escapes me
With your code you are only setting a variable to a string. You are not actually doing anything with it. This is probably more of what you are looking for:
Dim db As DAO.Database, rst As DAO.Recordset, sSQLmax As String
sSQLmax = "SELECT MAX([tablename].rowname) as MaxNum FROM [tablename]"
Set db = CurrentDb
Set rst = db.OpenRecordset(sSQLmax, dbOpenDynaset)
If (rst.RecordCount <> 0) Then
rst.MoveFirst
MsgBox "MaxNumber: " & rst.Fields("rowname")
End If
Try the DMax function
Dim result as String
result = DMax("[COLUMN NAME]", "[TABLE NAME]")

Looping through Table Records to Update another Tables Records based on a Key Identifier

I keep having issues with this query saying there are no reocrds but I know there are because I am looking at the table. I want to loop through a table to find certain column information based off a few parameters on the click of a button.
So when I click my button it'll loop through table one find the fields I need based on the ID and update the other table with those fields.
Private Sub GetResults_Click()
Dim strSQL As String
Dim SQL As String
Dim dba As Database
Dim tbl As Recordset
Dim rst1 As Recordset
Dim tstdt As Date
tstdt = Me.Date.Value
Set dba = CurrentDb
Set tbl = dba.OpenRecordset("tbl_Results", dbOpenDynaset, dbSeeChanges)
strSQL = "SELECT * FROM tbl_Results"
Set tbl = dba.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges)
If Not tbl.EOF Then
With tbl
.MoveFirst
Do Until tbl.EOF
Call getDataRecords(tbl!SystemAssignedPersonID, tstdt)
.MoveNext
Loop
End With
End If
Set rst1 = Nothing
Set tbl = Nothing
Set dba = Nothing
End Sub
Function getDataRecords(PersonID As Variant, TestDate As Date)
Dim dba As Database
Dim rst As Recordset
Dim rst1 As Recordset
Dim SQL As String
Set dba = CurrentDb
Set rst = dba.OpenRecordset("tbl_Results", dbOpenDynaset, dbSeeChanges)
Set rst1 = dba.OpenRecordset("dbo_tbl_Random", dbOpenDynaset, dbSeeChanges)
SQL = "SELECT * FROM dbo_tbl_Random WHERE SystemAssignedPersonID = " & PersonID & " AND Date = " & Date & " AND MenuUsed = 'RandomResult'"
Set rst1 = dba.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
rst.AddNew
rst.Fields("FileSent") = rst1!FileSent
rst.Fields("Result") = rst1!Result
rst.Update
End Function
Help before I go nuts! Thanks!
You're over-complicating things here. All this can be done in 1 SQL statement
Update tbl_Results as Res
Inner join dbo_tbl_Random as rand
on Res.PersonID = Rand.SystemAssignedPersonID and Res.[Date] = Rand.[Date]
set Res.FileSent = Rand.FileSent ,
Res.Result = Rand.Result
Where Rand.MenuUsed = 'RandomResult'
You can execute like this
dim sql as string
sql = "Update tbl_Results as Res " & _
"Inner join dbo_tbl_Random as rand " & _
" on Res.PersonID = Rand.SystemAssignedPersonID and Res.[Date] = Rand.[Date] " & _
"set Res.FileSent = Rand.FileSent , " & _
" Res.Result = Rand.Result " & _
" Where Rand.MenuUsed = 'RandomResult' "
CurrentDb.Execute(sql)
Update:
This is how I am expecting your tables are set up
tbl_results
dbo_tbl_Random
How I set up the query in the designer to confirm it is working