Access 솔루션 업데이트와 관련이 있습니다. VBA, 쿼리 수, 테이블 수가 적으며 데이터 입력 및 보고서 생성을위한 몇 가지 양식이 있습니다. Access의 이상적인 후보입니다.
테이블 디자인, VBA, 쿼리 및 폼을 변경하고 싶습니다. 버전 관리로 변경 사항을 추적하려면 어떻게해야합니까? (우리는 Subversion을 사용하지만 맛이 나옵니다.) 나는 전체 mdb를 subversion에 붙일 수 있지만 바이너리 파일을 저장할 것이므로 VBA 코드의 한 줄만 변경했다고 말할 수는 없습니다.
VBA 코드를 별도의 파일로 복사하여 저장하는 방법에 대해 생각했지만 데이터베이스의 내용과 빠르게 동기화되지 않는 사람들을 볼 수있었습니다.
답변
Access에서 문서화되지 않은 Application.SaveAsText ()를 사용하여 모든 코드, 양식, 매크로 및 보고서 모듈을 내보내는 VBScript로 자체 스크립트를 작성했습니다. 여기, 그것은 당신에게 몇 가지 포인터를 제공해야합니다. (주의 : 일부 메시지는 독일어로되어 있지만 쉽게 변경할 수 있습니다.)
편집 : 아래에 다양한 의견을 요약하면 다음과 같습니다.
우리 프로젝트는 .adp 파일을 가정합니다. .mdb / .accdb로이 작업을 수행하려면 OpenAccessProject ()를 OpenCurrentDatabase ()로 변경해야합니다.. ( OpenAccessProject()
확장자가 .adp 인 경우 사용하도록 업데이트하고 그렇지 않으면를 사용하십시오 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
명령 행을 사용하는 대신 클릭 가능한 명령이 필요한 경우 “decompose.cmd”라는 파일을 작성하십시오.
cscript decompose.vbs youraccessapplication.adp
기본적으로 내 보낸 모든 파일은 Access 응용 프로그램의 “스크립트”하위 폴더로 이동합니다. .adp / mdb 파일도이 위치 ( “접미사”접미사)에 복사되고 내 보낸 모든 모듈을 제거하여 실제로 작게 만듭니다.
대부분의 액세스 설정 및 사용자 정의 메뉴 표시 줄을 다른 방식으로 내보낼 수 없으므로 소스 파일로이 스텁을 체크인해야합니다. 설정이나 메뉴를 실제로 변경 한 경우에만이 파일에 대한 변경 사항을 커밋하십시오.
참고 : 응용 프로그램에 Autoexec-Makros가 정의되어 있으면 분해를 호출 할 때 Shift 키를 누르고 있어야 내보내기가 실행 및 방해되지 않습니다!
물론 “소스”-디렉토리에서 애플리케이션을 빌드하기위한 리버스 스크립트도 있습니다.
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
다시, 이것은 다음을 포함하는 컴패니언 “compose.cmd”와 함께 제공됩니다.
cscript compose.vbs youraccessapplication.adp
현재 응용 프로그램 덮어 쓰기를 확인하고 먼저 백업을 만듭니다. 그런 다음 Source-Directory에서 모든 소스 파일을 수집하여 스텁에 다시 삽입합니다.
즐기세요!
답변
Access에서 상당히 유용한 것으로 보입니다.
msdn 의이 링크 는 Microsoft Access 용 소스 제어 추가 기능을 설치하는 방법을 설명합니다. 이것은 Access 2007 용 Access Developer Extensions의 일부로 그리고 Access 2003 용으로 별도의 무료 추가 기능으로 무료 다운로드로 제공됩니다.
이 질문을하게되어 기쁩니다.이 기능을 원하기 때문에 시간을 내서 살펴 보았습니다. 위의 링크에는 이에 대한 자세한 정보가 있으며 추가 기능에 대한 링크가 있습니다.
업데이트 :
Access 2003 용 추가 기능을 설치했습니다. VSS에서만 작동하지만 Access 개체 (양식, 쿼리, 테이블, 모듈 등)를 리포지토리에 넣을 수 있습니다. 저장소에서 항목을 편집하면 체크 아웃하라는 메시지가 표시되지만 반드시 그럴 필요는 없습니다. 다음으로 애드 인이없는 시스템에서 어떻게 열고 열고 처리하는지 확인하겠습니다. 나는 VSS의 팬은 아니지만 액세스 객체를 저장소에 저장하는 것을 좋아합니다.
업데이트 2 :
추가 기능이없는 컴퓨터는 데이터베이스 구조 (테이블 필드 추가, 쿼리 매개 변수 등)를 변경할 수 없습니다. 처음에는 Access에 추가 기능이없는 경우 소스 제어에서 Access 데이터베이스를 제거 할 수있는 방법이 없었기 때문에 누군가 필요할 경우 이것이 문제가 될 수 있다고 생각했습니다.
“소형 및 복구”데이터베이스를 실행하면 소스 제어에서 데이터베이스를 제거 할 것인지 묻는 메시지가 표시됩니다. 예를 선택하고 추가 기능없이 데이터베이스를 편집 할 수있었습니다. 위 의 링크 에있는 기사는 Team System을 사용하도록 Access 2003 및 2007을 설정하는 지침도 제공합니다. SVN에 대한 MSSCCI 공급자를 찾을 수 있으면 해당 기능을 사용할 수 있습니다.
답변
Oliver가 게시 한 작성 / 분해 솔루션은 훌륭하지만 몇 가지 문제가 있습니다.
- 파일은 UCS-2 (UTF-16)로 인코딩되어 버전 제어 시스템 / 도구에서 파일을 이진 파일로 간주 할 수 있습니다.
- 파일에는 체크섬, 프린터 정보 등 자주 바뀌는 많은 부스러기가 있습니다. 깨끗한 diff를 원하거나 프로젝트에 협력해야하는 경우 심각한 문제입니다.
나는 이것을 직접 고치려고했지만 GitHub의 timabell / msaccess-vcs-integration 이라는 좋은 솔루션이 이미 있음을 발견했습니다 . msaccess-vcs-integration을 테스트했으며 훌륭하게 작동합니다.
2015 년 3 월 3 일 업데이트 : 프로젝트는 원래 Github의 bkidwell이 유지 관리 / 소유했지만 timabell 으로 전송 되었습니다. 위 링크는 프로젝트에 따라 업데이트됩니다. 예를 들어 bkidwell에 의해 원래의 프로젝트에서 일부 포크,있다 ArminBra로 하고 matonb에 의해 AFAICT는 사용할 수 없습니다.
Olivers의 분해 솔루션과 비교하여 msaccess-vcs-integration 사용의 단점 :
- 상당히 느립니다. 속도 문제를 해결할 수 있다고 확신하지만 프로젝트를 텍스트로 내보낼 필요는 없습니다 …
- 내 보낸 항목이 제거 된 스텁 액세스 프로젝트를 작성하지 않습니다. 이것은 (분해 스크립트의 코드를 채택하여) 고칠 수도 있지만 다시는 중요하지 않습니다.
어쨌든, 명확한 권장 사항은 msaccess-vcs-integration입니다. 내 보낸 파일에서 Git을 사용할 때의 모든 문제를 해결했습니다.
답변
올리버는 암석에 대답하지만 CurrentProject
참조는 저에게 효과적 이지 않았습니다. Arvin Meyer 의 비슷한 솔루션을 기반으로 수출 중에서 용기를 추출하고 이것을 대체했습니다 . adp 대신 mdb를 사용하는 경우 쿼리를 내보내는 이점이 있습니다.
' 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
답변
우리는 다음과 같은 자체 내부 도구를 개발했습니다.
- 모듈 : txt 파일로 내 보낸 다음 “파일 비교 도구”(프리웨어)와 비교
- 양식 : undocument application.saveAsText 명령을 통해 내 보냅니다. 그러면 두 가지 버전 ( “파일 비교 도구”)의 차이점을 다시 볼 수 있습니다.
- 매크로 : 주 VBA 프로 시저를 시작하는 한 줄의 “autoexec”매크로 만 있으므로 비교할 매크로가 없습니다.
- 쿼리 : 테이블에 저장된 텍스트 문자열입니다.
- 테이블 : 우리는 레코드와 테이블 구조의 차이점을 나열하여 자체 테이블 비교기를 작성했습니다.
전체 시스템은 txt 파일 (모듈 및 undocument application.loadFromText 명령으로 다시 작성되는 양식) 및 mdb 파일 (테이블)에서 자동으로 생성되는 Access 응용 프로그램의 “런타임”버전을 생성 할 수있을 정도로 똑똑합니다.
이상하게 들릴지 모르지만 작동합니다.
답변
이 게시물의 아이디어와 일부 블로그의 유사한 항목을 기반으로 mdb 및 adp 파일 형식으로 작동하는 응용 프로그램을 작성했습니다. 모든 데이터베이스 개체 (테이블, 참조, 관계 및 데이터베이스 속성 포함)를 일반 텍스트 파일로 가져 오거나 내 보냅니다. 이러한 파일을 사용하면 모든 소스 버전 제어로 작업 할 수 있습니다. 다음 버전에서는 일반 텍스트 파일을 데이터베이스로 다시 가져올 수 있습니다. 명령 줄 도구도 있습니다
http://accesssvn.codeplex.com/ 에서 애플리케이션 또는 소스 코드를 다운로드 할 수 있습니다.
문안 인사
답변
오래된 실을 부활 시키지만 이것은 좋은 것입니다. 내 프로젝트에 대해 두 개의 스크립트 (compose.vbs / decompose.vbs)를 구현했으며 이전 .mdb 파일에 문제가 발생했습니다.
코드가 포함 된 양식에 도달하면 중단됩니다.
NoSaveCTIWhenDisabled =1
Access는 문제가 있으며 이것이 이야기의 끝이라고 말합니다. 나는 몇 가지 테스트를 실행 하고이 문제를 해결하려고 노력했으며 끝에이 문제를 해결 한이 스레드를 발견했습니다.
기본적으로 (스레드가 중단 된 경우) .mdb를 사용하여 새 .accdb 형식으로 “다른 이름으로 저장”을 수행합니다. 그러면 소스 안전 또는 작성 / 분해 항목이 작동합니다. 또한 (de) 구성 스크립트가 올바르게 작동하도록 올바른 명령 줄 구문을 얻으려면 10 분 동안 놀아야했습니다. 그래서 그 정보도 있습니다.
작성하려면 (귀하의 항목이 C : \ SControl에 있습니다 (추출 된 파일을 저장할 Source라는 하위 폴더를 작성하십시오) :
'(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\
그게 다야!
위의 문제가 발생한 Access 버전에는 Access 2000-2003 “.mdb”데이터베이스가 포함되어 있으며 작성 / 분해 스크립트를 실행하기 전에 2007-2010 “.accdb”형식으로 저장하여 문제를 해결했습니다. 변환 후 스크립트는 정상적으로 작동합니다!