2017-08-01 101 views
0

我正在準備一個.accdb文件中的Visual Basic for Applications(VBA)腳本。 (我沒有任何要求,我只是打開了我所擁有的:Microsoft Access 2016應用程序,並打開了其Visual Basic編輯器並開始編碼。)爲什麼Access文件在DoCmd.TransferDatabase命令之後增長太多?如何將一個表從一個.MDB Access文件移動到另一個?

目標:該腳本旨在移動從.MDB文件到另一個.MDB文件的表格。 我找不到直接做這件事的方法,所以我分兩步做了。

什麼腳本的作用:

  • 第1步:轉移,或副本,給定的表從本地.mdb文件(其路徑+名稱+擴展名(存儲在變量命名srcTableName) 在可變 srcPath)到我的腳本文件(.ACCDB文件名爲Script.accdb 並保存在同一文件夾作爲源.MDB文件)
  • 第2步: 轉讓,或副本,新複製的表從腳本的當前文件的一些.MDB 文件,該文件是在一些硬盤(路徑+名稱+擴展在destPath)(命名 intermediaryTableName

我不能在2個步驟合併爲一個(即:表中直接從srcTableName複製到destPath

所以,這是它: 表.MDB文件,在當地- >在當前文件表(本地,包含腳本,擴展.ACCDB)- 在.MDB文件>表,在一些其他驅動器

它的工作原理。

問題是:每次我跑我的腳本時,腳本的文件(我有時也稱之爲「當前文件」,或.ACCDB一個)增長30MB以上。這是不合適的。 (我甚至不將文件保存爲什麼文件需要放大這樣的嗎?)

我檢測到的問題來自於命令:DoCmd.TransferDatabase。這個命令似乎增加了很多文件的大小。

運行腳本之後:腳本的文件(500 KB文件)已成爲27 776 KB之一。

追隨中運行:

  • 27 776KB - > 54 912 KB(差之前和運行後:27 136KB)
  • 54 912 KB - > 82 048 KB(差:27 135KB)

我不知道這個命令寫的是什麼。我無法在文檔或幾乎任何谷歌搜索結果中找到關於此的任何信息。 當我刪除當前文件(腳本文件)中複製的表時,文件的大小几乎不縮小。所以DoCmd.TransferDatabase似乎寫別的東西(一些元數據我沒有找到,也許)

我希望我可以做一些其他方式的第一步。尋找解決方法:

  • 我沒能在 順序編程配置ADODB.Connection它從舊.MDB文件導入表( srcPath之一)
  • DoCmd.CopyObject是一個似乎取悅我的函數,因爲它似乎並沒有創建「垃圾」/神祕地放大文件。 可用MSDN microsof的文檔沒有提供有關應用此函數或參數格式的效果的更多詳細信息,但似乎準備好僅操作屬於當前文件的對象 而不是外部文件。我想嘗試設置其參數 SourceObjectName到外部(即:在另一個驅動器中),詳細路徑,但似乎只有 接受表的(簡稱)名稱。我嘗試尋找一些類似於表的訪問對象的長路徑名稱,但也包括:結構 的包含我要導入的表 (srcDB.TableDefs(srcTableName).Connect)的表的字段對於此 似乎爲空表和「name」屬性只顯示已知(「sh5」)的表I 的名稱,並且可以看作Access的用戶,這似乎對 無用,請指定從外部文件。
  • 我能夠從一個「普通」訪問文件(.accdb擴展名)複製表或導出+導入表到另一個.accdb文件。由於 這樣,我試圖將.MDB文件轉換爲10 .accdb,但沒有成功。我得到了一個 「」該項目不能轉換成這種格式。該項目只能將 轉換爲Access 2000或更新的格式。「使用 時出現錯誤信息Microsoft.Office.Interop.Access.Application.ConvertAccessProject 函數。

我也試圖「壓縮和修復」當前/腳本的文件,設置訪問應用程序,以真正的「自動緊湊」選項,但它並沒有太大的差別: 下運行:文件82 048 KB的代碼塊之後 文件大小:82 048 KB腳本後 文件大小:109 056 KB(前和運行後差:27 008KB)

畢竟這:這個代碼塊之前大小

有人有想法阻止DoCmd.TransferDatabase這樣擴大文件? 或另一個解決方法將表從一個文件複製到另一個?

這裏是我的代碼,它應該提供更多有用的細節:

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 
+0

文件膨脹是正常的,雖然是不希望的行爲。這只是一個表面問題,並不表示故障。 – Gustav

+0

請注意,打開文件時無法壓縮和修復文件。它只在最後一次公開會議結束時有效。您使用的壓縮和修復代碼僅在其他數據庫上使用時纔有效。 –

+0

@Gustav,你知道爲什麼DoCmd.TransferDatabase使得文件像這樣膨脹是正常的嗎?在我的情況下,它不僅是一個整容問題,它確實使文件變得更重,並且我對文件可以達到的大小有限制,很容易被這種不需要的行爲克服。 –

回答

0

您可以使用SQL查詢來從一個數據庫移動表到另一個。在源數據庫 執行此:

SELECT * INTO MyTable IN 'C:\MyOtherDb.MDB' 
FROM MyTable; 

我已經使用這個有很多,從未有過這些大小問題。

您還可以使用SQL將表拉入當前的Db。

SELECT * INTO MyTable FROM [C:\MySourceDb.mdb].MyTable; 

顯然,您可以使用VBA來執行此查詢。

請注意,某些元信息(主索引以外的索引,查找字段)可能會丟失。

相關問題