Print Calculated Field Expression's Value to the Microsoft Access Immediate Window - vba

I did a little Microsoft Access DAO stuff to create a [FullName] Calculated Field (cFld As Field2 object) in one of my tables (tblEmpls) as a concatenation of [FirstName] and [LastName] in the table via the statement: cFld.Expression = "[FirstName] & ' ' & [LastName]".
I then used the TableDef.Fields.Append method on the cFld object to add it to the table. All good.
Now, when I try to print that expression to the Immediate window via 'Debug.Print "The FullName field is: " & cFld.Expression', the Immediate window output is: "The Calculated Field is: [FirstName] & ' ' & [LastName]", not say, "The Calculated Field is: David Bailey" like I want.
I guess I need a way to syntactically 'dereference' my cFld.Expression object so it's value not its name is printed in the Access VBA's Immediate window?
By the way, the fields in the database appear as expected: [FirstName]: "David": [LastName]: "Bailey": and [FullName]: "David Bailey"
The question: How do I get the concatenated [FullName] value, say, "David Bailey" to print in the Immediate window, and not the field names construct: "[FirstName] & ' ' & [LastName]"?
The TableDef object created the Calculated Field in the table, but yes I needed a RecordSet object for iteration through the table's records. Minimum set of code showing this.
Sub AddCFld()
Dim db As Database
Dim tdef As TableDef
Dim rst As Recordset2
Dim fld As Field2
Dim strFldName As String
Set db = CurrentDb
strFldName = "FullName"
Set tdef = db.TableDefs("tblEmpls")
On Error Resume Next
Set fld = tdef.Fields(strFldName)
On Error GoTo 0
If Not fld Is Nothing Then
Debug.Print "Oops, the Calculated Field already exists: " & strFldName
Set fld = Nothing
Set tdef = Nothing
Exit Sub
End If
Set fld = tdef.CreateField(strFldName, dbText, 200)
fld.Expression = "[FirstName] & ' ' & [LastName]"
Debug.Print "The Calculated Field expression is: " & fld.Expression
tdef.Fields.Append fld
Set rst = db.OpenRecordset("tblEmpls")
Do While Not rst.EOF
Debug.Print "The Calculated Field value is: " & rst!FullName
rst.MoveNext
Loop
db.Close
Set fld = Nothing
Set tdef = Nothing
End Sub
Immediate window output.
AddCFld
The Calculated Field expression is: [FirstName] & ' ' & [LastName]
The Calculated Field value is: Nancy Davolio
The Calculated Field value is: Andrew Fuller
The Calculated Field value is: Janet Leverling
The Calculated Field value is: Margaret Peacock
The Calculated Field value is: Steven Buchanan
The Calculated Field value is: Michael Suyama
The Calculated Field value is: Robert King
The Calculated Field value is: Laura Callahan
The Calculated Field value is: Anne Dodsworth

Ok, changed my answer a little bit :)
In the Immediate window you should use .value instead of .Expression
Debug.Print "The FullName field is: " & rs!Fullname.Value
Here is an example code:
Option Compare Database
Option Explicit
Private Sub Form_Open(Cancel As Integer)
' Loop Recordset with Do-Until
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("tblEmpls")
Do Until rs.EOF
Debug.Print "The fullName value is: " & rs!FullName.Value
rs.MoveNext
Loop
rs.Close
End Sub

Um, thanks very much, Micke. I guess I was trying to get the TableDef object to do what the RecordSet object was designed for. Oops! The TableDef object created the Calculated Field in the table, but yep I needed a RecordSet object to iterate through the table's records and print out the Calculated Fields therein to the Access Immediate window. My ignorance is now assuaged! (:>) Minimum set of code showing this ...
Sub AddCFld()
Dim db As Database
Dim tdef As TableDef
Dim rst As Recordset2
Dim fld As Field2
Dim strFldName As String
Set db = CurrentDb
strFldName = "FullName"
Set tdef = db.TableDefs("tblEmpls")
On Error Resume Next
Set fld = tdef.Fields(strFldName)
On Error GoTo 0
If Not fld Is Nothing Then
Debug.Print "Oops, the Calculated Field already exists: " & strFldName
Set fld = Nothing
Set tdef = Nothing
Exit Sub
End If
Set fld = tdef.CreateField(strFldName, dbText, 200)
fld.Expression = "[FirstName] & ' ' & [LastName]"
Debug.Print "The Calculated Field expression is: " & fld.Expression
tdef.Fields.Append fld
Set rst = db.OpenRecordset("tblEmpls")
Do While Not rst.EOF
Debug.Print "The Calculated Field value is: " & rst!FullName
rst.MoveNext
Loop
db.Close
Set fld = Nothing
Set tdef = Nothing
End Sub
Immediate window output ...
AddCFld
The Calculated Field expression is: [FirstName] & ' ' & [LastName]
The Calculated Field value is: Nancy Davolio
The Calculated Field value is: Andrew Fuller
The Calculated Field value is: Janet Leverling
The Calculated Field value is: Margaret Peacock
The Calculated Field value is: Steven Buchanan
The Calculated Field value is: Michael Suyama
The Calculated Field value is: Robert King
The Calculated Field value is: Laura Callahan
The Calculated Field value is: Anne Dodsworth

Related

Why does this line of code work half the time, and the other half gives me Data Type Conversion Error 3421

Here is the full code:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim frm As Access.Form
Dim i As Long
'For readability
Set frm = Forms!Frm_JobTicket
'Open Tbl_Schedule for adding Schedule Dates
Set db = CurrentDb
Set rs = db.OpenRecordset("Tbl_Schedule", dbOpenDynaset, dbAppendOnly)
'Creates loop for fields 1-14. Sets Date_ScheduledX = Forms!Frm_JobTicket!Txt_DateScheduledX. Runs through Loop then closes recordset
rs.AddNew
For i = 1 To 14
If (Not IsNull(frm("Txt_DateScheduled" & i & "_JobTicket"))) Then
rs("Date_Scheduled" & i) = frm("Txt_DateScheduled" & i & "_JobTicket")
End If
Next i
'Adds in Sales Order Number to Tbl_Schedule
rs!Sales_Order_Number = frm("Sales_Order_Number")
'Adds in Part Number to Tbl_Schedule
rs!Part_Number = frm("Part_Number")
'Adds updates and closes table
rs.Update
rs.Close
'Shows message box to inform the User if item was Scheduled
MsgBox "Item Scheduled."
'Runs Private Sub above. Clears all values from DateScheduled1-14 on Frm_JobTicket to null
ClearFields
'Clears DB and RS to null
Set db = Nothing
Set rs = Nothing
The line that doesn't work is this rs("Date_Scheduled" & i) = frm("Txt_DateScheduled" & i & "_JobTicket"). Sometimes it will run perfectly fine, and other times it gives me an endless flow of 3421 Data type conversion errors. I do not know what could be going wrong, none of the fields have default values, all of the fields in the table side are Date/Time with this same format, and now I am checking for nulls.
Any help would be greatly appreciated!!
Maybe something like
If Len(Me.Txt_DateScheduled & vbNullString) > 0 Then
rs("Date_Scheduled" & i) = frm("Txt_DateScheduled" & i & "_JobTicket")
Else
rs("Date_Scheduled" & i) = ""
End If
This is completely untested, but I think you should get the concept.

query a named single cell range vba

I am trying to select a single cell value in an excel spreadsheet named "AtwickShortfall" as follow
StrSql = "SELECT AtwickShortfall FROM [" & Glob_WsheetNameTradeLogOpsActions & "$AtwickShortfall]"
obviously does not work; can someone tell me the correct syntax ?
AtwickShortfall cell value is the sum of other values in the speadsheet; there are no tables in this spreadsheet at all.
UPDATE 1
tried this syntax
StrSql = "SELECT [AtwickShortfall] FROM [" & Glob_WsheetNameTradeLogOpsActions & "$]"
I get an error "No value given for one or more required parameters"
UPDATE 2
after amending my code as per #Dick Kusleika answer I now have this code
StrSql = "SELECT * FROM [AtwickShortfall]" ' & Glob_WsheetNameTradeLogOpsActions & "$AH34]"
Debug.Print (StrSql)
Set RecSet = ConnObj.Execute(StrSql)
If Not (RecSet Is Nothing) Then
With RecSet
If Not (.BOF) And Not (.EOF) Then
Debug.Print RecSet.Fields(0).Value
Else
'UdtKpi.HornInjMeterSum = 0
End If
End If
End With
End If
no errors but the recodset is empty (BOF is true); the value of AtwickShortfall is a formula that gives 0 at the moment. I also tried to remove the formula and fill the cell with 0 but same result: recordset BOF is true
UPDATE 3
I found a solution but please have a look at the screenshot below
cell AtwickShortfall is the one that I have now added a value of 125 on the column AH why this code work ?
StrSql = "SELECT Atw FROM [Operational_Actions$AH33:AH34]"
why it recognize the "atw" as a header of the range I gave??
If I change the above query to
StrSql = "SELECT Atw FROM [Operational_Actions$AH34:AH34]"
I get an epty recordset; It does not make sense how excel works to me; note that I have not implemented the worksheet data, it has been given to me
I think because the named range is at the workbook level (rather than worksheet level) that you can't specify what worksheet it's on. It's looking for a worksheet level named range when you specify the worksheet. This worked for me.
Sub getcell()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\99991-dc01\99991\dkusleika\My Documents\testadonamedrange.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=NO"";"
Set rs = cn.Execute("select * from [AtwickShortfall]")
Debug.Print rs.Fields(0).Value
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub

Debug.Print all data in a table

I am trying to use recordset code to loop through all the fields in a table and debug.print their values and field names in an order you would naturally read the table ie from left to right across columns then onto the row below
I have accomplished what I'm trying to do but only for the first row. This is the code:
Sub RecordSets()
Dim db As Database
Dim rs As Recordset
Dim i As Long
Set db = CurrentDb
Set rs = db.OpenRecordset("tbl1")
For i = 0 To rs.Fields.Count - 1
Debug.Print rs.Fields(i).Name
Debug.Print rs.Fields(i).Value
Next
rs.Close
db.Close
End Sub
Immediate window produces following result:
Category
Clothing
Item
Shirt
Price
5
This is the top row and is exactly as I want. But I cannot get any code to work accomplish this exact same thing for the other rows. I am 99% sure I need to use a Do Until .EOF loop in conjunction with the For...Next loop but I can't get the results whatever I try or I lock access up in an infinite query.
Thanks for your help
Untested:
Sub RecordSets()
Const SEP as String = vbTab
Dim db As Database
Dim rs As Recordset, numFlds As Long
Dim i As Long, s As String, sp as string
Set db = CurrentDb
Set rs = db.OpenRecordset("tbl1")
numFlds = rs.Fields.Count
'print the headers (field names)
For i = 0 To numFlds - 1
s = s & sp & rs.Fields(i).Name
sp = SEP '<< add separator for subsequent items
Next
Debug.Print s
'print the data
sp = "" '<< clear the separator
Do While Not rs.EOF
For i = 0 To numFlds - 1
s = s & sp & rs.Fields(i).Name
sp = SEP
Next
Debug.Print s
rs.MoveNext
Loop
rs.Close
db.Close
End Sub

MS Access Query to find gaps in sequential numbers when numbers are stored in Short Text field

I have a table (tblParts) with a PartNumber field (Short Text) which stores 6 digit part numbers for parts belonging to several families. The families are denoted by the first 2 digits of the part number (00, 01, 02, etc).
(NOTE: I did not create this table and am not able to change it at this time)
I need to find gaps in the numbering in order to fill in unused part numbers. If I have a project starting that needs 6 consecutive part numbers in a specific family, I want to find the first unused number in the first gap of that size or greater within that family.
Here is a small subset of the data.
PartNumber
020001
020002
020003
020004
020005
020006
020007
020009
020010
020011
020012
020013
020014
020019
020101
If I needed a single number, the query should find 020008. If I needed 3 numbers, it should find 0200015 and if I needed 10 numbers it should find 020020.
My SQL knowledge is very limited but I am trying to learn. I realize this would be much easier if the information was stored properly but I have no control over it.
I once wrote an article on the subject:
Find and Generate Missing Values in an Access Table
but that will fill up any gap until all new numbers were established. So, that code will need an expansion with an outer loop to ensure juxtaposed numbers at all times.
Private Sub btnSearch_Click()
' Read table/query sequentially to
' record all missing IDs.
' Fill a ListBox with missing values.
' A reference to Microsoft DAO must be
' present.
' Define search table or query.
Const cstrTable As String = "Orders"
Const cstrField As String = "OrderID"
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim lst As ListBox
Dim col As Collection
Dim strSQL As String
Dim strList As String
Dim lngLast As Long
Dim lngNext As Long
Dim lngMiss As Long
strSQL = "Select " & cstrField & "" _
& " From " & cstrTable & _
& " Order By 1;"
Set lst = Me!lstMissing
Set col = New Collection
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset(strSQL)
If rst.RecordCount = 0 Then
'The recordset is empty.
'Nothing to do.
Else
lngLast = rst(cstrField).Value
rst.MoveNext
While rst.EOF = False
lngNext = rst(cstrField).Value
For lngMiss = lngLast + 1 To _
lngNext - 1
col.Add (lngMiss)
Next
lngLast = lngNext
rst.MoveNext
Wend
'Generate next value in sequence.
'Discard if collecting only
'missing values.
col.Add (lngLast + 1)
End If
rst.Close
'Populate list box from collection.
For lngMiss = 1 To col.Count
If Len(strList) > 0 Then
strList = strList & ";"
End If
strList = strList & col(lngMiss)
Debug.Print col(lngMiss)
Next
lst.RowSource = strList
Debug.Print strList
Set rst = Nothing
Set dbs = Nothing
Set col = Nothing
Set lst = Nothing
End Sub

Excel table to Access query connection, [Microsoft][ODBC Microsoft Access Drive] too few parameters. expected 1

I'm trying to create a table in Excel, which takes data from Access Query. I'm unable to find this query listed under Data->From Access. I'm using Data->From Other Sources -> From Data connection Wizard -> ODBC DSN. On final step it throws error [Microsoft][ODBC Microsoft Access Drive] too few parameters. expected 1.
I will not post full query at this moment, it is long
I will post subquery part (with some formatting) , that already throws this error. Can someone take a look and pinpoint where is the problem.
All queries I have work properly in Access. But I need the results export to Excel, as whole reporting VBA tool is there. (I know I can make SELECT INTO and create table, but it is not as elegant and simple to update) Thank you all for your time. Have a nice day
SELECT
Employees.PersNo,
Employees.Employee_name,
Employees.Reporting_Month,
Employees.Gender_Key,
Employees.Start_Date,
Employees.Business_Unit,
Employees.Position_ID,
Employees.Position,
Employees.Local_Band,
Employees.PS_Group,
Employees.Wage_Amount,
val(Employees.Bonus) AS [Bonus_%],
val([Employees].[Commissions_(%)]) AS [Commisions_%],
Employees.Wage_type, Employees.Wkhrs,
Q1.Business_Unit,
Q1.Position_ID,
Q1.Position,
Q1.Local_Band,
Q1.PS_Group,
Q1.Wage_Amount,
[Q1].[Bonus_%],
[Q1].[Commisions_%],
Employees.Wage_type,
Employees.Wkhrs,
Employees.Evid_Status
FROM Employees LEFT JOIN (SELECT
Dateadd("m",1,[Employees.Reporting_Month]) AS Reporting_Month,
Employees.PersNo,
Employees.Local_Band,
Employees.PS_Group,
Employees.Wage_Amount,
val(Employees.Bonus) AS [Bonus_%],
val([Employees].[Commissions_(%)]) AS [Commisions_%],
Employees.Wage_type, Employees.Wkhrs,
Employees.Business_Unit,
Employees.Position_ID,
Employees.Position,
Employees.Evid_Status
FROM Employees WHERE Employees.Evid_Status=1 ) AS Q1
ON (Employees.Reporting_Month = [Q1].[Reporting_Month]) AND (Employees.PersNo = [Q1].[PersNo])
WHERE Employees.Evid_Status=1;
Because Position is a reserved word in MS Accces, simply escape the word in both outer query and subquery with backticks or square brackets.
Interestingly, while the table alias qualifier works for reserved words inside the MSAccess.exe GUI program, external ODBC calls like from Excel may fail without escaping such reserved words:
SELECT
...
Employees.[Position],
...
SELECT
...
Employees.`Position`,
...
You can use Excel to query Access, like you see in the link below.
http://translate.google.pl/translate?js=n&prev=_t&hl=pl&ie=UTF-8&layout=2&eotf=1&sl=pl&tl=en&u=http%3A%2F%2Fafin.net%2FKsiazkaSQLwExcelu%2FGraficznyEdytorZapytanSqlNaPrzykladzieMsQuery.htm
Also, consider using a parameter query to do the export from Access to Excel.
Dim dbs As DAO.Database
Dim qdfTemp As DAO.QueryDef
Dim strSQL As String, strQDF As String
Set dbs = CurrentDb
' Replace NameOfTableOrQuery with the real name of the table or query,
' replace NameOfForm with the real name of the form, and replace
' ADateControlOnForm and AnotherDateControlOnForm with the real names
' of the controls on that form
strSQL = "SELECT NameOfTableOrQuery.* FROM NameOfTableOrQuery " & _
"WHERE NameOfTableOrQuery.FieldName >= " & _
Format(Forms!NameOfForm!ADateControlOnForm.Value,"\#mm\/dd\/yyyy\#") & _
" And NameOfTableOrQuery.FieldName <=" & _
Format(Forms!NameOfForm!AnotherDateControlOnForm.Value,"\#mm\/dd\/yyyy\#") & "';"
strQDF = "_TempQuery_"
Set qdfTemp = dbs.CreateQueryDef(strQDF, strSQL)
qdfTemp.Close
Set qdfTemp = Nothing
' Replace C:\MyFolderName\MyFileName.xls with the real path and filename for the
' EXCEL file that is to contain the exported data
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, _
strQDF,"C:\MyFolderName\MyFileName.xls"
dbs.QueryDefs.Delete strQDF
dbs.Close
Set dbs = Nothing
Or...write data from a record set in Access to Excel.
Dim lngColumn As Long
Dim xlx As Object, xlw As Object, xls As Object, xlc As Object
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim blnEXCEL As Boolean, blnHeaderRow As Boolean
blnEXCEL = False
' Replace True with False if you do not want the first row of
' the worksheet to be a header row (the names of the fields
' from the recordset)
blnHeaderRow = True
' Establish an EXCEL application object
On Error Resume Next
Set xlx = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Set xlx = CreateObject("Excel.Application")
blnEXCEL = True
End If
Err.Clear
On Error GoTo 0
' Change True to False if you do not want the workbook to be
' visible when the code is running
xlx.Visible = True
' Replace C:\Filename.xls with the actual path and filename
' of the EXCEL file into which you will write the data
Set xlw = xlx.Workbooks.Open("C:\Filename.xls")
' Replace WorksheetName with the actual name of the worksheet
' in the EXCEL file
' (note that the worksheet must already be in the EXCEL file)
Set xls = xlw.Worksheets("WorksheetName")
' Replace A1 with the cell reference into which the first data value
' is to be written
Set xlc = xls.Range("A1") ' this is the first cell into which data go
Set dbs = CurrentDb()
' Replace QueryOrTableName with the real name of the table or query
' whose data are to be written into the worksheet
Set rst = dbs.OpenRecordset("QueryOrTableName", dbOpenDynaset, dbReadOnly)
If rst.EOF = False And rst.BOF = False Then
rst.MoveFirst
If blnHeaderRow = True Then
For lngColumn = 0 To rst.Fields.Count - 1
xlc.Offset(0, lngColumn).Value = rst.Fields(lngColumn).Name
Next lngColumn
Set xlc = xlc.Offset(1,0)
End If
' write data to worksheet
Do While rst.EOF = False
For lngColumn = 0 To rst.Fields.Count - 1
xlc.Offset(0, lngColumn).Value = rst.Fields(lngColumn).Value
Next lngColumn
rst.MoveNext
Set xlc = xlc.Offset(1,0)
Loop
End If
rst.Close
Set rst = Nothing
dbs.Close
Set dbs = Nothing
' Close the EXCEL file while saving the file, and clean up the EXCEL objects
Set xlc = Nothing
Set xls = Nothing
xlw.Close True ' close the EXCEL file and save the new data
Set xlw = Nothing
If blnEXCEL = True Then xlx.Quit
Set xlx = Nothing
Or, simply import the data from Access to Excel.
Sub ADOImportFromAccessTable(DBFullName As String, _
TableName As String, TargetRange As Range)
' Example: ADOImportFromAccessTable "C:\FolderName\DataBaseName.mdb", _
"TableName", Range("C1")
Dim cn As ADODB.Connection, rs As ADODB.Recordset, intColIndex As Integer
Set TargetRange = TargetRange.Cells(1, 1)
' open the database
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & _
DBFullName & ";"
Set rs = New ADODB.Recordset
With rs
' open the recordset
.Open TableName, cn, adOpenStatic, adLockOptimistic, adCmdTable
' all records
'.Open "SELECT * FROM " & TableName & _
" WHERE [FieldName] = 'MyCriteria'", cn, , , adCmdText
' filter records
RS2WS rs, TargetRange ' write data from the recordset to the worksheet
' ' optional approach for Excel 2000 or later (RS2WS is not necessary)
' For intColIndex = 0 To rs.Fields.Count - 1 ' the field names
' TargetRange.Offset(0, intColIndex).Value = rs.Fields(intColIndex).Name
' Next
' TargetRange.Offset(1, 0).CopyFromRecordset rs ' the recordset data
End With
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
Having the same error - linking Excel and Access.
After changing double quotes to single quotes the error "too few parameters. expected 1" was resolved. The sample of correct code.
AND all_clean.lastapp='Dial'