Programmaticaly rename a column in Access table after import from Excel - ms-access

Is there a way to programmatically rename the 1st column of a table in Access? Situation: after importing an Excel file into Access, I always need to rename the 1st column which always bears a different column name and manually rename it into F1, it would be much easier if this could be done programmaticaly. Is there an easy way to accomplish that using VBA?

Basically open an access application object then you're essentially renaming it as you would within Access vba.
Dim appAccess As Access.Application
Set appAccess = New Access.Application
With appAccess
.OpenCurrentDatabase "C:\...\DatabaseName.accdb"
.CurrentDb.TableDefs("Table1").Fields(1).Name = "F1"
.CloseCurrentDatabase
End With
Replace "Table1" with the name of your table and .Fields(1) refers to the first field, .Fields(2) refers to the second etc.
Note: Make sure you set your references to Access Object Library (found in Tools > References). It'll have a name similar to "Microsoft Access 12.0 Object Library"

Related

VBA Alternatives to workbook.open to pull data from a single cell

I wanted to find out if anyone can recommend an alternative way to query data in an excel file from an MS Access module.
If I have a data organised in a typical "Table" format e.g rows and columns with headers, then I have been connecting to the workbook using a DAO connection as below
Dim db as DAO.Database
Dim rsUsers as DAO.Recordset
Set db = OpenDatabase("C:\SaleLog.xls", False, True, "Excel 8.0;HDR=Yes;")
Set rsUsers = db.OpenRecordset("SELECT userID FROM [Sales$]")
I find this preferable to using
Dim xlApp As Excel.Application
Set xlApp = CreateObject("Excel.Application")
xlApp.Workbooks.Open "C:\SaleLog.xls", True, False
As it does not physically open an instance of an excel session and therefore runs a bit more quickly.
The only problem is when the data is not laid out like a table (e.g if I just wanted to get the value of 1 particular cell).
Does anyone know if there is a way to check the value of a cell in VBA without using Workbook.Open?
There may be a simpler way to achieve this but I have found 3 methods which can be used to pull data into MS Access from a single cell in a closed Excel workbook relatively efficiently (Many thanks to John Muggins for his help with this).
Firstly, the workbooks.open method can be used and will run more quickly if you set the read-only parameter to true (I'm unsure if this technically 'Opens' the workbook but it definitely seems to run more quickly while read-only). This requires you to set a reference to the Excel library.
Dim xlApp As Excel.Application
Dim src As Workbook
Set xlApp = CreateObject("Excel.Application")
Set src = xlApp.Workbooks.Open "C:\SaleLog.xls", True, True
You can then get data from specific cells using normal Excel VBA syntax like so
strUser = src.Worksheets("Sales").Range("B8")
src.Close False 'false doesn't save changes
Set src = Nothing
Another method is to use the DoCmd.Transferspreadsheet method to link or import a single cell, in this case you would need to set the HasFieldNames parameter to false as shown
path = "C:\SaleLog.xls"
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "tblTemp", path, False, "Sales!B8:B8"
This will create a table with a single field called F1. You can get the value stored in this table using a DLookup or a recordset (You may then wish to delete the temp table e.g. DoCmd.DeleteObject acTable, "tblTemp").
Lastly you can use a DAO connection as mentioned in the original question. You can specify a specific cell like so
Dim db as DAO.Database
Dim rsUsers as DAO.Recordset
Set db = OpenDatabase("C:\SaleLog.xls", False, True, "Excel 8.0;HDR=Yes;")
Set rsUsers = db.OpenRecordset("SELECT * FROM [Sales$B8:B8]")
Again this will create a recordset with a single field called F1. You can get the value of this field by using rsUsers.Fields("F1")
Each of the above methods can be (and usually are) used to pull data from an entire worksheet or range of cells but for the purpose of this question I wanted to show how they can be used to pull data from a single cell. I haven't tested them for efficiency although I doubt there is much difference in speed between them so probably best to go with the method that you find simplest.
If anyone knows how to tweak any of these methods to make them more efficient or has another approach altogether please feel free to comment or add a new answer :)

How do I create copies of CurrentDb using VBA

I need to create copies of the CurrentDB using VBA (approx. 12 copies). The copies need to be clones of the master database containing all the same forms, queries, etc. except only a limited dataset.
DoCmd.CopyDatabaseFile seems to be made for this, but only works if you are using it to copy the DB to an MS SQL Server. As MS states on their website:
Copies the database connected to the current project to a Microsoft
SQL Server database file for export.
docmd.TransferDatabase only exports the data itself, but not the structure, forms, etc.
Code I have found on the web and adapted doesn't work and throws an error on the .CopyFile line saying:
Run-time error 52: Bad file name or number
This is the code
Sub CopyDB()
Dim external_db As Object
Dim sDBsource As String
Dim sDBdest As String
sDBsource = "\\group\bsc\groups\L\BDTP\Compliance\ComplianceData\Compliance Group Reporting.accdb"
sDBdest = "\\group\bsc\groups\L\BDTP\Compliance\ComplianceData\Compliance Group Reporting_2.accdb"""
Set external_db = CreateObject("Scripting.FileSystemObject")
external_db.CopyFile sDBsource, sDBdest, True
Set external_db = Nothing
End Sub
How can I fix the above line? Alternatively is there a direct command in Access to create a copy? The "create backup" function would be tailor made for this, but I can not find it in VBA.
Looks like you have an extra quote in sDBdest accdb"""
And for database copy you can also use
FileCopy sDBsource, sDBdest
Instead of Scripting object

VB does not see Table after DoCmd.TransferDatabase using OpenRecordset

I am using Do.CMD.TransferDatabase to copy in two tables from a second access database. The TransferDatabase command runs, and I see the table in the Access list of tables, but the VB code doesn't see it.
I suspect I've messed up the internal list of tables because I see the tables (
myTable
myTable1
myTable2)
If I leave a table there on purpose, Access seems to "see" the table enough to not over-write it and Access writes a copy, but then the same code does not see the existing table to openit.
Code snippets (sanitized):
{
Dim ws As Workspace
Dim myDB As Database
Set myDB = DBEngine.Workspaces(0).Databases(0)
DoCmd.TransferDatabase acImport, "Microsoft Access", filename, acTable,"myTable", "myTable", False
Dim OriginalInformation As Recordset
Set OriginalInformation = myDB.TableDefs("myTable").OpenRecordset
The code stops on the last line and give the error that the item is not found in the collection.
How do I copy in a table and then look at the contents within the same VB function?
The answer is to use myDB.TableDerrs.Refresh between the import and using the
myDB.TableDefs("myTable").OpenRecordset

Preventing MSAccess linked tables from having a dbo_ prefix?

Is there a way to prevent MSAccess from concatenating 'dbo_' as the prefix to tables linked from a SQL Server db?
No. Microsoft Access' native naming convention process will force the name <schema>_<ObjectName> as your default table name. There are no controls or settings which will allow you to change that, except in code. It's rather complex and goes beyond the scope of this question, but if you do the linking in code (which I do) then you can store the TableAlias and create the linked table name that way.
You can write your table definition in the code to attach the table as below where
strTableAlias is your display name in Access
strTableName is your table name with schema <schema>.<ObjectName>.
Dim td As DAO.TableDef
set td = CurrentDb.CreateTableDef(strTableAlias, dbAttachSavePassword, _
strTableName, strConnectionStr)
CurrentDb.TableDefs.Append td
If you don't do the linking in code as mentioned by Johnny you can rename the links with this VBA code:
Public Sub Remove_DBO_Prefix()
Dim obj As AccessObject
Dim dbs As Object
Set dbs = Application.CurrentData
'Search for open AccessObject objects in AllTables collection.
For Each obj In dbs.AllTables
'If found, remove prefix
If Left(obj.Name, 4) = "dbo_" Then
DoCmd.Rename Mid(obj.Name, 5), acTable, obj.Name
End If
Next obj
End Sub
Courtesy https://www.microsoftaccessexpert.com/Microsoft-Access-Code-RemoveDBOPrefix.aspx
If you're doing this with the idea of using queries that you generate in Access outside of Access remember that Access creates it's own sql dialect so you may need to convert double quotes to single and # to ' among other things.

simple import form in Access

how to create an access form which has import excel file button. and after selecting excel file it automatically creates a table in the database with collumn headers as excel first row and data as excel other rows. if you think i am not putting any effort please give me suggestion or reference and ill do it on my own.
For versions of Access since 2003, you can use the File Dialog to allow the user to browse for the file they want, prior to that, you can use API calls. If this is overkill for you, you can have the user type in the file name and path, but you will have to check that it exists using code (Dir may suit).
It would be best to use TransferSpreadsheet method of the DoCmd object (available in any version of Access from, AFAIK, 1997 onward) to import the spreadsheet. This can be run as VBA (code) or a macro.
If we assume that you are able to create a form and wire up a button you have two issues:
The file open dialog.
Triggering the import.
For 1 you should be able to use the standard Microsoft file dialogs - my VB.OLD and Access are spectacularly rusty (no access 2007) but you can reference the appropriate COM assemblies from Access after which it becomes fairly easy.
2 is a bit more interesting - I beleive you can pretty much do this by menu selection from within access in which case, at least as a first step, you should be able to automate the same steps - pretty much anything you can do from a menu you can also do by calling the relevant command from VBA. The more complex solution would be to create VBA logic to create a linked table that links to the Excel file and then do a create table query and then drop the link.
In terms of effort, the form is something one would expect you to be able to do without much help - however automating something like an import from excel is not necessarily obvious.
An example using Access 2003 would be as follows for selecting a file:
Dim fDialog As Office.FileDialog
Dim strFile As String
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.InitialFileName = "C:\temp\*.xls"
.Filters.Clear
.Filters.Add "Excel file", "*.xls"
.Filters.Add "All Files", "*.*"
If .Show = True Then
strFile = .SelectedItems(1)
End If
End With
Debug.Print strFile
Note you would need to add a Reference to the Office 12 Object Library
To Import the file you can use the TransferSpreadsheet Function of the DoCmd Object. For E.g.
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "ExcelImport", strFile, True
The Access table called ExcelImport would have to already exist in the database.