Bagaimana Anda menggunakan kontrol versi dengan pengembangan akses?

163

Saya terlibat dengan memperbarui solusi Access. Ini memiliki jumlah VBA yang baik, sejumlah pertanyaan, sejumlah kecil tabel, dan beberapa formulir untuk entri data & pembuatan laporan. Ini kandidat yang ideal untuk Akses.

Saya ingin membuat perubahan pada desain tabel, VBA, kueri, dan formulir. Bagaimana saya bisa melacak perubahan saya dengan kontrol versi? (kami menggunakan Subversion, tetapi ini berlaku untuk semua rasa) Saya dapat menempelkan seluruh mdb dalam subversi, tetapi itu akan menyimpan file biner, dan saya tidak akan tahu bahwa saya baru saja mengubah satu baris kode VBA.

Saya berpikir tentang menyalin kode VBA untuk memisahkan file, dan menyimpannya, tetapi saya bisa melihat mereka dengan cepat tidak sinkron dengan apa yang ada di database.

Nathan DeWitt
sumber
1
Crossposting solusi ini untuk pertanyaan terkait mengekspor skema Access db.
Eric G
1
Access mendukung antarmuka SCC, sehingga kontrol versi apa pun yang kompatibel dengan antarmuka ini siap untuk diakses. Penafian: Saya bekerja untuk plasticscm.com dan kami telah beberapa pelanggan menggunakannya dengan Access.
pablo

Jawaban:

180

Kami menulis skrip kami sendiri di VBScript, yang menggunakan Application.SaveAsText () yang tidak didokumentasikan dalam Access untuk mengekspor semua kode, formulir, makro dan modul laporan. Ini dia, itu harus memberi Anda beberapa petunjuk. (Hati-hati: beberapa pesan dalam bahasa Jerman, tetapi Anda dapat dengan mudah mengubahnya.)

EDIT: Untuk meringkas berbagai komentar di bawah: Proyek kami mengasumsikan .adp-file. Untuk mendapatkan pekerjaan ini dengan .mdb / .accdb, Anda harus mengubah OpenAccessProject () menjadi OpenCurrentDatabase (). (Diperbarui untuk digunakan OpenAccessProject()jika melihat ekstensi .adp, gunakan yang lain OpenCurrentDatabase().)

decompose.vbs:

' Usage:
'  CScript decompose.vbs <input file> <path>

' Converts all modules, classes, forms and macros from an Access Project file (.adp) <input file> to
' text and saves the results in separate files to <path>.  Requires Microsoft Access.
'

Option Explicit

const acForm = 2
const acModule = 5
const acMacro = 4
const acReport = 3

' BEGIN CODE
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

dim sADPFilename
If (WScript.Arguments.Count = 0) then
    MsgBox "Bitte den Dateinamen angeben!", vbExclamation, "Error"
    Wscript.Quit()
End if
sADPFilename = fso.GetAbsolutePathName(WScript.Arguments(0))

Dim sExportpath
If (WScript.Arguments.Count = 1) then
    sExportpath = ""
else
    sExportpath = WScript.Arguments(1)
End If


exportModulesTxt sADPFilename, sExportpath

If (Err <> 0) and (Err.Description <> NULL) Then
    MsgBox Err.Description, vbExclamation, "Error"
    Err.Clear
End If

Function exportModulesTxt(sADPFilename, sExportpath)
    Dim myComponent
    Dim sModuleType
    Dim sTempname
    Dim sOutstring

    dim myType, myName, myPath, sStubADPFilename
    myType = fso.GetExtensionName(sADPFilename)
    myName = fso.GetBaseName(sADPFilename)
    myPath = fso.GetParentFolderName(sADPFilename)

    If (sExportpath = "") then
        sExportpath = myPath & "\Source\"
    End If
    sStubADPFilename = sExportpath & myName & "_stub." & myType

    WScript.Echo "copy stub to " & sStubADPFilename & "..."
    On Error Resume Next
        fso.CreateFolder(sExportpath)
    On Error Goto 0
    fso.CopyFile sADPFilename, sStubADPFilename

    WScript.Echo "starting Access..."
    Dim oApplication
    Set oApplication = CreateObject("Access.Application")
    WScript.Echo "opening " & sStubADPFilename & " ..."
    If (Right(sStubADPFilename,4) = ".adp") Then
        oApplication.OpenAccessProject sStubADPFilename
    Else
        oApplication.OpenCurrentDatabase sStubADPFilename
    End If

    oApplication.Visible = false

    dim dctDelete
    Set dctDelete = CreateObject("Scripting.Dictionary")
    WScript.Echo "exporting..."
    Dim myObj
    For Each myObj In oApplication.CurrentProject.AllForms
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acForm, myObj.fullname, sExportpath & "\" & myObj.fullname & ".form"
        oApplication.DoCmd.Close acForm, myObj.fullname
        dctDelete.Add "FO" & myObj.fullname, acForm
    Next
    For Each myObj In oApplication.CurrentProject.AllModules
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acModule, myObj.fullname, sExportpath & "\" & myObj.fullname & ".bas"
        dctDelete.Add "MO" & myObj.fullname, acModule
    Next
    For Each myObj In oApplication.CurrentProject.AllMacros
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acMacro, myObj.fullname, sExportpath & "\" & myObj.fullname & ".mac"
        dctDelete.Add "MA" & myObj.fullname, acMacro
    Next
    For Each myObj In oApplication.CurrentProject.AllReports
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acReport, myObj.fullname, sExportpath & "\" & myObj.fullname & ".report"
        dctDelete.Add "RE" & myObj.fullname, acReport
    Next

    WScript.Echo "deleting..."
    dim sObjectname
    For Each sObjectname In dctDelete
        WScript.Echo "  " & Mid(sObjectname, 3)
        oApplication.DoCmd.DeleteObject dctDelete(sObjectname), Mid(sObjectname, 3)
    Next

    oApplication.CloseCurrentDatabase
    oApplication.CompactRepair sStubADPFilename, sStubADPFilename & "_"
    oApplication.Quit

    fso.CopyFile sStubADPFilename & "_", sStubADPFilename
    fso.DeleteFile sStubADPFilename & "_"


End Function

Public Function getErr()
    Dim strError
    strError = vbCrLf & "----------------------------------------------------------------------------------------------------------------------------------------" & vbCrLf & _
               "From " & Err.source & ":" & vbCrLf & _
               "    Description: " & Err.Description & vbCrLf & _
               "    Code: " & Err.Number & vbCrLf
    getErr = strError
End Function

Jika Anda memerlukan Perintah yang dapat diklik, alih-alih menggunakan baris perintah, buat file bernama "decompose.cmd" dengan

cscript decompose.vbs youraccessapplication.adp

Secara default, semua file yang diekspor masuk ke subfolder "Scripts" dari aplikasi-Akses Anda. File .adp / mdb juga disalin ke lokasi ini (dengan akhiran "stub") dan dilucuti dari semua modul yang diekspor, membuatnya sangat kecil.

Anda HARUS memeriksa rintisan ini dengan file sumber, karena sebagian besar pengaturan akses dan bilah menu kustom tidak dapat diekspor dengan cara lain. Pastikan untuk melakukan perubahan pada file ini saja, jika Anda benar-benar mengubah beberapa pengaturan atau menu.

Catatan: Jika Anda memiliki Autoexec-Makros yang didefinisikan dalam Aplikasi Anda, Anda mungkin harus menahan tombol Shift ketika Anda menjalankan dekomposisi untuk mencegahnya mengeksekusi dan mengganggu ekspor!

Tentu saja, ada juga skrip terbalik, untuk membangun Aplikasi dari "Sumber" -Direktori:

compose.vbs:

' Usage:
'  WScript compose.vbs <file> <path>

' Converts all modules, classes, forms and macros in a directory created by "decompose.vbs"
' and composes then into an Access Project file (.adp). This overwrites any existing Modules with the
' same names without warning!!!
' Requires Microsoft Access.

Option Explicit

const acForm = 2
const acModule = 5
const acMacro = 4
const acReport = 3

Const acCmdCompileAndSaveAllModules = &H7E

' BEGIN CODE
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

dim sADPFilename
If (WScript.Arguments.Count = 0) then
    MsgBox "Please enter the file name!", vbExclamation, "Error"
    Wscript.Quit()
End if
sADPFilename = fso.GetAbsolutePathName(WScript.Arguments(0))

Dim sPath
If (WScript.Arguments.Count = 1) then
    sPath = ""
else
    sPath = WScript.Arguments(1)
End If


importModulesTxt sADPFilename, sPath

If (Err <> 0) and (Err.Description <> NULL) Then
    MsgBox Err.Description, vbExclamation, "Error"
    Err.Clear
End If

Function importModulesTxt(sADPFilename, sImportpath)
    Dim myComponent
    Dim sModuleType
    Dim sTempname
    Dim sOutstring

    ' Build file and pathnames
    dim myType, myName, myPath, sStubADPFilename
    myType = fso.GetExtensionName(sADPFilename)
    myName = fso.GetBaseName(sADPFilename)
    myPath = fso.GetParentFolderName(sADPFilename)

    ' if no path was given as argument, use a relative directory
    If (sImportpath = "") then
        sImportpath = myPath & "\Source\"
    End If
    sStubADPFilename = sImportpath & myName & "_stub." & myType

    ' check for existing file and ask to overwrite with the stub
    if (fso.FileExists(sADPFilename)) Then
        WScript.StdOut.Write sADPFilename & " exists. Overwrite? (y/n) "
        dim sInput
        sInput = WScript.StdIn.Read(1)
        if (sInput <> "y") Then
            WScript.Quit
        end if

        fso.CopyFile sADPFilename, sADPFilename & ".bak"
    end if

    fso.CopyFile sStubADPFilename, sADPFilename

    ' launch MSAccess
    WScript.Echo "starting Access..."
    Dim oApplication
    Set oApplication = CreateObject("Access.Application")
    WScript.Echo "opening " & sADPFilename & " ..."
    If (Right(sStubADPFilename,4) = ".adp") Then
        oApplication.OpenAccessProject sADPFilename
    Else
        oApplication.OpenCurrentDatabase sADPFilename
    End If
    oApplication.Visible = false

    Dim folder
    Set folder = fso.GetFolder(sImportpath)

    ' load each file from the import path into the stub
    Dim myFile, objectname, objecttype
    for each myFile in folder.Files
        objecttype = fso.GetExtensionName(myFile.Name)
        objectname = fso.GetBaseName(myFile.Name)
        WScript.Echo "  " & objectname & " (" & objecttype & ")"

        if (objecttype = "form") then
            oApplication.LoadFromText acForm, objectname, myFile.Path
        elseif (objecttype = "bas") then
            oApplication.LoadFromText acModule, objectname, myFile.Path
        elseif (objecttype = "mac") then
            oApplication.LoadFromText acMacro, objectname, myFile.Path
        elseif (objecttype = "report") then
            oApplication.LoadFromText acReport, objectname, myFile.Path
        end if

    next

    oApplication.RunCommand acCmdCompileAndSaveAllModules
    oApplication.Quit
End Function

Public Function getErr()
    Dim strError
    strError = vbCrLf & "----------------------------------------------------------------------------------------------------------------------------------------" & vbCrLf & _
               "From " & Err.source & ":" & vbCrLf & _
               "    Description: " & Err.Description & vbCrLf & _
               "    Code: " & Err.Number & vbCrLf
    getErr = strError
End Function

Sekali lagi, ini cocok dengan pendamping "compose.cmd" yang berisi:

cscript compose.vbs youraccessapplication.adp

Ia meminta Anda untuk mengkonfirmasi menimpa aplikasi Anda saat ini dan pertama kali membuat cadangan, jika Anda melakukannya. Itu kemudian mengumpulkan semua file sumber di Direktori Sumber dan memasukkan kembali mereka ke dalam rintisan.

Selamat bersenang-senang!

Oliver
sumber
1
Saya suka kode ini. Saya menemukan bahwa oApplication.OpenAccessProject tidak akan berfungsi pada file .accdb (atau mungkin itu adalah Access 2007) dan saya harus menggunakan oApplication.OpenCurrentDatabase sebagai gantinya.
hughdbrown
1
Saya melakukan sesuatu yang serupa (SaveAsText, tetapi dalam VBA dan dengan file MDB alih-alih ADP), tetapi saya memiliki satu masalah besar yang tersisa: setelah setiap ekspor, Subversion mengenali sekitar 100 file yang diubah (bahkan jika saya mengubah hanya satu atau dua ). ketika saya melihat perubahan, saya melihat bahwa beberapa nama variabel atau nama kontrol telah mengubah ejaan huruf besar / huruf kecil. Sebagai contoh: setiap file yang pernah berisi "OrderNumber" sekarang berisi "Ordernumber" dalam ekspor dan karenanya ditandai sebagai "diubah" (setidaknya oleh SVN, belum mencoba SCM lainnya). Adakah yang bisa saya hindari? Terima kasih banyak!
Christian Specht
3
Ya, ini juga merupakan gangguan terus-menerus dalam proyek kami. Sejauh yang kami tentukan, masalahnya adalah bahwa variabel dalam proyek Anda memiliki nama yang sama dengan kontrol, hanya dalam kasus yang berbeda (atas / rendah). Sekarang, tergantung pada urutan modul yang disusun, Access tampaknya mengambil satu ejaan dan "memperbaiki" yang lainnya, karena VBA seharusnya tidak peka huruf besar-kecil. Akses melakukan ini, meskipun kontrolnya ada pada bentuk yang berbeda! Masalahnya semakin besar jika Anda bahkan memiliki beberapa kontrol dengan nama yang sama dalam berbagai kasus pada formulir yang berbeda.
Oliver
3
Satu-satunya solusi adalah memburu setiap Variabel / Nama-Kontrol dan mengubah ejaan menjadi bentuk umum. Setelah ekspor dan melakukan perubahan, nama harus stabil. Awalan nama kontrol dengan tipenya cukup banyak memastikan melalui penamaan konvensi bahwa nama tidak bertabrakan dengan variabel. (misalnya txtTitle untuk kotak teks yang berisi bidang Judul atau cmbPengguna untuk kotak kombo dan sebagainya)
Oliver
Lupa menambahkan bahwa untuk mendapatkan pekerjaan ini dengan mdb, saya harus mengubah OpenAccessProject ke OpenCurrentDatabase .
DaveParillo
19

Tampaknya ada sesuatu yang cukup tersedia di Access:

Tautan ini dari msdn menjelaskan cara menginstal add-in kontrol sumber untuk Microsoft Access. Ini dikirimkan sebagai unduhan gratis sebagai bagian dari Access Developer Extensions for Access 2007 dan sebagai add-in gratis terpisah untuk Access 2003.

Saya senang Anda mengajukan pertanyaan ini dan saya meluangkan waktu untuk mencarinya, karena saya juga ingin kemampuan ini. Tautan di atas memiliki informasi lebih lanjut tentang ini dan tautan ke peralatan tambahan.

Pembaruan:
Saya menginstal add-in untuk Access 2003. Ini hanya akan bekerja dengan VSS, tetapi itu memungkinkan saya untuk memasukkan objek Access (formulir, kueri, tabel, modul, dll) ke dalam repositori. Saat Anda mengedit item apa pun di dalam repo, Anda diminta untuk memeriksanya, tetapi Anda tidak harus melakukannya. Selanjutnya saya akan memeriksa bagaimana menangani dibuka dan diubah pada suatu sistem tanpa tambahan. Saya bukan penggemar VSS, tapi saya benar-benar suka membayangkan menyimpan objek akses dalam repo.

Update2:
Mesin tanpa add-in tidak dapat membuat perubahan apa pun pada struktur basis data (tambahkan bidang tabel, parameter kueri, dll.). Pada awalnya saya pikir ini mungkin menjadi masalah jika seseorang perlu, karena tidak ada cara yang jelas untuk menghapus database Access dari kontrol sumber jika Access tidak memiliki tambahan add-in.

Id menemukan bahwa menjalankan database "kompak dan perbaikan" meminta Anda jika Anda ingin menghapus database dari kontrol sumber. Saya memilih ya dan dapat mengedit database tanpa add-in. Artikel di tautan di atas juga memberikan instruksi dalam mengatur Access 2003 dan 2007 untuk menggunakan Sistem Tim. Jika Anda dapat menemukan penyedia MSSCCI untuk SVN, ada kemungkinan besar Anda bisa menggunakannya.

Brettski
sumber
Perhatikan bahwa kami memiliki beberapa masalah dengan tidak dapat melihat ADP dari VSS jika lebih dari satu orang telah mengeditnya. Kami akhirnya harus memiliki cadangan terpisah untuk ini!
Simon
Saya bermain dengan pendekatan ini (menggunakan Vault, karena saya tahu tidak ada penyedia MSSCCI gratis untuk SVN ... TortoiseSVNSCC tidak terawat dan tidak bekerja untuk saya, dan dua atau tiga opsi lainnya bersifat komersial). Ini bekerja, tetapi itu memaksa Anda untuk menggunakan pendekatan penguncian eksklusif kuno ke kontrol sumber, dan untuk alasan itu saya berencana untuk meninggalkannya dan menggunakan solusi @ Oliver.
Todd Owen
14

Solusi menulis / dekomposisi yang diposting oleh Oliver sangat bagus, tetapi memiliki beberapa masalah:

  • File-file tersebut dikodekan sebagai UCS-2 (UTF-16) yang dapat menyebabkan sistem / alat kontrol versi menganggap file-file tersebut sebagai biner.
  • File-file tersebut mengandung banyak celah yang sering berubah - checksum, informasi printer dan banyak lagi. Ini adalah masalah serius jika Anda ingin membersihkan perbedaan atau perlu bekerja sama dalam proyek.

Saya berencana untuk memperbaiki ini sendiri, tetapi menemukan sudah ada solusi bagus yang tersedia: timabell / msaccess-vcs-integrasi di GitHub. Saya telah menguji msaccess-vcs-integrasi dan itu berfungsi dengan baik.

Diperbarui 3 Maret 2015 : Proyek ini awalnya dipelihara / dimiliki oleh bkidwell di Github, tetapi ditransfer ke timabell - tautan di atas ke proyek diperbarui sesuai dengan itu. Ada beberapa fork dari proyek asli oleh bkidwell, misalnya oleh ArminBra dan matonb , yang seharusnya tidak digunakan AFAICT.

Kelemahan menggunakan msaccess-vcs-integrasi dibandingkan dengan solusi dekomposisi Olivers:

  • Secara signifikan lebih lambat. Saya yakin bahwa masalah kecepatan dapat diperbaiki, tetapi saya tidak perlu mengekspor proyek saya ke teks sesering itu ...
  • Itu tidak membuat proyek Akses rintisan dengan barang yang diekspor dihapus. Ini juga dapat diperbaiki (dengan mengadopsi kode dari skrip penguraian), tetapi sekali lagi - tidak begitu penting.

Bagaimanapun, rekomendasi saya yang jelas adalah msaccess-vcs-integrasi. Itu memecahkan semua masalah yang saya miliki dengan menggunakan Git pada file yang diekspor.

hansfn
sumber
Sepertinya garpu ArminBra ada di depan sekarang (terlihat dari melihat grafik jaringan ). Matonb belum menanggapi satu-satunya permintaan penarikan, jadi kurasa setidaknya mereka sudah mengabaikannya.
Tim Abell
1
Dan sekarang ada juga garpu saya github.com/timabell/msaccess-vcs-integration - memperbaiki kerusakan ekspor tabel kunci majemuk. Dua lainnya terlihat agak ditinggalkan sehingga saya senang untuk mengambil laporan bug permintaan tarik dll pada garpu saya itu.
Tim Abell
Saya akan dengan sopan menyarankan untuk mengedit jawaban ini untuk menunjuk ke garpu saya karena itu sekarang versi yang paling aktif dipertahankan.
Tim Abell
2
@TimAbell: Saya telah memperbarui jawaban saya untuk mencerminkan fakta bahwa proyek telah ditransfer kepada Anda. PS! Saya harap kita bisa mendapatkan suara karena saya pikir ini adalah solusi terbaik.
hansfn
2
bagus, menavigasi garpu proyek github tampaknya menjadi masalah terbaru yang kami temukan untuk diri kita sendiri :-)
Tim Abell
14

Olivers menjawab batu, tetapi CurrentProjectreferensi itu tidak berhasil untuk saya. Saya akhirnya merobek nyali dari tengah ekspornya dan menggantinya dengan ini, berdasarkan solusi serupa oleh Arvin Meyer . Memiliki keuntungan mengekspor Kueri jika Anda menggunakan mdb, bukan adp.

' Writes database componenets to a series of text files
' @author  Arvin Meyer
' @date    June 02, 1999
Function DocDatabase(oApp)
    Dim dbs 
    Dim cnt 
    Dim doc 
    Dim i
    Dim prefix
    Dim dctDelete
    Dim docName

    Const acQuery = 1

    Set dctDelete = CreateObject("Scripting.Dictionary")

    Set dbs = oApp.CurrentDb() ' use CurrentDb() to refresh Collections
    Set cnt = dbs.Containers("Forms")
    prefix = oApp.CurrentProject.Path & "\"
    For Each doc In cnt.Documents
        oApp.SaveAsText acForm, doc.Name, prefix & doc.Name & ".frm"
        dctDelete.Add "frm_" & doc.Name, acForm
    Next

    Set cnt = dbs.Containers("Reports")
    For Each doc In cnt.Documents
        oApp.SaveAsText acReport, doc.Name, prefix & doc.Name & ".rpt"
        dctDelete.Add "rpt_" & doc.Name, acReport
    Next

    Set cnt = dbs.Containers("Scripts")
    For Each doc In cnt.Documents
        oApp.SaveAsText acMacro, doc.Name, prefix & doc.Name & ".vbs"
        dctDelete.Add "vbs_" & doc.Name, acMacro
    Next

    Set cnt = dbs.Containers("Modules")
    For Each doc In cnt.Documents
        oApp.SaveAsText acModule, doc.Name, prefix & doc.Name & ".bas"
        dctDelete.Add "bas_" & doc.Name, acModule
    Next

    For i = 0 To dbs.QueryDefs.Count - 1
        oApp.SaveAsText acQuery, dbs.QueryDefs(i).Name, prefix & dbs.QueryDefs(i).Name & ".txt"
        dctDelete.Add "qry_" & dbs.QueryDefs(i).Name, acQuery
    Next

    WScript.Echo "deleting " & dctDelete.Count & " objects."
    For Each docName In dctDelete
        WScript.Echo "  " & Mid(docName, 5)
        oApp.DoCmd.DeleteObject dctDelete(docName), Mid(docName, 5)
    Next

    Set doc = Nothing
    Set cnt = Nothing
    Set dbs = Nothing
    Set dctDelete = Nothing

End Function
DaveParillo
sumber
1
+1 untuk menyertakan kueri. Sekarang hanya perlu memasukkan skema tabel.
Marc Stober
Jawaban yang disetujui tidak berfungsi untuk Access 97, tetapi jawaban ini membantu saya untuk memodifikasinya untuk penggunaan saya sendiri. Terima kasih telah memposting ini!
CTristan
2
Saya sangat menyarankan untuk menempatkan penyimpanan kueri sebelum bentuk penyimpanan untuk mengubah urutan penghapusan nanti. Saya mengalami beberapa masalah dengan DeleteObject di pernyataan terakhir untuk Setiap ketika saya mencoba untuk menghapus pertanyaan yang sudah dihapus secara otomatis ketika formulir yang sesuai mereka telah dihapus sebelumnya. Juga, jika Anda memiliki beberapa formulir yang dibuka saat startup dan tidak ingin menahan F11 (atau menonaktifkannya), cukup masukkan oApp.DoCmd.Tutup acForm, "formName" setelah Anda menjalankannya melalui dokumen. Dokumen
Anton Kaiser
@Cunso Tolong bisakah Anda memposting kode Anda yang kompatibel dengan Access 97. Jadi saya tidak perlu mengembangkannya kembali.
Lorenz Meyer
bagaimana saya menggunakan ini? Sebut saja dari sub?
kevinykuo
11

Kami mengembangkan alat internal kami sendiri, di mana:

  1. Modul: diekspor sebagai file txt dan kemudian dibandingkan dengan "alat membandingkan file" (freeware)
  2. Formulir: diekspor melalui perintah undocument application.saveAsText. Maka dimungkinkan untuk melihat perbedaan antara 2 versi yang berbeda ("alat pembanding file" sekali lagi).
  3. Makro: kami tidak memiliki makro untuk dibandingkan, karena kami hanya memiliki makro "autoexec" dengan satu baris meluncurkan prosedur VBA utama
  4. Kueri: hanya string teks yang disimpan dalam tabel: lihat infra
  5. tabel: kami menulis pembanding tabel kami sendiri, daftar perbedaan dalam catatan DAN struktur tabel.

Seluruh sistem cukup pintar untuk memungkinkan kami menghasilkan versi "runtime" aplikasi Access kami, secara otomatis dihasilkan dari file txt (modul, dan formulir yang dibuat ulang dengan perintah undocument application.loadFromText) dan file mdb (tabel).

Mungkin terdengar aneh tapi berhasil.

Philippe Grondier
sumber
8
Akan senang melihat alat ini bersumber terbuka!
Todd Owen
Apakah ide yang baik untuk mengunggah file teks yang diekspor ini di GitHub?
Santosh
9

Berdasarkan ide-ide posting ini dan entri serupa di beberapa blog saya telah menulis aplikasi yang bekerja dengan format file mdb dan adp. Ini mengimpor / mengekspor semua objek database (termasuk tabel, referensi, relasi dan properti database) ke file teks biasa. Dengan file-file itu Anda dapat bekerja dengan kontrol versi sumber apa pun. Versi berikutnya akan memungkinkan impor kembali file teks biasa ke database. Akan ada juga alat baris perintah

Anda dapat mengunduh aplikasi atau kode sumber dari: http://accesssvn.codeplex.com/

salam

mnieto
sumber
Kami telah menggunakan ini selama hampir dua tahun sekarang dan itu bagus. Terima kasih!
mcfea
5

Menghidupkan kembali utas lama tapi ini bagus. Saya telah mengimplementasikan dua skrip (compose.vbs / decompose.vbs) untuk proyek saya sendiri dan mengalami masalah dengan file .mdb lama:

Itu terhenti ketika sampai ke formulir yang menyertakan kode:

NoSaveCTIWhenDisabled =1

Access mengatakan itu memiliki masalah dan itulah akhir ceritanya. Saya menjalankan beberapa tes dan bermain-main mencoba untuk mengatasi masalah ini dan menemukan utas ini dengan pekerjaan di akhir:

Tidak dapat membuat basis data

Pada dasarnya (seandainya utasnya mati), Anda mengambil .mdb dan melakukan "Simpan sebagai" ke format .accdb yang baru. Maka sumber yang aman atau menyusun / membusuk barang akan bekerja. Saya juga harus bermain-main selama 10 menit untuk mendapatkan sintaks baris perintah yang tepat untuk skrip penulisan (de) agar berfungsi dengan benar jadi inilah info itu juga:

Untuk menulis (misalkan barang Anda berada di C: \ SControl (buat sub folder bernama Sumber untuk menyimpan file yang diekstrak):

'(to extract for importing to source control)
cscript compose.vbs database.accdb     

'(to rebuild from extracted files saved from an earlier date)
cscript decompose.vbs database.accdb C:\SControl\Source\

Itu dia!

Versi Access di mana saya mengalami masalah di atas termasuk Access 2000-2003 ".mdb" database dan memperbaiki masalah dengan menyimpannya ke dalam format 2007-2010 ".accdb" sebelum menjalankan skrip penulisan / dekomposisi. Setelah konversi, skrip berfungsi dengan baik!

JKK
sumber
Bisakah Anda mengedit ini untuk memasukkan versi Access Anda di mana Anda mengalami masalah ini?
Nathan DeWitt
Tidak masalah, apakah Anda masih melakukan pengembangan akses Nathan? Jika ada yang berhasil mengintegrasikannya dengan kontrol versi?
JKK
Saya tidak melakukan pengembangan akses lagi. Saya punya satu proyek yang saya gunakan ini dalam perjalanan kembali ketika saya mengajukan pertanyaan, dan tidak pernah harus melakukan hal lain dengannya.
Nathan DeWitt
Keren, saya pikir sebagian besar bisnis menggunakan semacam server SQL khusus. Situasi saya sekarang ada campuran MS SQL Server, Oracle dan sekelompok Access database yang menarik data dari server ke tabel lokal dan ekspor ke excel. Campuran yang cukup rumit. Saya pikir saya akan memulai pertanyaan baru pada beberapa saran untuk menyiapkan proyek baru saya akan segera, melihat apa yang orang dapat menyarankan untuk mengurangi kompleksitas
JKK
4

Solusi hanya file teks (termasuk kueri, tabel, dan hubungan)

Saya telah mengubah pasangan skrip Oliver sehingga mereka mengekspor / mengimpor hubungan, tabel, dan kueri selain modul, kelas, formulir, dan makro. Semuanya disimpan dalam file plaintext, jadi tidak ada file database yang dibuat untuk disimpan dengan file teks dalam kontrol versi.

Ekspor ke file teks (decompose.vbs)

' Usage:
'  cscript decompose.vbs <input file> <path>

' Converts all modules, classes, forms and macros from an Access Project file (.adp) <input file> to
' text and saves the results in separate files to <path>.  Requires Microsoft Access.
Option Explicit

Const acForm = 2
Const acModule = 5
Const acMacro = 4
Const acReport = 3
Const acQuery = 1
Const acExportTable = 0

' BEGIN CODE
Dim fso, relDoc, ACCDBFilename, sExportpath
Set fso = CreateObject("Scripting.FileSystemObject")
Set relDoc = CreateObject("Microsoft.XMLDOM")

If (Wscript.Arguments.Count = 0) Then
    MsgBox "Please provide the .accdb database file", vbExclamation, "Error"
    Wscript.Quit()
End If
ACCDBFilename = fso.GetAbsolutePathName(Wscript.Arguments(0))

If (Wscript.Arguments.Count = 1) Then
 sExportpath = ""
Else
 sExportpath = Wscript.Arguments(1)
End If


exportModulesTxt ACCDBFilename, sExportpath

If (Err <> 0) And (Err.Description <> Null) Then
    MsgBox Err.Description, vbExclamation, "Error"
    Err.Clear
End If

Function exportModulesTxt(ACCDBFilename, sExportpath)
    Dim myComponent, sModuleType, sTempname, sOutstring
    Dim myType, myName, myPath, hasRelations
    myType = fso.GetExtensionName(ACCDBFilename)
    myName = fso.GetBaseName(ACCDBFilename)
    myPath = fso.GetParentFolderName(ACCDBFilename)

    'if no path was given as argument, use a relative directory
    If (sExportpath = "") Then
        sExportpath = myPath & "\Source"
    End If
    'On Error Resume Next
    fso.DeleteFolder (sExportpath)
    fso.CreateFolder (sExportpath)
    On Error GoTo 0

    Wscript.Echo "starting Access..."
    Dim oApplication
    Set oApplication = CreateObject("Access.Application")
    Wscript.Echo "Opening " & ACCDBFilename & " ..."
    If (Right(ACCDBFilename, 4) = ".adp") Then
     oApplication.OpenAccessProject ACCDBFilename
    Else
     oApplication.OpenCurrentDatabase ACCDBFilename
    End If
    oApplication.Visible = False

    Wscript.Echo "exporting..."
    Dim myObj
    For Each myObj In oApplication.CurrentProject.AllForms
        Wscript.Echo "Exporting FORM " & myObj.FullName
        oApplication.SaveAsText acForm, myObj.FullName, sExportpath & "\" & myObj.FullName & ".form.txt"
        oApplication.DoCmd.Close acForm, myObj.FullName
    Next
    For Each myObj In oApplication.CurrentProject.AllModules
        Wscript.Echo "Exporting MODULE " & myObj.FullName
        oApplication.SaveAsText acModule, myObj.FullName, sExportpath & "\" & myObj.FullName & ".module.txt"
    Next
    For Each myObj In oApplication.CurrentProject.AllMacros
        Wscript.Echo "Exporting MACRO " & myObj.FullName
        oApplication.SaveAsText acMacro, myObj.FullName, sExportpath & "\" & myObj.FullName & ".macro.txt"
    Next
    For Each myObj In oApplication.CurrentProject.AllReports
        Wscript.Echo "Exporting REPORT " & myObj.FullName
        oApplication.SaveAsText acReport, myObj.FullName, sExportpath & "\" & myObj.FullName & ".report.txt"
    Next
    For Each myObj In oApplication.CurrentDb.QueryDefs
        Wscript.Echo "Exporting QUERY " & myObj.Name
        oApplication.SaveAsText acQuery, myObj.Name, sExportpath & "\" & myObj.Name & ".query.txt"
    Next
    For Each myObj In oApplication.CurrentDb.TableDefs
     If Not Left(myObj.Name, 4) = "MSys" Then
      Wscript.Echo "Exporting TABLE " & myObj.Name
      oApplication.ExportXml acExportTable, myObj.Name, , sExportpath & "\" & myObj.Name & ".table.txt"
      'put the file path as a second parameter if you want to export the table data as well, instead of ommiting it and passing it into a third parameter for structure only
     End If
    Next

    hasRelations = False
    relDoc.appendChild relDoc.createElement("Relations")
    For Each myObj In oApplication.CurrentDb.Relations  'loop though all the relations
    If Not Left(myObj.Name, 4) = "MSys" Then
     Dim relName, relAttrib, relTable, relFoTable, fld
     hasRelations = True

     relDoc.ChildNodes(0).appendChild relDoc.createElement("Relation")
     Set relName = relDoc.createElement("Name")
     relName.Text = myObj.Name
     relDoc.ChildNodes(0).LastChild.appendChild relName

     Set relAttrib = relDoc.createElement("Attributes")
     relAttrib.Text = myObj.Attributes
     relDoc.ChildNodes(0).LastChild.appendChild relAttrib

     Set relTable = relDoc.createElement("Table")
     relTable.Text = myObj.Table
     relDoc.ChildNodes(0).LastChild.appendChild relTable

     Set relFoTable = relDoc.createElement("ForeignTable")
     relFoTable.Text = myObj.ForeignTable
     relDoc.ChildNodes(0).LastChild.appendChild relFoTable

     Wscript.Echo "Exporting relation " & myObj.Name & " between tables " & myObj.Table & " -> " & myObj.ForeignTable

     For Each fld In myObj.Fields   'in case the relationship works with more fields
      Dim lf, ff
      relDoc.ChildNodes(0).LastChild.appendChild relDoc.createElement("Field")

      Set lf = relDoc.createElement("Name")
      lf.Text = fld.Name
      relDoc.ChildNodes(0).LastChild.LastChild.appendChild lf

      Set ff = relDoc.createElement("ForeignName")
      ff.Text = fld.ForeignName
      relDoc.ChildNodes(0).LastChild.LastChild.appendChild ff

      Wscript.Echo "  Involving fields " & fld.Name & " -> " & fld.ForeignName
     Next
    End If
    Next
    If hasRelations Then
     relDoc.InsertBefore relDoc.createProcessingInstruction("xml", "version='1.0'"), relDoc.ChildNodes(0)
     relDoc.Save sExportpath & "\relations.rel.txt"
     Wscript.Echo "Relations successfuly saved in file relations.rel.txt"
    End If

    oApplication.CloseCurrentDatabase
    oApplication.Quit

End Function

Anda dapat menjalankan skrip ini dengan menelepon cscript decompose.vbs <path to file to decompose> <folder to store text files>. Jika Anda menghilangkan parameter kedua, itu akan membuat folder 'Sumber' tempat database berada. Harap perhatikan bahwa folder tujuan akan dihapus jika sudah ada.

Sertakan data dalam tabel yang diekspor

Ganti baris 93: oApplication.ExportXML acExportTable, myObj.Name, , sExportpath & "\" & myObj.Name & ".table.txt"

dengan garis oApplication.ExportXML acExportTable, myObj.Name, sExportpath & "\" & myObj.Name & ".table.txt"

Impor ke file Buat basis data (compose.vbs)

' Usage:
'  cscript compose.vbs <file> <path>

' Reads all modules, classes, forms, macros, queries, tables and their relationships in a directory created by "decompose.vbs"
' and composes then into an Access Database file (.accdb).
' Requires Microsoft Access.
Option Explicit

Const acForm = 2
Const acModule = 5
Const acMacro = 4
Const acReport = 3
Const acQuery = 1
Const acStructureOnly = 0   'change 0 to 1 if you want import StructureAndData instead of StructureOnly
Const acCmdCompileAndSaveAllModules = &H7E

Dim fso, relDoc, ACCDBFilename, sPath
Set fso = CreateObject("Scripting.FileSystemObject")
Set relDoc = CreateObject("Microsoft.XMLDOM")

If (Wscript.Arguments.Count = 0) Then
 MsgBox "Please provide the .accdb database file", vbExclamation, "Error"
 Wscript.Quit()
End If

ACCDBFilename = fso.GetAbsolutePathName(Wscript.Arguments(0))
If (Wscript.Arguments.Count = 1) Then
 sPath = ""
Else
 sPath = Wscript.Arguments(1)
End If


importModulesTxt ACCDBFilename, sPath

If (Err <> 0) And (Err.Description <> Null) Then
    MsgBox Err.Description, vbExclamation, "Error"
    Err.Clear
End If


Function importModulesTxt(ACCDBFilename, sImportpath)
    Dim myComponent, sModuleType, sTempname, sOutstring

    ' Build file and pathnames
    Dim myType, myName, myPath
    myType = fso.GetExtensionName(ACCDBFilename)
    myName = fso.GetBaseName(ACCDBFilename)
    myPath = fso.GetParentFolderName(ACCDBFilename)

    ' if no path was given as argument, use a relative directory
    If (sImportpath = "") Then
        sImportpath = myPath & "\Source\"
    End If

    ' check for existing file and ask to overwrite with the stub
    If fso.FileExists(ACCDBFilename) Then
     Wscript.StdOut.Write ACCDBFilename & " already exists. Overwrite? (y/n) "
     Dim sInput
     sInput = Wscript.StdIn.Read(1)
     If (sInput <> "y") Then
      Wscript.Quit
     Else
      If fso.FileExists(ACCDBFilename & ".bak") Then
       fso.DeleteFile (ACCDBFilename & ".bak")
      End If
      fso.MoveFile ACCDBFilename, ACCDBFilename & ".bak"
     End If
    End If

    Wscript.Echo "starting Access..."
    Dim oApplication
    Set oApplication = CreateObject("Access.Application")
    Wscript.Echo "Opening " & ACCDBFilename
    If (Right(ACCDBFilename, 4) = ".adp") Then
        oApplication.CreateAccessProject ACCDBFilename
    Else
        oApplication.NewCurrentDatabase ACCDBFilename
    End If
    oApplication.Visible = False

    Dim folder
    Set folder = fso.GetFolder(sImportpath)

    'load each file from the import path into the stub
    Dim myFile, objectname, objecttype
    For Each myFile In folder.Files
     objectname = fso.GetBaseName(myFile.Name)  'get rid of .txt extension
     objecttype = fso.GetExtensionName(objectname)
     objectname = fso.GetBaseName(objectname)

     Select Case objecttype
      Case "form"
       Wscript.Echo "Importing FORM from file " & myFile.Name
       oApplication.LoadFromText acForm, objectname, myFile.Path
      Case "module"
       Wscript.Echo "Importing MODULE from file " & myFile.Name
       oApplication.LoadFromText acModule, objectname, myFile.Path
      Case "macro"
       Wscript.Echo "Importing MACRO from file " & myFile.Name
       oApplication.LoadFromText acMacro, objectname, myFile.Path
      Case "report"
       Wscript.Echo "Importing REPORT from file " & myFile.Name
       oApplication.LoadFromText acReport, objectname, myFile.Path
      Case "query"
       Wscript.Echo "Importing QUERY from file " & myFile.Name
       oApplication.LoadFromText acQuery, objectname, myFile.Path
      Case "table"
       Wscript.Echo "Importing TABLE from file " & myFile.Name
       oApplication.ImportXml myFile.Path, acStructureOnly
      Case "rel"
       Wscript.Echo "Found RELATIONSHIPS file " & myFile.Name & " ... opening, it will be processed after everything else has been imported"
       relDoc.Load (myFile.Path)
     End Select
    Next

    If relDoc.readyState Then
     Wscript.Echo "Preparing to build table dependencies..."
     Dim xmlRel, xmlField, accessRel, relTable, relName, relFTable, relAttr, i
     For Each xmlRel In relDoc.SelectNodes("/Relations/Relation")   'loop through every Relation node inside .xml file
      relName = xmlRel.SelectSingleNode("Name").Text
      relTable = xmlRel.SelectSingleNode("Table").Text
      relFTable = xmlRel.SelectSingleNode("ForeignTable").Text
      relAttr = xmlRel.SelectSingleNode("Attributes").Text

      'remove any possible conflicting relations or indexes
      On Error Resume Next
      oApplication.CurrentDb.Relations.Delete (relName)
      oApplication.CurrentDb.TableDefs(relTable).Indexes.Delete (relName)
      oApplication.CurrentDb.TableDefs(relFTable).Indexes.Delete (relName)
      On Error GoTo 0

      Wscript.Echo "Creating relation " & relName & " between tables " & relTable & " -> " & relFTable
      Set accessRel = oApplication.CurrentDb.CreateRelation(relName, relTable, relFTable, relAttr)  'create the relationship object

      For Each xmlField In xmlRel.SelectNodes("Field")  'in case the relationship works with more fields
       accessRel.Fields.Append accessRel.CreateField(xmlField.SelectSingleNode("Name").Text)
       accessRel.Fields(xmlField.SelectSingleNode("Name").Text).ForeignName = xmlField.SelectSingleNode("ForeignName").Text
       Wscript.Echo "  Involving fields " & xmlField.SelectSingleNode("Name").Text & " -> " & xmlField.SelectSingleNode("ForeignName").Text
      Next

      oApplication.CurrentDb.Relations.Append accessRel 'append the newly created relationship to the database
      Wscript.Echo "  Relationship added"
     Next
    End If

    oApplication.RunCommand acCmdCompileAndSaveAllModules
    oApplication.Quit
End Function

Anda dapat menjalankan skrip ini dengan menelepon cscript compose.vbs <path to file which should be created> <folder with text files>. Jika Anda menghilangkan parameter kedua, itu akan melihat ke folder 'Sumber' di mana database harus dibuat.

Impor data dari file teks

Ganti baris 14: const acStructureOnly = 0dengan const acStructureOnly = 1. Ini hanya akan berfungsi jika Anda telah memasukkan data dalam tabel yang diekspor.

Hal-hal yang tidak tercakup

  1. Saya telah menguji ini hanya dengan file .accdb, jadi dengan hal lain mungkin ada beberapa bug.
  2. Pengaturan tidak diekspor, saya akan merekomendasikan membuat Makro yang akan menerapkan pengaturan pada awal database.
  3. Beberapa kueri yang tidak dikenal terkadang diekspor yang diawali dengan '~'. Saya tidak tahu apakah itu perlu.
  4. Nama objek MSAccess dapat berisi karakter yang tidak valid untuk nama file - skrip akan gagal saat mencoba menulisnya. Anda dapat menormalkan semua nama file , tetapi kemudian Anda tidak dapat mengimpornya kembali.

Salah satu sumber saya yang lain saat mengerjakan skrip ini adalah jawaban ini , yang membantu saya mencari cara untuk mengekspor hubungan.

Jakub M.
sumber
Ini sepertinya berhasil, Tapi tidak mengerti tabel yang ditautkan
Lord Darth Vader
2

Ada gotcha - VSS 6.0 hanya dapat menerima MDB menggunakan add-in di bawah sejumlah objek, yang mencakup semua tabel, kueri, modul, dan formulir lokal. Tidak tahu batas objek yang tepat.

Untuk membangun aplikasi prod lantai 10 tahun kami, yang sangat besar, kami terpaksa menggabungkan 3 atau 4 MDB terpisah dari SS menjadi satu MDB, yang mempersulit pembuatan otomatis hingga kami tidak membuang waktu untuk melakukannya.

Saya pikir saya akan mencoba skrip di atas untuk memuntahkan MDb ini ke SVN dan menyederhanakan build untuk semua orang.

ChuckB
sumber
2

Bagi mereka yang menggunakan Access 2010, SaveAsText bukan metode yang terlihat di Intellisense tetapi tampaknya metode yang valid, seperti yang disebutkan skrip Arvin Meyer yang berfungsi baik untuk saya.

Yang menarik, SaveAsAXL adalah baru untuk 2010 dan memiliki tanda tangan yang sama dengan SaveAsText, meskipun tampaknya itu hanya akan bekerja dengan database web, yang memerlukan SharePoint Server 2010.

Cory
sumber
SaveAsText juga tidak terlihat di A2003, kecuali Anda telah mengaktifkan anggota tersembunyi di Browser objek. Informasi bagus tentang SaveAsAXL.
David-W-Fenton
2

Kami memiliki masalah yang sama beberapa waktu lalu.

Percobaan pertama kami adalah alat pihak ketiga yang menawarkan proxy API SourceSafe untuk Subversion untuk digunakan dengan MS Access dan VB 6. Alat ini dapat ditemukan di sini .

Karena kami tidak puas dengan alat itu, kami beralih ke Visual SourceSafe dan VSS Acces Plugin.

Benjamin Brauer
sumber
2

Saya menggunakan Oasis-Svn http://dev2dev.de/

Saya hanya bisa mengatakan itu menyelamatkan saya setidaknya sekali. MDB saya tumbuh melebihi 2 GB dan itu mematahkannya. Saya bisa kembali ke versi lama dan mengimpor Formulir dan baru saja kehilangan satu atau dua hari kerja.

Friedrich
sumber
1

Saya menemukan alat ini di SourceForge: http://sourceforge.net/projects/avc/

Saya belum pernah menggunakannya, tapi ini mungkin permulaan untuk Anda. Mungkin ada beberapa alat pihak ke-3 lain yang terintegrasi dengan VSS atau SVN yang melakukan apa yang Anda butuhkan.

Secara pribadi saya hanya menyimpan file teks biasa untuk menyimpan perubahan log. Ketika saya melakukan MDB biner, saya menggunakan entri dalam log perubahan sebagai komentar komit saya.

Patrick Cuff
sumber
Punya tautan yang sebenarnya mengunduhnya? Apakah saya buta? Sepertinya saya tidak dapat menemukannya.
BIBD
sourceforge.net/project/showfiles.php?group_id=115226 Tidak Ada Paket File yang Didefinisikan. Yay.
Nathan DeWitt
1

Untuk kelengkapan ...

Selalu ada "Alat Visual Studio [TAHUN] untuk Sistem Microsoft Office" ( http://msdn.microsoft.com/en-us/vs2005/aa718673.aspx ) tetapi tampaknya membutuhkan VSS. Bagi saya VSS (kerusakan otomatis) lebih buruk daripada 347 poin simpanan saya di jaringan berbagi yang saya backup.

BIBD
sumber
1

Saya menggunakan Add-in Access 2003: Source Code Control . Ini bekerja dengan baik. Satu Masalah adalah karakter yang tidak valid seperti ":".

Saya masuk dan keluar. Secara internal Add-In melakukan hal yang sama dengan kode di sana, tetapi dengan lebih banyak dukungan alat. Saya dapat melihat apakah suatu objek diperiksa dan menyegarkan objek.

Musim panas
sumber
1

Jawaban dari Oliver sangat berhasil. Temukan versi lengkap saya di bawah ini yang menambahkan dukungan untuk kueri Access.

(silakan lihat jawaban dari Oliver untuk informasi lebih lanjut / penggunaan)

decompose.vbs:

' Usage:
'  CScript decompose.vbs <input file> <path>

' Converts all modules, classes, forms and macros from an Access Project file (.adp) <input file> to
' text and saves the results in separate files to <path>.  Requires Microsoft Access.
'
Option Explicit

const acForm = 2
const acModule = 5
const acMacro = 4
const acReport = 3
const acQuery = 1

' BEGIN CODE
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

dim sADPFilename
If (WScript.Arguments.Count = 0) then
    MsgBox "Bitte den Dateinamen angeben!", vbExclamation, "Error"
    Wscript.Quit()
End if
sADPFilename = fso.GetAbsolutePathName(WScript.Arguments(0))

Dim sExportpath
If (WScript.Arguments.Count = 1) then
    sExportpath = ""
else
    sExportpath = WScript.Arguments(1)
End If


exportModulesTxt sADPFilename, sExportpath

If (Err <> 0) and (Err.Description <> NULL) Then
    MsgBox Err.Description, vbExclamation, "Error"
    Err.Clear
End If

Function exportModulesTxt(sADPFilename, sExportpath)
    Dim myComponent
    Dim sModuleType
    Dim sTempname
    Dim sOutstring

    dim myType, myName, myPath, sStubADPFilename
    myType = fso.GetExtensionName(sADPFilename)
    myName = fso.GetBaseName(sADPFilename)
    myPath = fso.GetParentFolderName(sADPFilename)

    If (sExportpath = "") then
        sExportpath = myPath & "\Source\"
    End If
    sStubADPFilename = sExportpath & myName & "_stub." & myType

    WScript.Echo "copy stub to " & sStubADPFilename & "..."
    On Error Resume Next
        fso.CreateFolder(sExportpath)
    On Error Goto 0
    fso.CopyFile sADPFilename, sStubADPFilename

    WScript.Echo "starting Access..."
    Dim oApplication
    Set oApplication = CreateObject("Access.Application")
    WScript.Echo "opening " & sStubADPFilename & " ..."
    If (Right(sStubADPFilename,4) = ".adp") Then
        oApplication.OpenAccessProject sStubADPFilename
    Else
        oApplication.OpenCurrentDatabase sStubADPFilename
    End If

    oApplication.Visible = false

    dim dctDelete
    Set dctDelete = CreateObject("Scripting.Dictionary")
    WScript.Echo "exporting..."
    Dim myObj

    For Each myObj In oApplication.CurrentProject.AllForms
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acForm, myObj.fullname, sExportpath & "\" & myObj.fullname & ".form"
        oApplication.DoCmd.Close acForm, myObj.fullname
        dctDelete.Add "FO" & myObj.fullname, acForm
    Next
    For Each myObj In oApplication.CurrentProject.AllModules
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acModule, myObj.fullname, sExportpath & "\" & myObj.fullname & ".bas"
        dctDelete.Add "MO" & myObj.fullname, acModule
    Next
    For Each myObj In oApplication.CurrentProject.AllMacros
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acMacro, myObj.fullname, sExportpath & "\" & myObj.fullname & ".mac"
        dctDelete.Add "MA" & myObj.fullname, acMacro
    Next
    For Each myObj In oApplication.CurrentProject.AllReports
        WScript.Echo "  " & myObj.fullname
        oApplication.SaveAsText acReport, myObj.fullname, sExportpath & "\" & myObj.fullname & ".report"
        dctDelete.Add "RE" & myObj.fullname, acReport
    Next
    For Each myObj In oApplication.CurrentDb.QueryDefs
        if not left(myObj.name,3) = "~sq" then 'exclude queries defined by the forms. Already included in the form itself
            WScript.Echo "  " & myObj.name
            oApplication.SaveAsText acQuery, myObj.name, sExportpath & "\" & myObj.name & ".query"
            oApplication.DoCmd.Close acQuery, myObj.name
            dctDelete.Add "FO" & myObj.name, acQuery
        end if
    Next

    WScript.Echo "deleting..."
    dim sObjectname
    For Each sObjectname In dctDelete
        WScript.Echo "  " & Mid(sObjectname, 3)
        oApplication.DoCmd.DeleteObject dctDelete(sObjectname), Mid(sObjectname, 3)
    Next

    oApplication.CloseCurrentDatabase
    oApplication.CompactRepair sStubADPFilename, sStubADPFilename & "_"
    oApplication.Quit

    fso.CopyFile sStubADPFilename & "_", sStubADPFilename
    fso.DeleteFile sStubADPFilename & "_"


End Function

Public Function getErr()
    Dim strError
    strError = vbCrLf & "----------------------------------------------------------------------------------------------------------------------------------------" & vbCrLf & _
               "From " & Err.source & ":" & vbCrLf & _
               "    Description: " & Err.Description & vbCrLf & _
               "    Code: " & Err.Number & vbCrLf
    getErr = strError
End Function

compose.vbs:

' Usage:
'  WScript compose.vbs <file> <path>

' Converts all modules, classes, forms and macros in a directory created by "decompose.vbs"
' and composes then into an Access Project file (.adp). This overwrites any existing Modules with the
' same names without warning!!!
' Requires Microsoft Access.

Option Explicit

const acForm = 2
const acModule = 5
const acMacro = 4
const acReport = 3
const acQuery = 1

Const acCmdCompileAndSaveAllModules = &H7E

' BEGIN CODE
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

dim sADPFilename
If (WScript.Arguments.Count = 0) then
    MsgBox "Bitte den Dateinamen angeben!", vbExclamation, "Error"
    Wscript.Quit()
End if
sADPFilename = fso.GetAbsolutePathName(WScript.Arguments(0))

Dim sPath
If (WScript.Arguments.Count = 1) then
    sPath = ""
else
    sPath = WScript.Arguments(1)
End If


importModulesTxt sADPFilename, sPath

If (Err <> 0) and (Err.Description <> NULL) Then
    MsgBox Err.Description, vbExclamation, "Error"
    Err.Clear
End If

Function importModulesTxt(sADPFilename, sImportpath)
    Dim myComponent
    Dim sModuleType
    Dim sTempname
    Dim sOutstring

    ' Build file and pathnames
    dim myType, myName, myPath, sStubADPFilename
    myType = fso.GetExtensionName(sADPFilename)
    myName = fso.GetBaseName(sADPFilename)
    myPath = fso.GetParentFolderName(sADPFilename)

    ' if no path was given as argument, use a relative directory
    If (sImportpath = "") then
        sImportpath = myPath & "\Source\"
    End If
    sStubADPFilename = sImportpath & myName & "_stub." & myType

    ' check for existing file and ask to overwrite with the stub
    if (fso.FileExists(sADPFilename)) Then
        WScript.StdOut.Write sADPFilename & " existiert bereits. Überschreiben? (j/n) "
        dim sInput
        sInput = WScript.StdIn.Read(1)
        if (sInput <> "j") Then
            WScript.Quit
        end if

        fso.CopyFile sADPFilename, sADPFilename & ".bak"
    end if

    fso.CopyFile sStubADPFilename, sADPFilename

    ' launch MSAccess
    WScript.Echo "starting Access..."
    Dim oApplication
    Set oApplication = CreateObject("Access.Application")
    WScript.Echo "opening " & sADPFilename & " ..."
    If (Right(sStubADPFilename,4) = ".adp") Then
        oApplication.OpenAccessProject sADPFilename
    Else
        oApplication.OpenCurrentDatabase sADPFilename
    End If
    oApplication.Visible = false

    Dim folder
    Set folder = fso.GetFolder(sImportpath)

    ' load each file from the import path into the stub
    Dim myFile, objectname, objecttype
    for each myFile in folder.Files
        objecttype = fso.GetExtensionName(myFile.Name)
        objectname = fso.GetBaseName(myFile.Name)
        WScript.Echo "  " & objectname & " (" & objecttype & ")"

        if (objecttype = "form") then
            oApplication.LoadFromText acForm, objectname, myFile.Path
        elseif (objecttype = "bas") then
            oApplication.LoadFromText acModule, objectname, myFile.Path
        elseif (objecttype = "mac") then
            oApplication.LoadFromText acMacro, objectname, myFile.Path
        elseif (objecttype = "report") then
            oApplication.LoadFromText acReport, objectname, myFile.Path
        elseif (objecttype = "query") then
           oApplication.LoadFromText acQuery, objectname, myFile.Path
        end if

    next

    oApplication.RunCommand acCmdCompileAndSaveAllModules
    oApplication.Quit
End Function

Public Function getErr()
    Dim strError
    strError = vbCrLf & "----------------------------------------------------------------------------------------------------------------------------------------" & vbCrLf & _
               "From " & Err.source & ":" & vbCrLf & _
               "    Description: " & Err.Description & vbCrLf & _
               "    Code: " & Err.Number & vbCrLf
    getErr = strError
End Function
Daniel Hillebrand
sumber
0

Saya mencoba membantu berkontribusi untuk jawabannya dengan menambahkan opsi ekspor untuk Kueri dalam database akses. (Dengan banyak bantuan dari jawaban SO lainnya )

Dim def
Set stream = fso.CreateTextFile(sExportpath & "\" & myName & ".queries.txt")
  For Each def In oApplication.CurrentDb.QueryDefs

    WScript.Echo "  Exporting Queries to Text..."
    stream.WriteLine("Name: " & def.Name)
    stream.WriteLine(def.SQL)
    stream.writeline "--------------------------"
    stream.writeline " "

  Next
stream.Close

Belum dapat mengerjakan itu kembali ke fitur 'menulis', tetapi bukan itu yang saya perlukan untuk dilakukan saat ini.

Catatan: Saya juga menambahkan ".txt" ke masing-masing nama file yang diekspor di decompose.vbs sehingga kontrol sumber akan segera menunjukkan kepada saya file yang berbeda.

Semoga itu bisa membantu!


JBickford
sumber
0

Entri ini menjelaskan pendekatan yang sama sekali berbeda dari entri lainnya, dan mungkin bukan yang Anda cari. Jadi saya tidak akan tersinggung jika Anda mengabaikan ini. Tapi setidaknya itu adalah makanan untuk dipikirkan.

Dalam beberapa lingkungan pengembangan perangkat lunak komersial profesional, manajemen konfigurasi (CM) dari pengiriman perangkat lunak biasanya tidak dilakukan dalam aplikasi perangkat lunak itu sendiri atau proyek perangkat lunak itu sendiri. CM dikenakan pada produk akhir yang dapat dikirim, dengan menyimpan perangkat lunak dalam folder CM khusus, di mana file dan foldernya ditandai dengan identifikasi versi. Misalnya, Clearcase memungkinkan manajer data untuk "memeriksa" file perangkat lunak, menetapkannya sebagai "cabang", menetapkannya sebagai "gelembung", dan menerapkan "label". Ketika Anda ingin melihat dan mengunduh file, Anda harus mengonfigurasi "config spec" Anda untuk menunjuk ke versi yang Anda inginkan, kemudian masukkan ke dalam folder dan itu ada.

Hanya sebuah ide.

Bola VoliAddictSandiego
sumber
0

Bagi siapa pun yang terjebak dengan Access 97, saya tidak bisa mendapatkan jawaban lain untuk berfungsi. Menggunakan kombinasi jawaban Oliver dan DaveParillo yang luar biasa dan membuat beberapa modifikasi, saya dapat membuat skrip bekerja dengan database Access 97 kami. Ini juga sedikit lebih ramah pengguna karena menanyakan folder mana untuk meletakkan file.

AccessExport.vbs:

' Converts all modules, classes, forms and macros from an Access file (.mdb) <input file> to
' text and saves the results in separate files to <path>.  Requires Microsoft Access.
Option Explicit

Const acQuery = 1
Const acForm = 2
Const acModule = 5
Const acMacro = 4
Const acReport = 3
Const acCmdCompactDatabase = 4
Const TemporaryFolder = 2

Dim strMDBFileName : strMDBFileName = SelectDatabaseFile
Dim strExportPath : strExportPath = SelectExportFolder
CreateExportFolders(strExportPath)
Dim objProgressWindow
Dim strOverallProgress
CreateProgressWindow objProgressWindow
Dim strTempMDBFileName
CopyToTempDatabase strMDBFileName, strTempMDBFileName, strOverallProgress
Dim objAccess
Dim objDatabase
OpenAccessDatabase objAccess, objDatabase, strTempMDBFileName, strOverallProgress
ExportQueries objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress
ExportForms objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress
ExportReports objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress
ExportMacros objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress
ExportModules objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress
objAccess.CloseCurrentDatabase
objAccess.Quit
DeleteTempDatabase strTempMDBFileName, strOverallProgress
objProgressWindow.Quit
MsgBox "Successfully exported database."

Private Function SelectDatabaseFile()
    MsgBox "Please select the Access database to export."
    Dim objFileOpen : Set objFileOpen = CreateObject("SAFRCFileDlg.FileOpen")
    If objFileOpen.OpenFileOpenDlg Then
        SelectDatabaseFile = objFileOpen.FileName
    Else
        WScript.Quit()
    End If
End Function

Private Function SelectExportFolder()
    Dim objShell : Set objShell = CreateObject("Shell.Application")
    SelectExportFolder = objShell.BrowseForFolder(0, "Select folder to export the database to:", 0, "").self.path & "\"
End Function

Private Sub CreateExportFolders(strExportPath)
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    MsgBox "Existing folders from a previous Access export under " & strExportPath & " will be deleted!"
    If objFileSystem.FolderExists(strExportPath & "Queries\") Then
        objFileSystem.DeleteFolder strExportPath & "Queries", true
    End If
    objFileSystem.CreateFolder(strExportPath & "Queries\")
    If objFileSystem.FolderExists(strExportPath & "Forms\") Then
        objFileSystem.DeleteFolder strExportPath & "Forms", true
    End If
    objFileSystem.CreateFolder(strExportPath & "Forms\")
    If objFileSystem.FolderExists(strExportPath & "Reports\") Then
        objFileSystem.DeleteFolder strExportPath & "Reports", true
    End If
    objFileSystem.CreateFolder(strExportPath & "Reports\")
    If objFileSystem.FolderExists(strExportPath & "Macros\") Then
        objFileSystem.DeleteFolder strExportPath & "Macros", true
    End If
    objFileSystem.CreateFolder(strExportPath & "Macros\")
    If objFileSystem.FolderExists(strExportPath & "Modules\") Then
        objFileSystem.DeleteFolder strExportPath & "Modules", true
    End If
    objFileSystem.CreateFolder(strExportPath & "Modules\")
End Sub

Private Sub CreateProgressWindow(objProgressWindow)
    Set objProgressWindow = CreateObject ("InternetExplorer.Application")
    objProgressWindow.Navigate "about:blank"
    objProgressWindow.ToolBar = 0
    objProgressWindow.StatusBar = 0
    objProgressWindow.Width = 320
    objProgressWindow.Height = 240
    objProgressWindow.Visible = 1
    objProgressWindow.Document.Title = "Access export in progress"
End Sub

Private Sub CopyToTempDatabase(strMDBFileName, strTempMDBFileName, strOverallProgress)
    strOverallProgress = strOverallProgress & "Copying to temporary database...<br/>"
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    strTempMDBFileName = objFileSystem.GetSpecialFolder(TemporaryFolder) & "\" & objFileSystem.GetBaseName(strMDBFileName) & "_temp.mdb"
    objFileSystem.CopyFile strMDBFileName, strTempMDBFileName
End Sub

Private Sub OpenAccessDatabase(objAccess, objDatabase, strTempMDBFileName, strOverallProgress)
    strOverallProgress = strOverallProgress & "Compacting temporary database...<br/>"
    Set objAccess = CreateObject("Access.Application")
    objAccess.Visible = false
    CompactAccessDatabase objAccess, strTempMDBFileName
    strOverallProgress = strOverallProgress & "Opening temporary database...<br/>"
    objAccess.OpenCurrentDatabase strTempMDBFileName
    Set objDatabase = objAccess.CurrentDb
End Sub

' Sometimes the Compact Database command errors out, and it's not serious if the database isn't compacted first.
Private Sub CompactAccessDatabase(objAccess, strTempMDBFileName)
    On Error Resume Next
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    objAccess.DbEngine.CompactDatabase strTempMDBFileName, strTempMDBFileName & "_"
    objFileSystem.CopyFile strTempMDBFileName & "_", strTempMDBFileName
    objFileSystem.DeleteFile strTempMDBFileName & "_"
End Sub

Private Sub ExportQueries(objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Exporting Queries (Step 1 of 5)...<br/>"
    Dim counter
    For counter = 0 To objDatabase.QueryDefs.Count - 1
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter + 1 & " of " & objDatabase.QueryDefs.Count
        objAccess.SaveAsText acQuery, objDatabase.QueryDefs(counter).Name, strExportPath & "Queries\" & Clean(objDatabase.QueryDefs(counter).Name) & ".sql"
    Next
End Sub

Private Sub ExportForms(objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Exporting Forms (Step 2 of 5)...<br/>"
    Dim counter : counter = 1
    Dim objContainer : Set objContainer = objDatabase.Containers("Forms")
    Dim objDocument
    For Each objDocument In objContainer.Documents
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter & " of " & objContainer.Documents.Count
        counter = counter + 1
        objAccess.SaveAsText acForm, objDocument.Name, strExportPath & "Forms\" & Clean(objDocument.Name) & ".form"
        objAccess.DoCmd.Close acForm, objDocument.Name
    Next
End Sub

Private Sub ExportReports(objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Exporting Reports (Step 3 of 5)...<br/>"
    Dim counter : counter = 1
    Dim objContainer : Set objContainer = objDatabase.Containers("Reports")
    Dim objDocument
    For Each objDocument In objContainer.Documents
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter & " of " & objContainer.Documents.Count
        counter = counter + 1
        objAccess.SaveAsText acReport, objDocument.Name, strExportPath & "Reports\" & Clean(objDocument.Name) & ".report"
    Next
End Sub

Private Sub ExportMacros(objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Exporting Macros (Step 4 of 5)...<br/>"
    Dim counter : counter = 1
    Dim objContainer : Set objContainer = objDatabase.Containers("Scripts")
    Dim objDocument
    For Each objDocument In objContainer.Documents
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter & " of " & objContainer.Documents.Count
        counter = counter + 1
        objAccess.SaveAsText acMacro, objDocument.Name, strExportPath & "Macros\" & Clean(objDocument.Name) & ".macro"
    Next
End Sub

Private Sub ExportModules(objAccess, objDatabase, objProgressWindow, strExportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Exporting Modules (Step 5 of 5)...<br/>"
    Dim counter : counter = 1
    Dim objContainer : Set objContainer = objDatabase.Containers("Modules")
    Dim objDocument
    For Each objDocument In objContainer.Documents
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter & " of " & objContainer.Documents.Count
        counter = counter + 1
        objAccess.SaveAsText acModule, objDocument.Name, strExportPath & "Modules\" & Clean(objDocument.Name) & ".module"
    Next
End Sub

Private Sub DeleteTempDatabase(strTempMDBFileName, strOverallProgress)
    On Error Resume Next
    strOverallProgress = strOverallProgress & "Deleting temporary database...<br/>"
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    objFileSystem.DeleteFile strTempMDBFileName, true
End Sub

' Windows doesn't like certain characters, so we have to filter those out of the name when exporting
Private Function Clean(strInput)
    Dim objRegexp : Set objRegexp = New RegExp
    objRegexp.IgnoreCase = True
    objRegexp.Global = True
    objRegexp.Pattern = "[\\/:*?""<>|]"
    Dim strOutput
    If objRegexp.Test(strInput) Then
        strOutput = objRegexp.Replace(strInput, "")
        MsgBox strInput & " is being exported as " & strOutput
    Else
        strOutput = strInput
    End If
    Clean = strOutput
End Function

Dan untuk mengimpor file ke dalam basis data, Anda harus membuat ulang basis data dari awal atau Anda ingin memodifikasi file di luar Access karena suatu alasan.

AccessImport.vbs:

' Imports all of the queries, forms, reports, macros, and modules from text
' files to an Access file (.mdb).  Requires Microsoft Access.
Option Explicit

const acQuery = 1
const acForm = 2
const acModule = 5
const acMacro = 4
const acReport = 3
const acCmdCompileAndSaveAllModules = &H7E

Dim strMDBFilename : strMDBFilename = SelectDatabaseFile
CreateBackup strMDBFilename
Dim strImportPath : strImportPath = SelectImportFolder
Dim objAccess
Dim objDatabase
OpenAccessDatabase objAccess, objDatabase, strMDBFilename
Dim objProgressWindow
Dim strOverallProgress
CreateProgressWindow objProgressWindow
ImportQueries objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress
ImportForms objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress
ImportReports objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress
ImportMacros objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress
ImportModules objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress
objAccess.CloseCurrentDatabase
objAccess.Quit
objProgressWindow.Quit
MsgBox "Successfully imported objects into the database."

Private Function SelectDatabaseFile()
    MsgBox "Please select the Access database to import the objects from.  ALL EXISTING OBJECTS WITH THE SAME NAME WILL BE OVERWRITTEN!"
    Dim objFileOpen : Set objFileOpen = CreateObject( "SAFRCFileDlg.FileOpen" )
    If objFileOpen.OpenFileOpenDlg Then
        SelectDatabaseFile = objFileOpen.FileName
    Else
        WScript.Quit()
    End If
End Function

Private Function SelectImportFolder()
    Dim objShell : Set objShell = WScript.CreateObject("Shell.Application")
    SelectImportFolder = objShell.BrowseForFolder(0, "Select folder to import the database objects from:", 0, "").self.path & "\"
End Function

Private Sub CreateBackup(strMDBFilename)
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    objFileSystem.CopyFile strMDBFilename, strMDBFilename & ".bak"
End Sub

Private Sub OpenAccessDatabase(objAccess, objDatabase, strMDBFileName)
    Set objAccess = CreateObject("Access.Application")
    objAccess.OpenCurrentDatabase strMDBFilename
    objAccess.Visible = false
    Set objDatabase = objAccess.CurrentDb
End Sub

Private Sub CreateProgressWindow(ByRef objProgressWindow)
    Set objProgressWindow = CreateObject ("InternetExplorer.Application")
    objProgressWindow.Navigate "about:blank"
    objProgressWindow.ToolBar = 0
    objProgressWindow.StatusBar = 0
    objProgressWindow.Width = 320
    objProgressWindow.Height = 240
    objProgressWindow.Visible = 1
    objProgressWindow.Document.Title = "Access import in progress"
End Sub

Private Sub ImportQueries(objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress)
    strOverallProgress = "Importing Queries (Step 1 of 5)...<br/>"
    Dim counter : counter = 0
    Dim folder : Set folder = objFileSystem.GetFolder(strImportPath & "Queries\")
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    Dim file
    Dim strQueryName
    For Each file in folder.Files
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter + 1 & " of " & folder.Files.Count
        strQueryName = objFileSystem.GetBaseName(file.Name)
        objAccess.LoadFromText acQuery, strQueryName, file.Path
        counter = counter + 1
    Next
End Sub

Private Sub ImportForms(objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Importing Forms (Step 2 of 5)...<br/>"
    Dim counter : counter = 0
    Dim folder : Set folder = objFileSystem.GetFolder(strImportPath & "Forms\")
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    Dim file
    Dim strFormName
    For Each file in folder.Files
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter + 1 & " of " & folder.Files.Count
        strFormName = objFileSystem.GetBaseName(file.Name)
        objAccess.LoadFromText acForm, strFormName, file.Path
        counter = counter + 1
    Next
End Sub

Private Sub ImportReports(objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Importing Reports (Step 3 of 5)...<br/>"
    Dim counter : counter = 0
    Dim folder : Set folder = objFileSystem.GetFolder(strImportPath & "Reports\")
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    Dim file
    Dim strReportName
    For Each file in folder.Files
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter + 1 & " of " & folder.Files.Count
        strReportName = objFileSystem.GetBaseName(file.Name)
        objAccess.LoadFromText acReport, strReportName, file.Path
        counter = counter + 1
    Next
End Sub

Private Sub ImportMacros(objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Importing Macros (Step 4 of 5)...<br/>"
    Dim counter : counter = 0
    Dim folder : Set folder = objFileSystem.GetFolder(strImportPath & "Macros\")
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    Dim file
    Dim strMacroName
    For Each file in folder.Files
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter + 1 & " of " & folder.Files.Count
        strMacroName = objFileSystem.GetBaseName(file.Name)
        objAccess.LoadFromText acMacro, strMacroName, file.Path
        counter = counter + 1
    Next
End Sub

Private Sub ImportModules(objAccess, objDatabase, objProgressWindow, strImportPath, strOverallProgress)
    strOverallProgress = strOverallProgress & "Importing Modules (Step 5 of 5)...<br/>"
    Dim counter : counter = 0
    Dim folder : Set folder = objFileSystem.GetFolder(strImportPath & "Modules\")
    Dim objFileSystem : Set objFileSystem = CreateObject("Scripting.FileSystemObject")
    Dim file
    Dim strModuleName
    For Each file in folder.Files
        objProgressWindow.Document.Body.InnerHTML = strOverallProgress & counter + 1 & " of " & folder.Files.Count
        strModuleName = objFileSystem.GetBaseName(file.Name)
        objAccess.LoadFromText acModule, strModuleName, file.Path
        counter = counter + 1
    Next

    ' We need to compile the database whenever any module code changes.
    If Not objAccess.IsCompiled Then
        objAccess.RunCommand acCmdCompileAndSaveAllModules
    End If
End Sub
CTristan
sumber