2016-12-28 57 views
4

我想要做的是映射我的按鈕(導入按鈕在我的窗體上)導入文本文件(文本文件實際上是在網絡驅動器上)。這些文本文件是固定的列。我很困惑如何合併表單和模塊一起工作。表單上的按鈕如何調用此模塊執行?另外,如果有更有效的方式來導入這些固定的文本文件,我將不勝感激。導入文本文件 - Vb/Access

我公司目前有以下VBA代碼設置爲我的形式(將用於導入文本文件到我的Access數據庫):

Private Sub cmdImport_Click() 

On Error GoTo Click_Err 

    reportDate = Format(txtReportDate, "YYMMDD") 
    reportGenDate = Format(textReportDate, "YYYYMMDD") 
    rDate = txtReportDate 

    If Nz(txtReportDate, "") = "" Then 
     MsgBox "NOTICE! Please enter the Report Month you wish to Import." 
     Exit Sub 
    End If 

    DoCmd.Hourglass True 
    DoCmd.SetWarnings False 

    ImportAll 

    DoCmd.Hourglass False 
    DoCmd.SetWarnings True 
    MsgBox "Finished Importing!" 
    DoCmd.OpenQuery "query_Files_Loaded_CE", acViewNormal, acReadOnly 

click_Exit: 
    DoCmd.Hourglass False 
    DoCmd.SetWarnings True 
    Exit Sub 

Click_Err: 
    DoCmd.Hourglass False 
    MsgBox "Error Detected: " & Err.Number & " - " & Err.Description, vbCritical, "Error" 
    Resume click_Exit 
End Sub 

對於我的模塊(請原諒的提示):

Option Compare Database 
Public reportDate As String 
Public reportGenDate As String 
Public rDate As Date 

    Public Function Import2010() 
    'Used to import a date range 
    Dim funcDate As Date ' 
    funcDate = #2/1/2016# 
    reportDate = Format(funcDate, "YYMM") 
    rDate = funcDate 

    'Basically Do While is a loop so what your doing here as long as the value of the date does not EQUAL 3/1/2016 
    'excute the nexxt line of code other wise exit this loop 
    Do While funcDate <> #3/1/2016# 
     DoCmd.SetWarnings False 
     'ImportAll 
     ImportFile "H3561" 
     'Msg Box reportDate 
     funcDate = DateAdd("m", 1, funcDate) 
     reportDate = Format(funcDate, "YYMM") 
     rDate = funcDate 
    Loop 

    DoCmd.SetWarnings True 

End Function 

Public Function ImportAll() ' Import button on FrmIMport 

    'A recordset is a selection of records from a table or query. 
    'Dim is short for the word Dimension and it allows you to declare variable names and their type. 
    'When you read data from the database in VBA, the result will be in a recordset (with the exception of scalar data). 
    Dim rs As Recordset 
    Dim sql As String 

    'This code loops through the recordset of all contracts and import files, as in it looks for 
    'Specific value based off a specific condition. 

    sql = "SELECT DISTINCT Contract FROM Contract_CE" 
    Set rs = CurrentDb.OpenRecordset(sql) 
    rs.MoveLast 'This method is used to move to the last record in a Recordset object. It also makes the last record the current record. 
    rs.MoveFirst 'This method is used to move to the first record in a Recordset object. It also makes the first record the current record. 
    If rs.RecordCount > 0 Then 
     Do While rs.EOF = False 
      ImportFile rs!contract 
      rs.MoveNext 'This method is used to move to the next record in a Recordset object. It also makes the "next" record the current record. 
     Loop 
    End If 

End Function 

Public Function ImportFile(contract As String) 

    Dim filepath As String 
    Dim tempPath As String 
    Dim zipFile As String 

    'Set paths 
    filepath = "\\XXXXX\XXXXX\XXXXX\XXXXXXX" 
    'tempPath = 
    tempPath = "\\XXXXXX\XXXXX\XXXXX\XX" 

    'Find the file 
    zipFile = GetFile(filepath) 

    'check if file exists 
    If zipFile = "" Then 
     'DoCmd.Hourglass False 
     'MsgBox contract & " " & reportDate & " File could not be located." 
     'DoCmd.Hourglass True 
     LogFail (contract) 
     Exit Function 
    End If 

    'Clearing out existing Contract/ReportDate data from Table 
    DeleteContract (contract) 

    'Delete all files in temp folder 
    DeleteAllFiles (tempPath) 

    'UnzipFile txt to temp folder 
    UnZip filepath & zipFile, tempPath 

    'Get txt file namee 
    txtFile = Replace(zipFile, ".zip", ".txt") 

    DoEvents 
    Sleep 10000 'wait for file to unzip 

    'The TransferText method is used to import/export text between the current Access database or Access project and a text file located 
    'externally to your database. You can also use this command to link to data in a text file. Additionally, can import from, export to, and link to a table in an HTML file. 
    'Importing txt file 
    'Depcreated - Alec Johnson - 5/12/2016 - Created new import spec 
    'DoCMD.TransferText acImportFixed, "ImportSpec_COMPRPT", tempPath & txtfile, False 
    DoCmd.TransferText acImportFixed, "COMPRPT_2016", "COMPRPT_CE", filepath & txtFile, False '<--does path go here? 

    'Update FileName 
    UpdateFileName (zipFile) 

    'Delete txt file from location 
    DeleteAllFiles (tempPath) 

    'Delete any Null records added to main table 
    DeleteNulls 

    'Log to table if successful 
    LogSuccess (contract) 

End Function 

Public Function DeleteAllFiles(path As String) 

'Delete all files in this folder 
On Error Resume Next 
Kill path & "*.*" 
End Function 

Function UnZip(filename As String, destinationPath As String) 
'FileSystemObject also called as FSO, provides an easy object based model to access computer’s file system. 
'You simply have to create an instance of FileSystemObject in VBA and then you can generate files, read files, delete files, 
'iterate though folders and do many other operations on your computer’s file system. 


    'Unzip file (s) to destination 
    Dim app As Object 
    Dim zipFile As Variant, unzipTo As Variant 

    zipFile = filename 
    unzipTo = destinationPath 

    Set FSO = CreateObject("Scripting.FileSystemObject") 

    If Not FSO.FolderExists(unzipTo) Then 
     FSO.CreateFolder (unzipTo) 
    End If 

    'If you want to extract only file you can use this: 
    'oApp.Namespace(FileNameFolder).CopyHere _ 
    'oApp.Namespace(Fname).items.items("test.txt") 

    Set oApp = CreateObject("Shell.Application") 

    oApp.Namespace(unzipTo).CopyHere oApp.Namespace(zipFile).Items 

    Set FSO = Nothing 

End Function 

Public Function GetFile(filepath As String) As String 

    Dim fileNamePart As String 
    Dim fCheck 

    fileNamePart = "COMPRPT_" + reportDate 
    fCheck = "" 
    fFound = "" 

    Set oFolder = CreateObject("scripting.filesystemobject").GetFolder(filepath) 
    For Each aFile In oFolder.Files 
     Set fCheck = aFile 
     If InStr(fCheck.Name, fileNamePart) Then 
      Set fFound = aFile 
      End If 
     Next 

     If fFound = "" Then 
      GetFile = "" 
     Else 
      GetFile = fFound.Name 
     End If 

End Function 

Public Function DeleteContract(contract As String) 

    Dim sql As String 
    sql = "Delete * FROM COMPRPT WHERE ContractNumber = '" & contract & "' AND ReportGenerationDate = '" & reportGenDate & "'" 
    DoCmd.RunSQL sql 
End Function 

Public Function LogSuccess(contract As String) 

    Dim sql As String 
    sql = "INSERT INTO FilesLoaded (Contract, ReportDate, Loaded) VALUES ('" & contract & "', #" & rDate & "#, -1)" 
    DoCmd.RunSQL sql 

End Function 


Public Function DeleteNulls() 

    Dim sql As String 
    sql = "DELETE * FROM COMPRPT WHERE ContractNumber Is Null" 
    DoCmd.RunSQL sql 


End Function 

Public Function lksjdlaskjd() 

    ImportFile "H0351", #4/1/2009# 
End Function 

這裏是一個文本文件的一個例子:

enter image description here

+0

是你的模塊形式在單獨的文件?如果不是的話,你的公共職能應該在形式上可見,你只需要用它的名字來稱呼它。如果它們在單獨的文件中,則可以在表單文件中引用包含該模塊的文件,然後使用這些函數。 –

+0

你可以添加你想要導入的示例文本文件嗎?我沒有看到你使用函數'ImportFile'的位置,也不知道爲什麼你有函數而不是subs。 (函數應該返回一個值,如果完成,則返回True)。這些模塊在哪裏? – Velid

+0

@Velid我已添加完整的代碼。我將很快提供一個文本文件的例子。我不想解壓縮文件,只需從本地網絡上的路徑中獲取文本文件並將其導入到我的數據庫中即可。 – KKP

回答

3

如果我理解正確的話,你的問題就出在這裏:

DoCmd.TransferText acImportFixed, "COMPRPT_2016", "COMPRPT_CE", filepath & txtFile, False '<--does path go here? 

但您解壓縮到tempPath,所以這應該是

DoCmd.TransferText acImportFixed, "COMPRPT_2016", "COMPRPT_CE", tempPath & txtFile, False 

與網絡文件的工作一般比本地文件慢,所以我會讓tempPath成爲本地路徑。

編輯:請注意,爲了使tempPath & txtFile工作,tempPath必須以\結束:
tempPath = "C:\XXXXXX\XXXXX\XXXXX\XX\"


與您的代碼的其他問題:

1 - 首先,使用Option Explicit,看this question瞭解詳情。

您有多個未聲明或拼寫錯誤的變量,例如fFoundoAppapp

2 - 這只是一個等待發生的錯誤:

reportDate = Format(txtReportDate, "YYMMDD") 
reportGenDate = Format(textReportDate, "YYYYMMDD") 

名稱的第二個文本框txtReportGenDate,不textReportDate

3 - 在ImportAll(),這一切都是不需要的,因爲你不使用總記錄:

rs.MoveLast 
rs.MoveFirst 
If rs.RecordCount > 0 Then 

4 - 這是錯誤的語法:

DeleteContract (contract) 

它適用於一單個參數,但是對於具有> 1個參數的subs將失敗。

使用

DeleteContract contract 

Call DeleteContract(contract) 

retVal = DeleteContract(contract) 
2

我是如何合併的形式和模塊一起工作感到困惑。表單上的按鈕如何調用此模塊執行?

對象和過程可以被認爲是公共或私人。例如: -

Private Sub Test 
    Msgbox "Hello World!" 
End Sub 

是私有的,這意味着只有其父母可以呼籲它。爲了闡述這一點,讓我們創建兩個模塊Module1Module2,並把我們的private sub TestModule1

另外在Module1我們另一個私有程序: -

Private Sub Test2 
    Msgbox "Back at ya" 
End Sub 

Module1TestTest2父母,因爲他們有相同的父,他們可以運行對方: -

Private Sub Test 
    Msgbox "Hello World!" 
    Test2 'This will run the Test2 procedure 
End Sub 

Module2不能運行它們中的任何一個,因爲它沒有視圖,它不涉及。

現在如果我們將Test更改爲公開(Public Sub Test),那麼Module2將能夠看到它,因爲它已經被公開。

Module2我們有: -

Public Sub Test3 
    Module1.Test 'This will run as it is public 
    Module1.Test2 'This will fail as it is private 
End Sub 

還有這樣太從模塊調用它們二: -

Public Sub Test3 
    Test 'This will run as it is public 
    Test2 'This will fail as it is private 
End Sub 

這不是明確的,但並可能導致錯誤和混亂,你可以在Module2一個過程,它也被稱爲Test,你怎麼會知道Test3正在運行哪些測試?爲了安全起見,你明確寫下它的位置Module1.Test