2016-12-28 99 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