How to fix MS Access EnumFields error in VBA - vba

I just started studying VBA for Access. I am therefore using some examples of site "https://learn.microsoft.com/en-us/office/client-developer/access/access-home".
When the code contains "EnumFiels" its execution generates the error "Sub or Function not defined".
I can't understand the reason for it and, above all, I don't know how to eliminate it.
For instance:
Sub WhereX()
Dim dbs As Database, rst As Recordset
Set dbs = OpenDatabase("Northwind.mdb")
Set rst = dbs.OpenRecordset("SELECT LastName, " _
& "FirstName FROM Employees " _
& "WHERE LastName = 'King';")
rst.MoveLast
EnumFields rst, 12
dbs.Close
End Sub

Related

Automation Error when Attempting to Query Access Database Using VBA

I've made the following ADODB object declarations in code.
Dim OConn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field
Set OConn = New ADODB.Connection
Set rs = New ADODB.Recordset
I would like to use the following code to read from a table on a MS Access database file and generate a recordset, rs.
'Get the table name from the search results.
tableName = ThisWorkbook.Sheets("PLC Module Data").Cells(2, 9).Value
'Set the SQL string.
strSql = "SELECT Code, Points, Type, Description, Rating " & _
"FROM " & tableName
'Set the connection string and open the connection to the Access DB.
OConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=Q:\AutoCAD Improvements\PLC IO Utility Docs\PLC IO Spreadsheet
App\PLC IO App\ace_plc.mdb"
OConn.Open
'Open the recordset and error out if nothing is returned
Set rs = OConn.Execute(strSql)
If rs.EOF Then
MsgBox "No matching records found."
rs.Close
OConn.Close
Exit Sub
End If
I've checked the query statement within the Access file itself and it works fine. I always get the error
Run-time error'-2147217900 (80040e14)': Automation Error
on the line,
Set rs = OConn.Execute(strSql)
If anyone could take a look over my code and determine why this is happening it would be much appreciated. I've looked at similar examples online and it seems like this should be correct.
I added the brackets around the tableName string and it works now. Thanks for all the feedback.
'Set the SQL string.
strSql = "SELECT Code, Points, Type, Description, Rating " & _
"FROM [" & tableName & "]"

Performing SQL queries on basic Excel 2013 worksheet as table using ADO with VBA triggers Errors

I'm developping modules on a client XLSm with 32-bits 2013 Excel.
I'd like to use datas on worksheet as if it is an Access table.
With a lot of difficulties, I think connection is now OK.
Still, I have error : 3001 Arguments are of wrong type, are out of acceptable range. Error that I cannot understand.
Here excerpts of VBA lines :
In addition, I added 20 lines in data Worksheet below the header line to permit to Excel to interpret for the type of each columns.
varCnxStr = "Data Source=" & G_sWBookREINVOICingFilePath & ";" & "Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=15';"
With conXLdb
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Mode = adModeShareExclusive
.Open varCnxStr
End With
strSQL = "SELECT * "
strSQL = strSQL & " FROM [ReInvoiceDB$B2B5072] inum "
strSQL = strSQL & " WHERE inum.InvoiceNum LIKE '1712*' "
strSQL = strSQL & ";"
'>> TRIGGERs ERROR with the current Where Clause !!'
adoXLrst.Open strSQL, conXLdb, dbOpenDynamic, adLockReadOnly, adCmdText
If adoXLrst.BOF And adoXLrst.EOF Then
'no records returned'
GoTo Veloma
End If
adoXLrst.MoveFirst
Do While Not adoXLrst.EOF
'Doing stuff with row'
adoXLrst.MoveNext
Loop
sHighestSoFar = adoXLrst(1).Value '> just to try for RecordSet : Codes are not completed...
sPrefixeCURR = Mid(sHighestSoFar, 1, 4)
Highest = CInt(Mid(sHighestSoFar, 5))
'> Increment >'
Highest = Highest + 1
HighestStr = sPrefixeCURR & Format(Highest, "00")
strGSFNumber = HighestStr
adoXLrst.Close
conXLdb.Close
Veloma:
On Error Resume Next
Set adoXLrst = Nothing
Set conXLdb = Nothing
Exit Sub
Etc.
Any idea about what seems be wrong ?
Thank you
Below is an old example I have been using successfully. Note that the sheet name in the book are Sheet1 and Sheet2, but in the query I had to use sheet1$ and sheet2$. I noticed you had $ signs in the middle of your sheet names. perhaps that's the issue ?
Sub SQLUpdateExample()
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
con.Open "Driver={Microsoft Excel Driver (*.xls)};" & _
"DriverId=790;" & _
"Dbq=" & ThisWorkbook.FullName & ";" & _
"DefaultDir=" & ThisWorkbook.FullName & ";ReadOnly=False;"
Set rs = New ADODB.Recordset
Set rs = con.Execute("UPDATE [Sheet1$] inner join [Sheet2$] on [Sheet1$].test1 = [Sheet2$].test1 SET [Sheet1$].test3 = [Sheet2$].test2 ")
Set rs = Nothing
Set con = Nothing
End Sub
To give more details about the whole module to be implemented : it is to perform a Transaction unit.
This transaction will comprise 3 operations : get a max value from a column (Invoice number) to increment it, record the new number inside an Access table (by DAO), the same Excel file (by ADO) and generating document on HDD.
So it is aimed to use the Excel file as a table not as a file manipulated with Windows script or Excel VBA. My end user is disturbed by the pop-uping of an Excel opening file operation. As a developer, I'm feeling more comfortable with using SQL statements as much as possible inside Transaction session. Is that your opinion too ?

Access 2013 Compile error - object required

I use Access quite a bit but only dabble in VBA code. I have some code that works, but I tried to compile the code and get the following error.
Private Sub Report_Open(Cancel As Integer)
Dim RS As Date
Set RS = CurrentDb.OpenRecordset("tblDate")
MsgBox ("The month and year are: " & RS)
DoCmd.OutputTo acOutputReport, "LP Completions", "PDFFormat(*.pdf)", Chr(34) & "\\sharepoint.xx.yyyy.zzz\Reports\" & Format(RS.Fields(0), "yyyy-mm") & Chr(32) & " - LP Completions - Exec Report.pdf" & Chr(34), False
End Sub
I get a Compile Error: Object Required. In the code view the RS = is highlighted.
I have no clue why this is coming up. Can someone provide some guidance as to how to fix this? Thanks so much!
If you're opening a recordset the variable should be a recordset. You then reference the field in the table you're after in the messagebox.
If you have more than one record in the table it will return the first value - so either create a temporary query to return the value you're after, or search the recordset and go to the correct record.
Private Sub Test()
Dim RS As dao.Recordset
Set RS = CurrentDb.OpenRecordset("tblDate")
MsgBox "The month and year are: " & Format(RS.Fields("MyDateField"), "yyyy-mm")
End Sub
Edit:
If you're using a query to get the record:
Private Sub Test2()
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Set qdf = CurrentDb.CreateQueryDef("", "SELECT MAX(MyDateField) AS MaxDateField FROM tblDate")
Set rs = qdf.OpenRecordset
MsgBox "The month and year are: " & Format(rs.Fields("MaxDateField"), "yyyy-mm")
End Sub
In VBA, Set is only to be used when assigning to object variables. A variable of type Date is not an object variable, so you just say
RS = CurrentDb.OpenRecordset("tblDate")
(note that you can, if you really want to, put a Let in front, but pretty much no one ever does).

How to limit the number of results in an LDAP query

I'm programming an Office 2010 Word template that needs to interact with the Active Directory, to retrieve some user info. The user filling out the template can give some input for the search that is used to retrieve the AD info.
I'm using the ADODB Recordset and Command to setup my query:
Public Function GetActiveDirectoryInfo(searchString As String) As Object
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim strQuery, adoRecordset
'remove user input asteriks
searchString = Replace(searchString, "*", "")
' Setup ADO objects.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
strBase = "<LDAP://" & GLOBAL_LDAP_USER_OU & ">"
' Filter on user objects.
strFilter = "(&(objectCategory=person)(objectClass=user)(|(sn=" & searchString & "*)(cn=" & searchString & "*)))"
' Comma delimited list of attribute values to retrieve.
strAttributes = ACTIVE_DIRECTORY_FIELDS
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";OneLevel"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 10
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
'adoCommand.Properties("Maximum Rows") = 10 'error: read only
On Error GoTo err_NoConnection
' Run the query.
Set adoRecordset = adoCommand.Execute
Set foundItems = adoRecordset
Debug.Print "Found : " & foundItems.RecordCount & " records"
Exit Function
err_NoConnection:
'in case of error: return <nothing>
Debug.Print Err.description
Set GetActiveDirectoryInfo = Nothing
End Function
THis function is part of a User Class in MS Word.
My question: how to prevent the user from retrieving thousands of records? I have been reading about paging, but that seems more like a network-load-thing than actually limiting the search results that will eventually get back to me.
I've tried several things but with no results. For instance setting the MaxRecords or Maximum Rows properties. Both give an error (non existing property for the first, and read only error for the second).
ANy ideas anyone.
MS Office 2010 dutch
ADO Objects 6.0
Thanx!
Unfortunately ADO MaxRecord that limits the number of search results is not implemented for ADsDSObject. The link https://support.microsoft.com/kb/269361 details the workaround to solve the issue.

SQL insert with MS Access fails

I have just started to do some coding with Access and trying to create a function that adds a row to a table but this would not work.
I have created a simple table (Table1) with two columns "FirstName" and "LastName" and a button that fires off the following code:
Private Sub Command0_Click()
AppendRow "Table1", "John", "Doe"
End Sub
Where AppendRow is:
Function AppendRow(toTableName As String, firstName As String, lastName As String) As Boolean
' Returns True on success, false otherwise
' USAGE: AppendRow "toTableName", "firstName", "lastName"
On Error GoTo errhandler
Dim strSql As String
'Create the SQL string
strSql = "INSERT INTO " & toTableName & " (FirstName, LastName) " & _
"VALUES ('" & firstName & "', '" & lastName & "');"
'Print the SQL so we can paste into the query build if there are errors
Debug.Print strSql
MsgBox strSql
'Run the SQL Query
CurrentDb.Execute strSql
'If no errors return true
AppendRow = True
ExitHere:
Exit Function
errhandler:
'There is an error return false
AppendRow = False
With Err
MsgBox "Error " & .Number & vbCrLf & .Description, vbOKOnly Or vbCritical, "AppendTable"
End With
Resume ExitHere
End Function
The SQL string looks like this
INSERT INTO Table1 (FirstName, LastName) VALUES ('John', 'Doe')
EDIT: Added missing quotes.
You reported that you are now quoting the text values you attempt to insert, but that you do not get the row inserted and apparently no error message. I don't understand why that is so, and offer this simple procedure simply to see whether you can get something to work.
Public Sub AppendRow(ByVal toTableName As String, _
ByVal pFirstName As String, _
ByVal pLastName As String)
Dim db As DAO.Database
Dim rs As DAO.Recordset
'* ensure SetWarnings is not off *'
DoCmd.SetWarnings True
Set db = CurrentDb
Set rs = db.OpenRecordset(toTableName, dbOpenTable, dbAppendOnly)
With rs
.AddNew
!firstName = pFirstName
!lastName = pLastName
.Update
.Close
End With
Set rs = Nothing
Set db = Nothing
End Sub
I didn't include error handling because this is intended only for testing. I made it a subroutine instead of a function because I noticed you weren't using the function's return value in your code which called the function.
If this doesn't work for you, please tell us the error message you receive and which line in that procedure triggers the error.
HansUp's code didnt work for me until I removed the dbAppendOnly option from the OpenRecordSet function call. MS Help documentation implies that it is only valid for Dynaset RecordSets, not TableSet Recordsets. Changed it to "Set rs = db.OpenRecordset(toTableName, dbOpenTable)" and it worked.
But his code was extremely helpful and I am very grateful. I had been going around and around unable to make my .Execute "INSERT "...-type code work either. I have no idea what was going on with that. It worked once and I made a minor change... Maybe my blood pressure peaking from my aggravation had something to do with it.
btw, #ymail.com is a valid email domain despite what your automated eddress checker says.