Merge 2 fields and insert into table - ms-access

hi i am trying to insert value into my output table 
in my Input table have 
profit  extra 
10         20 
when i insert into my output table it should get concatenated as 
cost 
1020 
sub test()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
db. execut "Insert into OUTPUT_TBL (DESCRIPTION,COST,DEBIT,CREDIT) " & _
" SELECT INPUT.DESCRIPTION,((INPUT.PROFIT)+(INPUT.EXTRA)) AS COST," & _
" IIF(EXTERNAL.SOLUTION='DEBIT',(AMOUNT),0) as DEBIT, " & _
" IIF(EXTERNAL.SOLUTION='CREDIT',(AMOUNT),0) AS CREDIT " & _
" FROM INPUT , EXTERNAL"
db.close
end test
when i try to run it i am getting error as  run time error 3075

Couple issues - noticed a typo, it should be db.execute "" not db.execut
Also, for string concatenation use & in Access SQL. 3075 means you used a bad operator.
Another thing, You may also need to add a JOIN to the SQL.
For example, to get you on the right track:
db.execute "Insert into OUTPUT_TBL (DESCRIPTION,COST,DEBIT,CREDIT) SELECT INPUT.DESCRIPTION,((INPUT.PROFIT)&""&(INPUT.EXTRA)) AS COST,IIF(EXTERNAL.SOLUTION='DEBIT',(AMOUNT),0) as DEBIT, IIF(EXTERNAL.SOLUTION='CREDIT',(AMOUNT),0) AS CREDIT from INPUT JOIN EXTERNAL ON INPUT.KEY=EXTERNAL.KEY"

Related

Selecting fields command gives error

I want to sort multiple fields in an access data base but being a newbie I took reference from MSDN program and first trying to sort on a single field. I'm getting error From syntax wrong on the following lines.
Set rst = dbs.OpenRecordset("SELECT ACT_CD, " _
& "SNO FROM Banks_Trnx_2018-2019" _
& "ORDER BY SNO DESC;")
The full program as follows.
Option Compare Database
Sub OrderByX()
Dim dbs As Database, rst As Recordset
' Modify this line to include the path to Northwind
' on your computer.
Set dbs = OpenDatabase("E:\FY_2018-2019\Banks\Banks_Trnx_2018-2019.accdb")
' Select the last name and first name values from
' the Employees table, and sort them in descending
' order.
Set rst = dbs.OpenRecordset("SELECT ACT_CD, " _
& "SNO FROM Banks_Trnx_2018-2019" _
& "ORDER BY SNO DESC;")
' Populate the Recordset.
rst.MoveLast
' Call EnumFields to print recordset contents.
' EnumFields rst, 12
dbs.Close
End Sub
I am clueless. Please help. As already mentioned I would like to sort on three fields (multiple fields) comprising of text and numerical fields which presently I can easily do by setting columns in proper order and selecting them together while sorting. Since it is a repetitive operation I am trying to develop VBA procedure for the same. Any pointer in the right direction shall be highly appreciated.
You should set your sql to a variable first - makes it a lot easier to troubleshoot - you'd be able to see you've left out some spaces between keywords and table
Set rst = dbs.OpenRecordset("SELECT ACT_CD, " _
& "SNO FROM [Banks_Trnx_2018-2019]" _
& "ORDER BY SNO DESC;")
Should be (with added brackets for table as suggested by #skkakkar)
Set rst = dbs.OpenRecordset("SELECT ACT_CD, " _
& "SNO FROM [Banks_Trnx_2018-2019] " _
& "ORDER BY SNO DESC;")
You have a - in your table name. I didn't even think that was allowed, either put brackets around your table name or change the table name.
"SELECT ACT_CD, " _
& "SNO FROM [Banks_Trnx_2018-2019]" _
& "ORDER BY SNO DESC;"
or
"SELECT ACT_CD, " _
& "SNO FROM [Banks_Trnx_2018_2019] " _
& "ORDER BY SNO DESC;"
and change table name.

Reading data types from a table and run Alter table statement without locking table

I am using the below function to determine the field data types from whichever table is given in the function parameter. Basically the function reads the data type from the table and compares it to what it should be based on the "FieldDataTypes" table. If it doesn't match, then I would like to run an Alter table SQL statement as shown below. However I am realizing that once I open the recordset I am unable to alter the table. When I run the Sub/Function below I get the error:
The database could not lock table "TEST TABLE" because it is already in use by another person or process. 3211.
How can I get around this so that I can loop through the fields and still alter the data types as necessary?
Thanks,
Charlie
Sub TestReFormat()
FncFormatFields ("TEST TABLE")
End Sub
Public Function FncFormatFields(strTableName As String)
Dim rst As DAO.Recordset
Dim fld As Field
Dim strFieldName As String
Dim strSQL As String
Dim intDataType As Integer
Dim intDataTypeCheck As Integer
On Error GoTo FormatFieldsErr:
rstSQL = "SELECT * FROM [" & strTableName & "]"
Set rst = CurrentDb.OpenRecordset(strTableName)
For Each fld In rst.Fields
strFieldName = fld.Name
intDataType = fld.Type
Debug.Print strFieldName & " " & intDataType
intDataTypeCheck = DLookup("DataTypeInt", "FieldDataTypes", "[FieldName] = '" & strFieldName & "'")
Debug.Print intDataTypeCheck
If intDataTypeCheck <> intDataType Then
strSQL = "ALTER TABLE [" & strTableName & "] ALTER COLUMN [" & strFieldName & "] " & intDataTypeCheck & ""
DoCmd.RunSQL (strSQL)
End If
Continue2428:
Next fld
Exit Function
FormatFieldsErr:
If Err.Number = 2428 Then
Resume Continue2428
Else
MsgBox Err.Description & " " & Err.Number
End If
End Function
Break your function into two parts:
A Function that examines the table returns a SQL array of ALTER TABLE statements
A Function that executes the SQL array
The query that locks the table in 1) will be closed, allowing you to alter it in 2) without error.
PS: Use rstSQL = "SELECT TOP 1 * FROM [" & strTableName & "]" so you don't waste resources returning multiple rows.
You can update data in a table without locking. In fact FEW know that the Access database engine JET/ACE can even update columns in records that are currently in use and dirty by other users (the update has to be specific to the one column - this is possible in some cases).
However, to modify a table structure and data type? You will require full exclusive rights and other users cannot have the table open, and you need full lock rights to the whole database.
Since in this case the data is of no interest, only the table structure, you can use a TableDef object to get the table structure; this will get around the lock:
Public Function FncFormatFields(tablename As String)
Dim dbs As Database, tdf As TableDef, fld As Field
On Error GoTo FormatFieldsErr:
Set dbs = CurrentDb
Set tdf = dbs.TableDefs(tablename)
For Each fld In tdf.Fields
Dim fieldname As String
fieldname = fld.Name
Dim datatype As Integer
datatype = fld.Type
Debug.Print fieldname & " " & datatype
Dim finalDatatype As Integer
finalDatatype = DLookup("DataTypeInt", "FieldDataTypes", "[FieldName] = '" & fieldname & "'")
Debug.Print finalDatatype
If datatype <> finalDatatype Then DoCmd.RunSQL "ALTER TABLE [" & tablename & "] ALTER COLUMN [" & fieldname & "] " & finalDatatype & ""
Next
Continue2428:
Next fld
Exit Function
FormatFieldsErr:
If Err.Number = 2428 Then Resume Continue2428
MsgBox Err.Description & " " & Err.Number
End Function
Even if the data is of interest, TableDef has an OpenRecordset method that returns the data in the table.
It might also be possible to use a snapshot-type recordset, which doesn't have an open connection to the database, and therefore shouldn't be affected by the lock. (I didn't test this.)
Note: I've only tested this with an .accdb; if this works as well with an .mdb that would be good to know.

Creating a Change Log using VBA Insert Into

I am trying to create a change log anytime a field is changed. I want it to record the property, the manager, and the date it was changed. I looked up INSERT INTO and followed the directions and came up with this code, but I get an error.
Private Sub Manager_AfterUpdate()
INSERT INTO tbl_ManagerChangeLog (Property, NewMan, [Date Change])
VALUES (Me.ID, Me.Manager, DATE())
End Sub
There error I get reads, "Compile Error: Expected: End of statement"
Any help is appreciated.
Here is final code that worked for me. Thank you for all of the help.
Private Sub Manager_Change()
Dim dbs As Database, PropID As Integer, ManNam As String, ChangeDate As Date
Set dbs = CurrentDb()
PropID = Me.ID
ManNam = Me.Manager
ChangeDate = Date
dbs.Execute " INSERT INTO tbl_ManagerChangeLog " & "(Property, NewMan, DateChange)VALUES " & "(" & PropID & ", " & ManNam & ", #" & ChangeDate & "#);"
End Sub
You must run a SQL query using Execute funcion from currentDb object, and build the query values concatenating values:
Private Sub Manager_AfterUpdate()
Dim sSQL as String
sSQL = "INSERT INTO tbl_ManagerChangeLog (Property, NewMan, [Date Change]) " & _
"VALUES (" & Me.ID & ",'" & Me.Manager "'," & _
"#" & format(DATE(),"YYYY-MM-DD HH:NN:SS") & "#)"
currentDB.Execute sSQL
End Sub
Try the following VBA to run a sql query.
Private Sub Manager_AfterUpdate()
Dim strSql As String , Db As dao.Database
strSql = "INSERT INTO tbl_ManagerChangeLog (Property, NewMan, [Date Change]) VALUES (Me.ID, Me.Manager, DATE());"
'Use Current Database
Set Db = CurrentDb()
'Run the SQL Query
Db.Execute strSql
End Sub

How to sort an Access DB Table to show in right order when opening via VBA?

I already have a VBA script that edits this, that, and the other and even opens the table at the end of the script. The only problem is that I want the data I am viewing to be sorted by columnA, and then by columnB.
How do I do that via VBA in Access 2010?
If you just want to see the record set then you could do something like the following:
Dim qdef As Dao.QueryDef
Set qdef = CurrentDb.CreateQueryDef("MyQuery", "SELECT * " & _
"FROM TableName " & _
"ORDER BY columnA, columnB")
DoCmd.OpenQuery "MyQuery"
Then once you are done doing whatever it is you want to do with it you could execute the following to remove the query:
On Error Resume Next
DoCmd.DeleteObject acQuery, "MyQuery"
Or you could do the following:
Dim RSData as DAO.Recordset
Set RSData = CurrentDB.OpenRecordSet("SELECT * " & _
"FROM TableName " & _
"ORDER BY columnA, columnB")
If (RSData.RecordCount > 0) Then
RSData.MoveFirst
Do While RSData.EOF <> True
'HERE YOU CAN WORK WITH EACH FIELD OF THE RECORD INDIVIDUALLY USING
RSData.Fields("columnA").value
RSData.MoveNext
Loop
End If
Then once you are done doing whatever it is you want to do with it you could execute the following:
RSData.Close
Set RSData = Nothing

Possible to join two recordsets using VBA/ADO?

The goal is to join an Access table with matching data from a SQL Server table. I would do this using linked tables in Access but I'm running into Access' BigInt problem (I would have a view created to cast BigInt as Int but that isn't an option right now).
So I've been trying to create two recordsets and join them in VBA/ADO. The left side of the join would be the Access table with Season and WeekNum and the right side of the join would be the SQL Server table with Season and Weeknum and other data. This works fine until I try to create a third recordset that is the result of the join (in this example, I haven't tried to do a join, just the first part of the join by selecting from the Access recordset). I'm getting a Type Mismatch error on the line when I do Set ObjRecordset3 = "SELECT * FROM " & Access_Recordset '.
Is it even possible to join two recordsets? If so, how is this done?
Function Join()
Dim SQL_Server_Connection As ADODB.Connection
Set SQL_Server_Connection = New ADODB.Connection
Dim SQL_Server_Query As String
Dim SQL_Server_Recordset As New ADODB.Recordset
Dim Access_Recordset As New ADODB.Recordset
Dim ObjConnection As ADODB.Connection
Set ObjConnection = CreateObject("ADODB.Connection")
Dim ObjRecordset3 As New ADODB.Recordset
' Get data from Bump Table 3:
Access_Recordset.Open "SELECT * FROM [Bump Table 3]", CurrentProject.Connection
' Open connection to SQL Server:
SQL_Server_Connection_String = "DSN=MySQLServer"
SQL_Server_Connection.Open SQL_Server_Connection_String
' Define the SQL Server query:
SQL_Server_Query = "SELECT Season, WeekNum FROM TE"
' Populate the SQL_Server_Recordset:
SQL_Server_Recordset.Open SQL_Server_Query, SQL_Server_Connection, adOpenDynamic, adLockOptimistic
'Join Access_Recordset (Table: Bump Table 3) to SQL_Server_Recordset (Table: TE)
Set ObjRecordset3 = "SELECT * FROM " & Access_Recordset ' Type Mismatch error on this line
Access_Recordset.Close
Set Access_Recordset = Nothing
SQL_Server_Recordset.Close
Set SQL_Server_Recordset = Nothing
SQL_Server_Connection.Close
End Function
* UPDATE *
I figured out how to get to my ultimate goal which was to get data about a list of account numbers in an Access table from SQL Server based on the account number field which is common to both tables. Realizing that I can create a persistent temp table on SQL Server, I used a combination of DAO and ADO to get the values from the Access table and create a temp table. All I had to do then is run the pass-through query which references the temp table. The only odd thing (which is not a problem at this point) is if I create the temp table and run the pass-through query in VBA, this setup works. But if I create the temp table in VBA and double-click on the pass-through query, Access says that the temp table can't be found. Anyway, here's the code:
Public Sub Insert_Into_Access_From_ADO_Recordset_Using_PTQ_Simpler()
Dim dbs As DAO.Database
Set dbs = CurrentDb()
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
Dim rst As ADODB.Recordset
'Open SQL Server
Dim str_cnn As String
str_cnn = "MYDSN"
cnn.Open str_cnn
' Drop the temp table:
Dim str_SQL_Drop_Temp_Table As String
str_SQL_Drop_Temp_Table = "IF OBJECT_ID('tempdb..##BumpData','U') IS NOT NULL "
str_SQL_Drop_Temp_Table = str_SQL_Drop_Temp_Table & " DROP TABLE ##BumpData "
cnn.Execute str_SQL_Drop_Temp_Table
' Create the temp table:
Dim str_SQL_Create_Temp_Table As String
str_SQL_Create_Temp_Table = " CREATE TABLE ##BumpData "
str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & "("
str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & " ID INT "
str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & " , AccountNumber VARCHAR(Max)"
str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & ")"
cnn.Execute str_SQL_Create_Temp_Table
' Insert values from the Access table into the temp table
' by looping through the Access table as a recordset:
Dim rst_DAO As DAO.Recordset
Set rst_DAO = dbs.OpenRecordset("Bump Data")
Dim str_SQL_Insert As String
rst_DAO.MoveFirst
With rst_DAO
Do While Not rst_DAO.EOF
'str_Loan_Number_List = str_Loan_Number_List & "'" & Trim(rst![Loan Number]) & "'" & ","
str_SQL_Insert = " INSERT INTO ##BumpData VALUES (" & rst_DAO![ID] & ",'" & Trim(rst_DAO![Loan Number]) & "') "
cnn.Execute str_SQL_Insert
.MoveNext
Loop
End With
' Run the pass-thru query which joins to the temp table:
DoCmd.SetWarnings False
DoCmd.RunSQL "SELECT * INTO [Bump Results] FROM [Bump PTQ]"
DoCmd.SetWarnings True
End Sub
You reported this line triggers the error:
Set ObjRecordset3 = "SELECT * FROM " & Access_Recordset
The right side of the = sign attempts to concatenate a string with an ADODB.Recordset object. That is probably the immediate cause of the compile error. However, that's not the only problem with that line. Set <recordset object> = "any string value" will not work. And finally, Access SQL does not support FROM <recordset object> for any type of recordset object (ADO or DAO).
I think you should look for a simpler approach. In following query, dbo_BigIntTable is an ODBC link to a SQL Server table. It includes a field, bigint_fld, whose SQL Server data type is BigInt. However, Access sees that field as Text type. Therefore I can join it with the string equivalent of a Long Integer field (tblFoo.id).
SELECT tblFoo.id, dbo_BigIntTable.bigint_fld
FROM
tblFoo
INNER JOIN dbo_BigIntTable
ON CStr(tblFoo.id) = dbo_BigIntTable.bigint_fld;
The Access query designer complained it can't display that join in Design View, but I was able create the join from SQL View and it worked fine.