I have an Access data file that contains tables.
that access file linked with other access files (the executive file that contains the forms and the operations).
I added the following code inside the tables file inside a module:
Public Function MyFun()
On Error Resume Next
Dim xCounter As Integer
xCounter = DLookup("xcounter", "tblfs1", "[xid] = 1")
xCounter = xCounter + 1
Dim xSql As String
xSql = "update tblfs1 set [xcounter] = " & xCounter & " where [xid] = 1"
CurrentDb.Execute xSql
If xCounter >= 300 Then
DoCmd.Rename "Tbl_FS", acTable, "FS"
DoCmd.Rename "Tbl_All", acTable, "All"
DoCmd.Rename "Tbl_Customers", acTable, "Customers"
DoCmd.Rename "Tbl_Rates", acTable, "Rates"
DoCmd.Rename "Tbl_Temp", acTable, "Temp"
DoCmd.Rename "Tbl_Users", acTable, "Users"
End If
End Function
and I created a macro to run that function in a startup (RunCode) and I named the macro (AutoExec).
my problem is when I open (the access tables file) by clicking, the code works but when I use the executive file that linked with (the access tables file), the code doesn't work!!
how to make the code run when I work on the executive file without open (the access tables file) and without doing that from the executive file.
That is not possible - the backend (data) file is "dead" in this regard.
The closest you can get some action in the backend, is to create data macros.
Related
I have a CSV file that needs to be imported into Access using a linked table. However, this exceeds the 255 column limit.
This was solved by using some VBA with a button. On press the data is loaded into a linked table. I now need to add some extra code under this to create a copy of the linked table and save it as a local table.
This needs to be done on one press of the button. Below is what i have got currently.
Private Sub cmdImportExcel_Click()
'DoCmd.TransferSpreadsheet acImport, , "tblRawTestData", "C:\Users\jacklythgoe\documents\Access\Test Analyzer\data\TestResultsCopy.csv", True, Range:="TestResultsCopy!A:C"
' Requires reference to Microsoft Office 11.0 Object Library.
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Dim testResultsWorkSheet As Worksheet, strFile As String
' Set up the File Dialog.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
' Allow user to make multiple selections in dialog box
.AllowMultiSelect = True
' Set the title of the dialog box.
.Title = "Please select the font(s)."
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Text File", "*.csv"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
'Loop through each file selected and add it to our list box.
For Each varFile In .SelectedItems
Next
End If
End With
DoCmd.TransferText TransferType:=acLinkDelim, tableName:="tblImport", FileName:="C:\Users\jacklythgoe\Documents\Access\Test Analyzer\data\TestResultsCopy.csv", HasFieldNames:=False
'DoCmd.TransferText TransferType:=acLinkDelim, TableName:="tblImport", FileName:="C:\MyData.csv", HasFieldNames:=True
End Sub
You could try something like this:
DoCmd.CopyObject , "tblImport_Copy", acTable, "tblImport"
DoCmd.SelectObject acTable, "tblImport_Copy", True
DoCmd.RunCommand acCmdConvertLinkedTableToLocal
Makes a copy of the linked table, 2. Selects the copy, 3. Converts into a lokal table
Not sure if you have all the details in your question.
If you already have solved the issue with the linking the CSV file as a table, then just build a make table query that selects the fields from the linked csv file and run the query from your button click event. It creates a local table for you
Something like this would work:
Dim dbs As DAO.Database
Dim lngRowsAffected As Long
Dim lngRowsDeleted As Long
Set db = CurrentDb
' Execute runs both saved queries and SQL strings
db.Execute <mymaketablequery>, dbFailOnError
' Get the number of rows inserted.
lngRowsAffected = db.RecordsAffected
Msgbox "Inserted " & lngRowsAffected & " new records"
I need to import tables from various databases on a monthly basis. Once the tables are imported, the databases are archived and not looked at again.
I have the following VBA code which works fine when a DB is not password protected:
Private Sub ImportTheData(ByVal dbImport As String)
DoCmd.SetWarnings False 'Turn OFF display alerts
'Import the full activity & comments table from the Import DB to a temporary table
DoCmd.TransferDatabase acImport, "Microsoft Access", dbImport, acTable, "tbl_Activity", "tbl_TempActivity", True
DoCmd.TransferDatabase acImport, "Microsoft Access", dbImport, acTable, "tbl_Comments", "tbl_TempComments", True
'code continues ...
The last parameter (storelogin) is set to true, but there seems to be no way to programmatically set those login parameters (password).
When I run the code, the user is prompted to enter the password (despite the SetWarnings = False). As I'm importing dozens of files each time this is not a viable solution.
Is there a way to programatically import tables using DoCmd.TransferDatabase when a file is password protected and if so how?
Open the database with DAO, supplying the password, then you can import the tables.
Public Sub ImportEncr()
Const dbImport = "D:\DbEncr.accdb"
Const sPassword = "foobar"
Dim DB As DAO.Database
Set DB = DBEngine.OpenDatabase(Name:=dbImport, Options:=False, ReadOnly:=False, Connect:=";PWD=" & sPassword)
DoCmd.TransferDatabase acImport, "Microsoft Access", dbImport, acTable, "tblEncr", "tblEncr", False
DB.Close
Set DB = Nothing
End Sub
StoreLogin applies to linking tables from ODBC databases.
You can use SQL and build a SQL statement and .RunSQL that I believe.
An example SQL would be
SELECT * into tblIMPORT
FROM xyz IN '' '; database=C:\Workspace\Database1.accdb;PWD=test';
Hope this helps.
I'm preparing a Visual Basic for Applications (VBA) script in a .accdb file. (I don't have any requirement to do so, I just opened what I have: the Microsoft Access 2016 application, and opened its Visual Basic editor and started coding.)
Goal: The script is meant to move a table from an .MDB file to another .MDB file.
I couldn't find a way to do it directly, so I did that in 2 steps.
What the script does:
1st step: Transfers, or copies, a given table (stored in variable named srcTableName)
from a local .MDB file (whose path+name+extension is in variable
srcPath) into my script's file (an .accdb file called Script.accdb
and stored in the same folder as the source .MDB file)
2nd step:
Transfers, or copies, the table newly copied (named
intermediaryTableName) from the script's current file to some .MDB
file which is in some Drive (path+name+extension in destPath)
I couldn't merge the 2 steps into one (that is: to copy the table directly from srcTableName to destPath)
So, this is it:
table in .MDB file, in local -> table in current file (local, contains script, extension .accdb) -> table in .MDB file, in some other drive
It works.
My problem is: each time I run my script, the script's file (which I sometimes call also. the "current file", or the .accdb one) grows 30MB more. This is unnaceptable. (I don't even save the file. Why does the file need to enlarge like this?)
I detected the problem comes from the command: DoCmd.TransferDatabase. This command seems to increase the file size a lot.
After running the script: the script's file (a 500 KB file) has become a 27 776 KB one.
Followings runs:
27 776KB -> 54 912 KB (difference before and after run: 27 136KB)
54 912 KB -> 82 048 KB (difference: 27 135KB)
I have no idea what this command writes. I couldn't find any information on this on the documentation or in pretty much any google result.
When I delete the table copied in the current file (the script's file) the size of the file almost does not shrink. So DoCmd.TransferDatabase seems to write something else (some metadata I didn't find, maybe)
I wish I could do the 1st step in some other way. Looking for workarounds:
I was not able to configure programatically an ADODB.Connection in
order for it to import the table from the old .MDB file (the
srcPath one)
DoCmd.CopyObject is a function that seems to please me, since it
seems to create no "rubbish"/enlarge the file mysteriously. The
available MSDN microsof's documentation provides no further details about the effects of applying this function or the arguments' formats, but it seems to be
prepared to manipulate only objects that belong to the current file,
and not an external file. I want to try to set its argument
SourceObjectName to an external (that is: in another drive), detailed path, but it seems to only
accept the table's (short) name. I tried to look some long-path name for access objects like tables, but also: the fields of the structure
that contains the table I want to import
(srcDB.TableDefs(srcTableName).Connect) seem to be empty for this
table, and the "name" attribute only displays the name of the table I
already know ("sh5") and can see as a user of Access, which seems to be of no use to
specify the path to it from an external file.
I was able to copy tables, or to export+import tables, from a "normal" access file (.accdb extension) to another .accdb file. As
such, I tried to convert a .MDB file to .accdb, but was not successful. I got a
""The project cannot be converted into this format. The project can
only be converted to Access 2000 or newer format." error message while using a
Microsoft.Office.Interop.Access.Application.ConvertAccessProject
function.
I also tried to "compact and repair" the current/the script's file, setting the "Auto compact" option of the Access Application to True, but it didn't make much difference:
Next run: file size before this block of code: 82 048 KB
file size after that block of code: 82 048 KB
file size after script: 109 056 KB (difference before and after run: 27 008KB)
After all this:
Does someone have an idea to prevent DoCmd.TransferDatabase from enlarging the file like this?
Or another workaround to copy the table from one file to another?
Here is my code, should it provide any more useful details:
Option Explicit
Option Compare Database
'Copies one given table from the <srcPath> to a file <destPath> (This file serves as an intermediary. it contains the script and copies the table into a format I can manipulate and send to the destiny file.)
Sub CopyTableFromOneFileToTheOther()
Dim srcFileTitle As String 'file name (with no extension nor path) from which we want to copy the table
Dim srcTableName As String 'name of the table we want to move
Dim srcPath As String 'includes srcTableName, plus: old .MDB extension and path
Dim srcDB As DAO.Database
Dim destFileTitle As String 'file name (with no extension nor path) into which we want to move the table
Dim destPath As String 'includes destFileTitle, plus: extension and path
Dim destDB As DAO.Database 'file (access database) to which we want to copy the table to
Dim destTableName As String
Dim currentFilePath 'detailed path (included path, title, extension)
Dim intermediaryTableName 'name of the table held temporarily in the current file (the script's file)
Dim accessApp As Access.Application
Dim testTableName As String
'Initializations
srcFileTitle = "Actifs" 'This file is expected to be on local (in the same folder you put this file with script).
srcTableName = "sh5" 'table we want to copy / move
destFileTitle = "Actifs_toUpdate" 'title of the file to which we want to move the table. This file is expected to be somewhere remote. please update destPath as well.
srcPath = CurrentProject.Path & "\" & srcFileTitle & ".MDB"
destTableName = srcTableName & "_copy"
destPath = "G:\Users\b\bernarcl\Documents" & "\" & destFileTitle & ".MDB"
currentFilePath = CurrentProject.Path & "\" & CurrentProject.Name
intermediaryTableName = srcTableName
Debug.Print "srcPath = " & srcPath & " | srcTableName= " & srcTableName
DebugPrint "currentFilePath = " & currentFilePath & "|" & "intermediaryTableName = " & intermediaryTableName
Debug.Print "destPath = " & destPath & " | destTableName = " & destTableName & vbNewLine
'Compact and repair current file, to see if enabling this prevents the file to grow 30MB
Set accessApp = New Access.Application
With accessApp
.OpenCurrentDatabase CurrentProject.Path & "\" & CurrentProject.Name
.SetOption "Auto compact", True
.CloseCurrentDatabase
.Quit
End With
'Delete table form current file, if it already exists. Otherwise the file will store more and more of these, becoming too heavy.
If TableExists(srcTableName, CurrentDb) Then
Set srcDB = DBEngine.Workspaces(0).OpenDatabase(srcPath)
'testTableName = srcDB.TableDefs(srcTableName).Connect
'Debug.Print "testTableName= " & testTableName
'Dim t As TableDefs
' Set t = srcDB.TableDefs
Debug.Print "Table " & srcTableName & " exists in file " & CurrentDb.Name & ". Let's delete it, and import the most updated one afterwards."
DoCmd.DeleteObject acTable, srcTableName
End If 'table exists
'Importing table of old file, in order to have it in a macro-compatible format
'PROBLEM of memory spending here. The file grows 30MB each time it runs this instruction.
'I didn't find equivalent and successful ways to transfer database table from one file to another: tried DoCmd.CopyObject, configuring ADODB.Connection's parameters,
DoCmd.TransferDatabase TransferType:=acImport, DatabaseType:="Microsoft Access", _
DatabaseName:=srcPath, ObjectType:=acTable, _
Source:=srcTableName, Destination:=srcTableName, _
StoreLogin:=True
If (fileExists(destPath)) Then
Debug.Print "File " & destFileTitle & " already exists."
Set destDB = DBEngine.Workspaces(0).OpenDatabase(destPath)
If TableExists(destTableName, destDB) Then
Debug.Print "Table " & destTableName & " exists in file " & destFileTitle & ". Let's update it."
'DoCmd.DeleteObject acTable, destTableName
DoCmd.CopyObject destPath, destTableName, acTable, srcTableName 'This also warns the user and substitues the previous/current table with the to-be-copied one
Else
Debug.Print "Table " & destTableName & " does NOT exist in file " & destFileTitle & ". Let's create it."
DoCmd.CopyObject destPath, destTableName, acTable, srcTableName 'creates table in destPath for the first time
End If 'table exists
Else
'create new file, before copying
Debug.Print "file named= " & destFileTitle & " does not exist, then let's create it."
Set accessApp = New Access.Application
Set destDB = accessApp.DBEngine.CreateDatabase(Name:=destPath, Locale:=DB_LANG_GENERAL)
End If 'fileExists(destPath)
DoCmd.DeleteObject acTable, srcTableName 'deletes from current file. We don't need it here, anymore.
destDB.Close
End Sub
'Auxiliary functions
Private Function fileExists(ByVal strFile As String, Optional bFindFolders As Boolean) As Boolean
Dim lngAttributes As Long
lngAttributes = (vbReadOnly Or vbHidden Or vbSystem) 'Include read-only files, hidden files, system files.
If bFindFolders Then
lngAttributes = (lngAttributes Or vbDirectory) 'Include folders as well.
Else
Do While Right$(strFile, 1) = "\"
strFile = Left$(strFile, Len(strFile) - 1)
Loop
End If
On Error Resume Next
fileExists = (Len(Dir(strFile, lngAttributes)) > 0) 'If Dir() returns something, the file exists.
End Function
Private Function TableExists(ByVal srcTableName As String, db As DAO.Database) As Boolean
On Error Resume Next
Dim tdef As TableDef
db.TableDefs.Refresh
For Each tdef In db.TableDefs
If tdef.Name = srcTableName Then
TableExists = True
Exit For
End If
Next tdef
End Function
You can use an SQL query to move a table from one database to another.
Execute this on the source DB:
SELECT * INTO MyTable IN 'C:\MyOtherDb.MDB'
FROM MyTable;
I have used this a lot, and have never had these size problems.
You can also use SQL to pull in tables to the current Db.
SELECT * INTO MyTable FROM [C:\MySourceDb.mdb].MyTable;
Obviously, you can use VBA to execute this query.
Note that some meta-information (indexes other than the primary one, lookup fields) might be lost.
I'm trying to import a CSV file that is created from a web form I developed. When the form submits it creates a record in my CSV with a multitude of customer information.
As per requirements I needed to put it into a CSV, and then separately have it import into an Access database for others to use (Two steps required for server security).
The way I'm trying to do it is with a simple form with a button on it inside Access, that simply says Import, that will pull an update of the CSV whenever the user needs it.
My error is confusing me as it's stating
"Field 'F1' doesn't exist in destination table 'Applications' "
I do not have a field in my CSV labeled F1, or even any record that contains 'F1', and there is no field named F1 in my access table Applications (obviously).
Here is my VB module code from Access
Option Compare Database
Sub ImportingCSV()
Function Import()
On Error GoTo Macro1_Err
DoCmd.TransferText acImportDelim, "", "Applications", "C:\Users\ALee\Documents\formTesting22.csv", False, ""
Import:
Exit Function
Macro1_Err:
MsgBox Error$
Resume Macro1_Exit
End Function
And here is my CSV file format (spaced out for your readability)
OPUCN#WVQNAJT4PD,
2017.05.03,
test,
v,
90545452929,
4062033985,
No,
VM#TEST.VMTEST,
10003937683827,
test,
test,
689 395 3967,
2048 2983999,
No,rle#don.ca,
111 e Streeth south,
12,
Temporary,
Commercial,
100,
200,
300,
208/120V,
Three-Phase,
Underground (UG),
Ganged Position*,
23,
"dsbsdhfbslhfbshfbsdhlfbgshdfgsfslfgljshgfljshgfljshgflsj"
The error is telling me that the field for the second phone number ("4062033985" in the CSV) doesn't have a field in the table Applications, but it does! "F1" in the CSV is Customer Mobile. When I import manually through Access's import wizard this works fine.
Hopefully someone can point me in the right direction, not familiar with VB script or macros in access.
Don't import the file.
Link the csv file as a table. Then create a query to read and convert (purify) the data.
Use this query as source for further processing of the date like appending data to other tables.
a CSV file is a spreadsheet... try...
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml,[YourDestinationTable],"C:\YourFileDirectoryPath, filename, and extension",true,[Spreadsheet name if multiple sheet names]
There are all kinds of ways to do this sort of thing. This is certainly the simplest method.
Private Sub Command0_Click()
DoCmd.TransferText acImportDelim, "", "Book1", "C:\your_path_here\Book1.csv", True, ""
End Sub
Let's say you want to import several CSV files, all of the same type, into the same table. Just run the script below.
Option Compare Database
Option Explicit
Private Sub Command0_Click()
DoImport
End Sub
Function DoImport()
Dim strPathFile As String
Dim strFile As String
Dim strPath As String
Dim strTable As String
Dim blnHasFieldNames As Boolean
' Change this next line to True if the first row in CSV worksheet
' has field names
blnHasFieldNames = True
' Replace C:\Documents\ with the real path to the folder that
' contains the CSV files
strPath = "C:\your_path_here\"
' Replace tablename with the real name of the table into which
' the data are to be imported
strFile = Dir(strPath & "*.csv")
Do While Len(strFile) > 0
strTable = Left(strFile, Len(strFile) - 4)
strPathFile = strPath & strFile
DoCmd.TransferText acImportDelim, , strTable, strPathFile, blnHasFieldNames
' Uncomment out the next code step if you want to delete the
' EXCEL file after it's been imported
' Kill strPathFile
strFile = Dir()
Loop
End Function
You can do all kinds of other thins too; navigate to a file using the msoFileDialogFilePicker; you can loop through record sets and load them, one by one, into your table. As Gustav suggested, you can link to your file (staging) and write records into a table (production). You should probably try all of these methods, and play around with
I created code for importing data from Excel into desired table, via TransferSheet and builded Query method. I'm also trying to resolve all errors that User could do when Importing data into db (wrong file format, appending 0 rows,field names not same as in DB etc.), but cannot get rid of Error 3059 "was unable to append all data to table" - It occurs when you try to Import some invalid data. I want a custom Msgbox for this error, and stop executing my Query. Here's my code - in short :
Private Sub CmdImport_Click()
Dim SQL As String
Dim dbs As DAO.Database
Set dbs = CurrentDb
On Error GoTo ERR1
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "NEWTABLE", "<Imported file>", True
SQL = " INSERT INTO MyTable (Field1)" & _
" SELECT DISTINCT" & _
" FROM NEWTABLE"
DoCmd.SetWarnings False
dbs.Execute SQL
DoCmd.RunSQL "DELETE * FROM NEWTABLE"
DoCmd.SetWarnings True
ERR1:
If Err.Number = 3059 Then
MsgBox "This file doesn't have proper data to import. Import canceled !"
Exit Sub
End If
End Sub
This code pops-up custom Msgbox after Access allready opens built-in window, regardless of DoCmd.SetWarnings False. If I move DoCmd.SetWarnings False before TransferSheet method, import gets executed and no Msgbox is displayed - which is wrong. How can I handle this error, anybody knows ??
You could import to a temp table.
Then read this with a query that converts and cleans the data, and use this query for your further processing - which now will run without errors caused by malformed data.
I have figured out another way to solve this. I have put all controls that I need before DoCmd.TransferSheet method, including eliminating error that causes "was unable to append all data to table". I added code for checking excel file, and If Excel file data doesn't match criteria, DoCmd.TransferSheet is not performed - so therefore error "was unable to append all data to table" doesn't appear at all. Here It is (part of code which first checks If Excel file data is proper to perform DoCmd.TransferSheet import) :
Dim XcelApp As Object
Dim x, i
Set XcelApp = CreateObject("Excel.Application")
XcelApp.ScreenUpdating = False
XcelApp.Workbooks.Open("C:\Users\Lucky\Desktop\Test\Sample.xlsx")
With XcelApp
i = XcelApp.Rows(1).Find(What:="Število", LookIn:=xlValues, Lookat:=xlWhole).Column
x = XcelApp.Range(XcelApp.Cells(1, i), XcelApp.Cells(XcelApp.Rows.Count, i).End(xlUp)).Value
For i = 2 To UBound(x)
If Not IsNumeric(x(i, 1)) Then
ExcelApp.Quit
Set ExcelApp = Nothing
MsgBox "This Excel file is not valid"
: Exit Sub
End If
Next i
End With
XcelApp.Quit
XcelApp = Nothing
Code is snapshop from this solved thread: loop through Excel columns