如何在 Access 开发中使用版本控制?

2024-04-10

我参与更新 Access 解决方案。它有大量的 VBA、大量的查询、少量的表格以及一些用于数据输入和报告生成的表单。它是 Access 的理想候选者。

我想更改表设计、VBA、查询和表单。如何使用版本控制跟踪我的更改? (我们使用 Subversion,但这适用于任何风格)我可以将整个 mdb 保存在 subversion 中,但这将存储一个二进制文件,而且我无法知道我刚刚更改了一行 VBA 代码。

我考虑过将 VBA 代码复制到单独的文件中,然后保存它们,但我发现它们很快就与数据库中的内容不同步了。


我们用 VBScript 编写了自己的脚本,该脚本使用 Access 中未记录的 Application.SaveAsText() 来导出所有代码、表单、宏和报告模块。就在这里,它应该给你一些指导。 (注意:有些消息是德语的,但您可以轻松更改。)

EDIT: To summarize various comments below: Our Project assumes an .adp-file. In order to get this work with .mdb/.accdb, you have to change OpenAccessProject() to OpenCurrentDatabase(). (Updated to use OpenAccessProject() if it sees a .adp extension, else use OpenCurrentDatabase().)

分解.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

如果您需要可单击的命令,请使用以下命令创建一个名为“decompose.cmd”的文件,而不是使用命令行

cscript decompose.vbs youraccessapplication.adp

默认情况下,所有导出的文件都会进入 Access 应用程序的“Scripts”子文件夹中。 .adp/mdb 文件也被复制到此位置(带有“stub”后缀)并删除所有导出的模块,使其非常小。

您必须将此存根与源文件一起签入,因为大多数访问设置和自定义菜单栏无法以任何其他方式导出。如果您确实更改了某些设置或菜单,请务必仅提交对此文件的更改。

注意:如果您的应用程序中定义了任何 Autoexec-Makros,则在调用分解时可能必须按住 Shift 键,以防止它执行并干扰导出!

当然,还有反向脚本,从“源”目录构建应用程序:

撰写.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

同样,这与一个同伴“compose.cmd”一起包含:

cscript compose.vbs youraccessapplication.adp

它会要求您确认覆盖当前的应用程序,并首先创建备份(如果您这样做)。然后它收集源目录中的所有源文件并将它们重新插入到存根中。

玩得开心!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Access 开发中使用版本控制? 的相关文章

  • 使用 Git 维护项目

    我有 2 个项目 实际上这 2 个项目彼此大约 80 相同 主要区别在于语言和商业模式 一个是针对使用英语的更多受众 并且有 9 美元 月的商业模式 另一个是使用本地语言与免费增值商业模式 有时 当我想添加新的特性 功能时 我想将其添加到两
  • 访问:根据记录中的最新日期进行分组(嵌套查询)

    下表中的此查询 SELECT ID Value As of FROM Table a INNER JOIN SELECT ID MAX As of AS As of FROM Table GROUP BY ID b ON a ID b ID
  • 如何使用 git-svn 使 svn:external 保持最新?

    将我的存储库视为 SVN 存储库 我得到 svn co http myrepo foo trunk foo foo bar baz gt http myrepo baz trunk 将其视为 Git 存储库 我得到 git svn clon
  • 根据代码版本测试和管理数据库版本

    当您开发应用程序时 数据库的更改不可避免地会出现 我发现的技巧是让数据库构建与代码保持同步 过去 我添加了一个针对目标数据库执行 SQL 脚本的构建步骤 但这很危险 因为您可能会无意中添加虚假数据或更糟的情况 我的问题是保持数据库与代码同步
  • 二进制增量存储

    我正在寻找一种二进制增量存储解决方案来版本化大型二进制文件 数字音频工作站文件 使用 DAW 文件时 与用于存储原始数据 波形 的大量数据相比 大多数更改 尤其是在混音结束时 都非常小 如果我们的 DAW 文件有一个版本控制系统 让我们可以
  • 使用 .NET SDK / C# 在 StarTeam 中查找文件的过去修订版本

    我正在尝试编写一个 C 程序来比较 StarTeam 存储库中不同版本的文件 查看文件的当前版本与给定的先前签入之间是否有任何更改 我目前能够从当前版本中查找 签出文件 但很难找到正确的方法来查找这些文件的过去版本 至少在 NET 方面 B
  • 更改索引设置访问 VBA

    我正在尝试自动化 Access 中的流程 我希望自动化的步骤之一是更改表中某些字段的索引设置 我需要这样做来提高后续查询的速度 使用索引查询速度大约快 100 倍 无论如何 假设我的表名为 Cars 如下所示 ID Name Charact
  • MS-Access 查询中的语法错误(缺少运算符)

    以下查询给了我 missing operator 语法错误 所需的输出是表中数据的组合 dbo tbl 和意见 vw 我用过的所有钥匙都存在 有任何想法吗 SELECT dbo tbl BOD fpartno AS PartNumber d
  • “Git 推送非快进更新被拒绝”是什么意思?

    我正在使用 Git 来管理我的两台计算机和我的开发 我尝试将更改提交到 GitHub 但收到此错误 无法将一些参考推送到
  • MS Access VBA:通过 Outlook 发送电子邮件 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何使用 MS Access VBA 通过帐户发送电子邮件 我知道这个问题很模糊 但是很难在网上找到在某种程度上还没有过时的相关信息 编辑
  • 参数太少错误,同时未使用参数占位符

    我尝试使用 PYODBC 在 Access 数据库中执行 SQL 查询 但出现以下错误 pyodbc Error 07002 07002 Microsoft ODBC Microsoft Access 驱动程序 参数太少 预期为 1 301
  • 使用 GIT 自动增加 AssemblyFileVersion

    好吧 我知道这可能不是传统的 但除此之外 我使用 AssemblyFileVersion 作为我的 构建名称 字符串 它的格式如下 File Version information for an assembly consists of t
  • 在两个单独的分支或存储库中管理项目后端和前端?

    我启动了一个移动应用程序项目 该项目将具有服务器端和应用程序本身 所以 在master分支我创建了2个项目myapp server and myapp然后我创建了另外 2 个分支backend and frontend我只想将与它们相对应的
  • 有没有办法调用 VBA(MS Access 2002 或 2003)中任何控件的 BeforeUpdate 事件过程?

    在 VBA 中 我正在更改 Access 表单中的一些控件的值 我喜欢在执行此操作后运行这些控件的 BeforeUpdate 事件 因为它会检查字段之间的一致性 Private Sub ExampleProc1 Dim intCancel
  • git 可以与 Xcode 集成吗?

    有没有办法将 git 存储库与 Xcode 内置的 SCM 功能一起使用 Xcode 4 原生支持 git WWDC 2010 上的开发者工具国情咨文演讲 在这里了解更多 Xcode 4 中的新增功能 http developer appl
  • Git:如何变基到特定提交?

    我想变基到特定的提交 而不是另一个分支的 HEAD A B C master D topic to A B C master D topic 代替 A B C master D topic 我怎样才能做到这一点 您可以通过在您喜欢的提交上创
  • 为什么版本控制系统缺乏 Visual Source Safe 的共享功能?您使用并认为哪些源代码控制值得尝试?

    我们正在寻找一种版本控制系统来改变我们当前的源安全系统 我们将它与 Visual Studio 一起使用 到目前为止 我们已经失败了 主要原因是我们看到的所有替代方案都不支持 VSS 的一项或多项功能 尤其是我们广泛使用的一项 文件共享 那
  • Git 到 TFS 源代码管理迁移

    我想看看 TFS 如何为我的命令工作 所以我想将我们当前的 GIT 存储库移动到 TFS 数据库 我们使用 GIT 来获得普遍的分支支持 因此我想使用 TFS 2010 来解决该问题 现在的问题是 如何将 GIT 存储库导出到 TFS 显然
  • 使用 VBA 通过 Access 导航网页/操作 IE

    你好 StackOverflow 社区 我有一个关于使用 Access VBA 操作 IE 的问题 本质上 我正在尝试编写代码 使用 IE 打开特定网页 在该页面中搜索特定链接 目标链接的名称将取决于用户的情况 通过以编程方式单击该链接导航
  • 如何提取 Mercurial 中变更集的所有已更改文件?

    直到最近 我们一直在网络工作室的所有项目中使用 SVN 并且 Subversive 和 TortoiseSVN 等多个客户端中存在一个非常方便的功能 可以提取在某个版本中更改的所有文件 Mercurial 有没有办法做到这一点 我不在乎它是

随机推荐

  • 当存储状态更改时,React 组件不会更新

    下面是我的组件类 该组件似乎永远不会执行 componentWillUpdate 即使我可以在 mapStateToProps 返回之前通过日志记录看到状态更新 状态 100 发生变化 但组件不刷新 import React Compone
  • 从 cellRendererFramework 向父级发出事件

    使用 ag grid 您可以定义您的GridOptions columnDefs列信息包括cellRendererFramework 我有一个正在使用的组件cellRendererFramework其中包括通过单击其模板中的按钮触发的事件
  • 如何将HAR文件导入Excel

    我必须知道有关浏览器 例如 chrome 加载的文档的一些信息 因为检查元素是不错的选择 现在我必须将数据导入到 Excel 中 检查元素允许将数据保存为 har http 存档 文件 如何将网络信息从检查元素保存到 Excel 我的浏览器
  • 根据 Swift 中的 UILabel 文本调整 UIView 高度

    所以我有一个简单的UIView with a UILabel包含在其中 目前 高度UIView是硬编码的 当UILabel文本足够长 内容需要比文本更高的高度UIView提供 有没有一个简单的方法来计算合适的高度UIView为了显示包含的所
  • Django 3.x 错误:“mysql.connector.django”不是可用的数据库后端

    最近将 Django 项目从 2 x 升级到 3 x 我注意到mysql connector django后端 来自mysql connector python 不再有效 它使用的 Django 的最后一个版本是 2 2 11 3 0 就打
  • C++ 中独立于平台的 GUID 生成?

    在 C 中以编程方式生成 GUID 或 UUID 而不依赖于特定于平台的工具的最佳方法是什么 我正在尝试为模拟中的对象创建唯一标识符 但不能依赖 Microsoft 的实现 因为该项目是跨平台的 Notes 由于这是针对模拟器的 所以我 并
  • 存储/访问有向图的最佳方式

    我有大约 3500 个防洪设施 我想将它们表示为一个网络来确定水流路径 本质上是一个有向图 我目前正在使用 SqlServer 和 CTE 递归地检查所有节点及其上游组件 只要上游路径没有大量分叉 这就可以工作 然而 由于增加了上游的复杂性
  • Spring Data JPA更新方法

    我仍在寻找 Spring Data JPA 中的更新方法来更新给定的Object保存在关系数据库中 我只找到了一些解决方案 其中我被迫通过 Query 注释指定某种 UPDATE 查询 与 Modifying 相比 例如 Modifying
  • CodeIgniter SMTP 电子邮件消息 - 用等号替换字符

    我正在使用 CodeIgniter 电子邮件库通过我们的 Exchange 服务器发送电子邮件 我遇到的问题是电子邮件的内容变得混乱 有一些单词被等号 替换 我尝试了 2 个不同的 Exchange 服务器 它们位于不同的位置并且没有任何关
  • anaconda 中使用的 Gcc 版本的 python

    如何更改 anaconda 或虚拟环境中使用的 python gcc 版本 现在当我启动 python 时它显示 GCC 4 4 7 20120313 Red Hat 4 4 7 1 在linux2上 这与系统范围内的相同gcc in us
  • 我的问题是关于 R 的:如何对 R 中表中的每个重复进行编号?

    在我的数据集中 它们是全名列 例如 下面 我想在它旁边添加另一列 提及名称是否使用 R 出现了两次一 二 三 四 次 输出应类似于下面的列 重复次数 例如 数据集名称 People Full name Number of repetitio
  • 如何捕获并打印未知类型的异常

    我有一些程序 每次运行它时 它都会引发异常 我不知道如何检查它到底抛出了什么 所以我的问题是 是否可以捕获异常并打印它 如果它源自std exception你可以通过参考捕捉 try code that could cause except
  • 如何将 FFmpeg 命令行转换为 ffmpeg-python 代码?

    我有这个命令行代码 ffmpeg i 0 mp4 c v libx265 preset fast crf 28 tag v hvc1 c a aac bitexact map metadata 1 out mkv 我想将其转换为Python
  • 在同一个ipa中支持armv6和armv7

    我有一个 XCode 项目 配置如下 项目格式 XCode 3 1 兼容 架构 标准 armv6 armv7 基础 SDK 最新 iOS 当前设置为 iOS 4 2 仅构建活动架构 未选中 有效架构 armv6 armv7 我的问题 生成的
  • 如何在selenium中获取和设置文本编辑器值

    我的网页上有文本编辑器 我需要使用 c 中的 selenium 脚本填充其值 我知道如何为文本框执行此操作 我已经检查了流程在文本框中设置值 https stackoverflow com questions 10557196 using
  • 如何隐藏 optgroup/option 元素?

    有没有办法隐藏option or optgroupHTML 元素 我试过打电话hide 在 jQuery 中 也使用常规 Javascript 来设置style display none 它可以在 Firefox 中运行 但不能在任何其他浏
  • 带有 REST API 的 Ruby on Rails

    我对 Ruby on Rails 很陌生 虽然我喜欢所提供的组织和标准 但我对如何让 Rails 在这种特定情况下为我工作感到有点困惑 我有一个 Web 服务 我想将其与 Rails 应用程序一起使用 直接连接到数据库会很好 并且可以立即为
  • GXT 3.x EditorGrid:逐个单元选择单元格编辑器类型

    无论如何 是否可以逐个单元地定义编辑器类型GXT 3 0 我需要创建一个转置表 列变成行 行变成列 在这种情况下 一列 从普通表的角度来看 将具有不同的编辑器类型 而行将具有相同的编辑器类型 我正在尝试使用以下方法 它似乎工作正常 并允许根
  • 使输入类型=“密码”在移动设备上使用数字键盘

    在我为移动设备设计的网站上 我有一个用于 PIN 码的输入字段 我希望在输入文本时隐藏文本 并且希望当移动设备上的用户想要输入 PIN 码时弹出数字键盘 当类型 数字 时 数字键盘会弹出 但当类型 密码 时 数字键盘不会弹出 并且我无法 或
  • 如何在 Access 开发中使用版本控制?

    我参与更新 Access 解决方案 它有大量的 VBA 大量的查询 少量的表格以及一些用于数据输入和报告生成的表单 它是 Access 的理想候选者 我想更改表设计 VBA 查询和表单 如何使用版本控制跟踪我的更改 我们使用 Subvers