2014-04-28 25 views
7

Użyłem wiele razy opcji doCmd.TransferText, aby użyć zapisanej specyfikacji importu tekstu, ponieważ można łatwo zapisać ścieżkę pliku zwróconą z pliku Application.FileDialog(msoFileDialogFilePicker), aby znaleźć wybrany plik. importować z zapisaną specyfikacją.Jak określić inną ścieżkę pliku dla zapisanego importu programu Excel

Mam problem ze znalezieniem sposobu na to samo z plikiem excel, łatwo jest zapisać specyfikację importu excela, ale przy użyciu metody DoCmd.TransferSpreadSheet nie ma możliwości użycia zapisanego importu, a także użycie doCmd.RunSavedImportExport nie ma opcji określenia ścieżki pliku.

Czy istnieje obejście tego inny niż przy użyciu innego typu pliku (np .csv)

Odpowiedz

8

„Saved Import” i „Zapisane Eksport” w programie Access są przechowywane w ImportExportSpecification obiektów, które tworzą kolekcję CurrentProject.ImportExportSpecifications. Szczegóły zapisanego importu Excela będą wyglądały jak poniższy XML, który utworzyłem poprzez ręczne importowanie arkusza kalkulacyjnego Excela i zaznaczenie pola "Zapisz kroki importu" na ostatniej stronie kreatora importu.

<?xml version="1.0" encoding="utf-8" ?> 
<ImportExportSpecification Path = "C:\Users\Gord\Desktop\xlsxTest.xlsx" xmlns="urn:www.microsoft.com/office/access/imexspec"> 
    <ImportExcel FirstRowHasNames="true" Destination="xlsxTest" Range="Sheet1$" > 
      <Columns PrimaryKey="ID"> 
        <Column Name="Col1" FieldName="ID" Indexed="YESNODUPLICATES" SkipColumn="false" DataType="Long" /> 
        <Column Name="Col2" FieldName="TextField" Indexed="NO" SkipColumn="false" DataType="Text" /> 
        <Column Name="Col3" FieldName="DateField" Indexed="NO" SkipColumn="false" DataType="DateTime" /> 
      </Columns> 
     </ImportExcel> 
</ImportExportSpecification> 

ImportExportSpecification został zapisany pod nazwą Import-xlsxTest. Teraz, jeśli mogę zmienić nazwę pliku Excel z „xlsxTest.xlsx” do „anotherTest.xlsx” Mogę użyć następującego kodu VBA, aby zmienić nazwę pliku w XML ImportExportSpecification, a następnie wykonać import:

Option Compare Database 
Option Explicit 

Sub DoExcelImport() 
    Dim ies As ImportExportSpecification, i As Long, oldXML() As String, newXML As String 

    Const newXlsxFileSpec = "C:\Users\Gord\Desktop\anotherTest.xlsx" ' for testing 

    Set ies = CurrentProject.ImportExportSpecifications("Import-xlsxTest") 
    oldXML = Split(ies.XML, vbCrLf, -1, vbBinaryCompare) 
    newXML = "" 
    For i = 0 To UBound(oldXML) 
     If i = 1 Then 
      ' re-write the second line of the existing XML 
      newXML = newXML & _ 
        "<ImportExportSpecification Path = """ & _ 
        newXlsxFileSpec & _ 
        """ xmlns=""urn:www.microsoft.com/office/access/imexspec"">" & _ 
        vbCrLf 
     Else 
      newXML = newXML & oldXML(i) & vbCrLf 
     End If 
    Next 
    ies.XML = newXML 
    ies.Execute 
    Set ies = Nothing 
End Sub 

Więcej informacje na ImportExportSpecification obiektów, zobacz

ImportExportSpecification Object (Access)

+0

Thurough i pomocny jak zawsze Gord, dzięki! – pegicity

+0

Wielkie dzięki Gord! – ArtiBucco

+1

Oczywiście powinno to działać świetnie i daje dobre informacje podstawowe, ale znalazłem drugi sub() na http://stackoverflow.com/a/14443025/6099655, aby być bardziej prostym – CWilson

0

W moim przypadku

vbCrLf nie działa - ale vbLF ma!

Używam programu Access 2010 (32-bitowy).

Pozdrowienia od Stefana

2

Zbadałem ten sam problem. Rozwiązanie opublikowane przez Gorda dało mi błąd interpretacji XML. Cosmichighway opublikowało to rozwiązanie: http://www.utteraccess.com/forum/index.php?showtopic=1981212.

To rozwiązanie działa w programie Access 2010 i Access 2013 i powinna także działać w programie Access 2007.

With CurrentProject.ImportExportSpecifications("nameOfSpecification") 
    debug.print .XML 
    .XML = Replace(.XML, varSavedPathName, varNewPathName) 
    debug.print .XML 
End With 

byłem generowania unikalną nazwę pliku za wywóz, więc powrócił do oryginalnej ścieżki filename gdy proces był kompletny . WorkHoursTransactions jest const. Przykład:

CONST ConstExportSavedPathName="c:\temp\Name Of File To Use.xls" 

tmpFileName = WorkHoursTransactions & ";" & Format(Now(), "YYYYMMDD-HHMMSS") & ".xls" 
With CurrentProject.ImportExportSpecifications(WorkHoursTransactions) 
    .XML = Replace(.XML, ConstExportSavedPathName, tmpFileName) 
    'Debug.Print .XML 
End With 

DoCmd.OpenReport WorkHoursTransactions, acViewReport, , , acWindowNormal 
DoCmd.RunSavedImportExport WorkHoursTransactions 

' return to original filename 
With CurrentProject.ImportExportSpecifications(WorkHoursTransactions) 
    .XML = Replace(.XML, tmpFileName, ConstExportSavedPathName) 
    'Debug.Print .XML 
End With 

Natknąłem się na tę fajną wskazówkę, aby użyć bezpośredniego okna do wyświetlenia XML. Jeśli masz specyfikację eksportowej nazwie „Export-Tabela 1”, to można wkleić ten w najbliższym oknie, aby zobaczyć XML:

? CurrentProject.ImportExportSpecifications.Item("Export-Table1").XML 
2

widziałem to i myślałem, że dzielić się coś pracowałem jakiś czas z powrotem do Rozwiąż problem.Daje większą kontrolę nad tym, co można zmienić w specyfikacji:

' MSXML2 requires reference to "Microsoft XML, v6.0" 
' earlier versions are probably compatible, remember to use the appropriate DOMDocument object version. 
Sub importExcelFile(ImportSpecName As String, Filename As String, SheetName As String, OutputTableName As String) 
    Dim XMLData As MSXML2.DOMDocument60 
    Dim ImportSpec As ImportExportSpecification 
    Dim XMLNode As IXMLDOMNode 

    ' Get XML object to manage the spec data 
    Set XMLData = New MSXML2.DOMDocument60 

    XMLData.async = False 
    XMLData.SetProperty "SelectionLanguage", "XPath" 
    XMLData.SetProperty "SelectionNamespaces", "xmlns:imex='urn:www.microsoft.com/office/access/imexspec'" 
     ' need to rename the default namespace, so that we can XPath to it. New name = 'imex' 

    ' existing Import Specification (should be set up manually with relevant name) 
    Set ImportSpec = CurrentProject.ImportExportSpecifications(ImportSpecName) 
    XMLData.LoadXML ImportSpec.XML 

    ' change it's path to the one specified 
    With XMLData.DocumentElement 
     .setAttribute "Path", Filename 
     ' Destination attribute of the ImportExcel node 
     Set XMLNode = .SelectSingleNode("//imex:ImportExcel/@Destination") ' XPath to the Destination attribute 
     XMLNode.Text = OutputTableName 
     ' Range attribute of the ImportExcel node 
     Set XMLNode = .SelectSingleNode("//imex:ImportExcel/@Range") ' XPath to the range attribute 
     XMLNode.Text = SheetName & "$" 
    End With 

    ImportSpec.XML = XMLData.XML 

    ' run the updated import 
    ImportSpec.Execute 

End Sub 
0

dodać do @Alberts odpowiedź, jeśli mamy bieżącą ścieżkę pliku jako stała, wtedy, kiedy uruchomić kod następnym razem (na przykład , użytkownik zdecyduje się zapisać plik Excela w innym folderze po pewnym czasie), funkcja "Zamień" nie znajdzie szukanego tekstu, ponieważ ścieżka została zmieniona w pierwszym uruchomieniu. Aby uczynić go dynamicznym, wystarczy zapisać bieżącą ścieżkę pliku do tabeli, gdy zostanie zastąpiona przez nową ścieżkę. W funkcji "Zamień" po prostu odwołujemy się do tej wartości. Nie ma twardego kodowania ścieżek plików.

Let Current File Path = DLookup("[Current file path]", "File Path Table") 
Let New File Path = DLookup("[New file path]", "File Path Table") 
With CurrentProject.ImportExportSpecifications("Saved-Export") 
    .XML = Replace(.XML, Current File Path, New File Path) 
End With 
DoCmd.RunSavedImportExport Saved-Export 

'Now you write the 'new file path' to the 'current file path' field in the table 

Set mydb = DBEngine.Workspaces(0).Databases(0) 
Set myset = mydb.OpenRecordset("File Path Table") 
myset.Edit 
    Let myset![Current file path] = New File Path 
myset.Update 
myset.Close 
Set myset = Nothing 
Set mydb = Nothing 

więc następnym razem to działa, to wybrać odpowiedni plik bieżący zastąpić.

Powiązane problemy