MSOffice小知识:Access数据库的生成、修理压缩和版本转换

Author:水如烟

在前面的基本框架中给出了代码下载。到现在,其中一些文件需要修改,主要的是考虑了远程对象的使用,就是CreateObject(Application,Server),加了Server。只是,现在给出的代码还是只是支持本地的。

修改后的有关文件如下:
ApplicationBase.vb

Option   Strict   Off
Namespace  uOffice
    
Public   MustInherit   Class  ApplicationBase
        
Implements  IDisposable

        
Friend  gOfficeApplication  As  ApplicationEnum
        
Protected  gApplicationObject  As   Object

        
Private  gBeforeProcessStartTime  As   Date
        
Private  gAfterProcessStartTime  As   Date

        
Private  gServer  As   String   =   ""

        
Friend   Sub  CreateInstance( ByVal  officeApplication  As  ApplicationEnum,  ByVal  server  As   String )
            gOfficeApplication 
=  officeApplication
            gServer 
=  server
            CreateInstance()
        
End Sub

        
Private   Sub  CreateInstance()
            
' 保留原有配置
            SaveDefaultPropertiesWhenApplicationInitialize()

            
' 取实例前时间
            gBeforeProcessStartTime  =  Now

            
' 实例
             Select   Case  gOfficeApplication
                
Case  ApplicationEnum.Access
                    gApplicationObject 
=   CreateObject (SR.GetString( " Office_Application_Access " ), gServer)
                
Case  ApplicationEnum.Excel
                    gApplicationObject 
=   CreateObject (SR.GetString( " Office_Application_Excel " ), gServer)
                
Case  ApplicationEnum.Word
                    gApplicationObject 
=   CreateObject (SR.GetString( " Office_Application_Word " ), gServer)
            
End   Select

            
' 取实例后时间
            gAfterProcessStartTime  =  Now
        
End Sub

        
' '' <summary>
         ' '' 退出主进程
         ' '' </summary>
         Public   Sub  Quit()
            
' 置回默认设置,如Excel.DisplayAlerts = True
            ResetDefaultPropertiesBeforeApplicationRelease()

            
' 释放其它对象,如Excel.Worksheets
            RealseInternalComObjectsBeforeApplicationRelease()

            
' 释放主进程,如Excel
            Application_Quit()

            
' 保证完全退出
             Try
                ApplicationRelease()
            
Catch  ex  As  Exception
            
End   Try
        
End Sub

        
' '' <summary>
         ' '' 退出其它Com对象
         ' '' </summary>
         Protected   MustOverride   Sub  RealseInternalComObjectsBeforeApplicationRelease()

        
Protected   Overridable   Sub  Application_Quit()
            gApplicationObject.Quit()
        
End Sub

        
' '' <summary>
         ' '' 退出OfficeApplication进程
         ' '' </summary>
         Private   Sub  ApplicationRelease()
            ComObjReleaseMethod.ReleaseComObject(gApplicationObject)
            
Select   Case  gOfficeApplication
                
Case  ApplicationEnum.Access
                    ComObjReleaseMethod.KillProcess(SR.GetString(
" Office_ProcessName_Access " ), gBeforeProcessStartTime, gAfterProcessStartTime, gServer)
                
Case  ApplicationEnum.Excel
                    ComObjReleaseMethod.KillProcess(SR.GetString(
" Office_ProcessName_Excel " ), gBeforeProcessStartTime, gAfterProcessStartTime, gServer)
                
Case  ApplicationEnum.Word
                    ComObjReleaseMethod.KillProcess(SR.GetString(
" Office_ProcessName_Word " ), gBeforeProcessStartTime, gAfterProcessStartTime, gServer)
            
End   Select
        
End Sub

        
' '' <summary>
         ' '' 保存默认设置
         ' '' </summary>
         Protected   MustOverride   Sub  SaveDefaultPropertiesWhenApplicationInitialize()

        
' '' <summary>
         ' '' 置回默认设置
         ' '' </summary>
         Protected   MustOverride   Sub  ResetDefaultPropertiesBeforeApplicationRelease()

        
' ///以下为实现IDisposable接口IDE自动创建的代码
         Private  disposedValue  As   Boolean   =   False          '  To detect redundant calls

        
'  IDisposable
         Protected   Overridable   Sub  Dispose( ByVal  disposing  As   Boolean )
            
If   Not   Me .disposedValue  Then
                
If  disposing  Then
                    
'  TODO: free unmanaged resources when explicitly called
                    Quit()
                
End   If

                
'  TODO: free shared unmanaged resources
             End   If
            
Me .disposedValue  =   True
        
End Sub

#Region  " IDisposable Support "
        
'  This code added by Visual Basic to correctly implement the disposable pattern.
         Public   Sub  Dispose()  Implements  IDisposable.Dispose
            
'  Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose( True )
            GC.SuppressFinalize(
Me )
        
End Sub
#End Region

    
End Class
End Namespace

ApplicationBaseCommon.vb
Option   Strict   Off

Namespace  uOffice
    Partial 
Public   Class  ApplicationBase

        
' '' <summary>
         ' '' 设置对象可见性
         ' '' </summary>
         ' '' <param name="visible"></param>
         ' '' <remarks></remarks>
         Public   Sub  SetVisible( ByVal  visible  As   Boolean )
            
Me .gApplicationObject.Visible  =  visible
        
End Sub

        
' '' <summary>
         ' '' 服务器
         ' '' </summary>
         ' '' <remarks>本地时字符串为空,否则如//MyComputer</remarks>
         Public   ReadOnly   Property  Server()  As   String
            
Get
                
Return  gServer
            
End   Get
        
End Property

        
' '' <summary>
         ' '' 版本号
         ' '' </summary>
         Public   ReadOnly   Property  Version()  As   String
            
Get
                
Return   Me .gApplicationObject.Version
            
End   Get
        
End Property

        
' '' <summary>
         ' '' 默认文件地址
         ' '' </summary>
         ' '' <remarks>一般在MyDocuments目录下,按具体情形重载</remarks>
         Public   Overridable   ReadOnly   Property  DefaultFilePath()  As   String
            
Get
                
Return  System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
            
End   Get
        
End Property

        
' '' <summary>
         ' '' 稍停数秒
         ' '' </summary>
         ' '' <param name="seconds">秒数</param>
         ' '' <remarks></remarks>
         Protected   Sub  WaitingSeconds( ByVal  seconds  As   Integer )
            
Dim  tmpNow  As   Date   =  Now
            
While  Now.Subtract(tmpNow).Seconds  <  seconds
                Windows.Forms.Application.DoEvents()
            
End   While
        
End Sub

    
End Class
End Namespace


ComObjReleaseMethod.vb
Namespace  uOffice
    
Friend   Class  ComObjReleaseMethod

        
Friend   Shared   Sub  Invoke( ByVal  comObj  As   Object ByVal  methodName  As   String ByVal  parameters()  As   Object )
            
Dim  mMethod  As  Reflection.MethodInfo  =  comObj.GetType.GetMethod(methodName)
            mMethod.Invoke(comObj, parameters)
        
End Sub

        
Friend   Shared   Sub  ReleaseComObject( ByVal  comObj  As   Object )
            System.Runtime.InteropServices.Marshal.ReleaseComObject(comObj)
            comObj 
=   Nothing
        
End Sub

        
Friend   Shared   Sub  KillProcess( ByVal  comObjProcessName  As   String ByVal  beforeProcessStartTime  As   Date ByVal  afterProcessStartTime  As   Date )

            
Dim  mProcessList  As  Process()
            
Dim  mProcessStartTime  As   Date

            mProcessList 
=  Process.GetProcessesByName(comObjProcessName)

            
For   Each  tmpProcess  As  Process  In  mProcessList
                mProcessStartTime 
=  tmpProcess.StartTime
                
If  mProcessStartTime.CompareTo(beforeProcessStartTime)  >   0   AndAlso  mProcessStartTime.CompareTo(afterProcessStartTime)  <   0   Then
                    tmpProcess.Kill()
                
End   If
            
Next

        
End Sub

        
Friend   Shared   Sub  KillProcess( ByVal  comObjProcessName  As   String ByVal  beforeProcessStartTime  As   Date ByVal  afterProcessStartTime  As   Date ByVal  Server  As   String )
            
' 暂只支持本地
             If  Server  =   ""   Then
                KillProcess(comObjProcessName, beforeProcessStartTime, afterProcessStartTime)
            
Else

            
End   If

        
End Sub

        
Friend   Shared   Sub  KillProcess( ByVal  comObjProcessName  As   String )

            
Dim  mProcessList  As  Process()

            mProcessList 
=  Process.GetProcessesByName(comObjProcessName)

            
For   Each  tmpProcess  As  Process  In  mProcessList
                tmpProcess.Kill()
            
Next

        
End Sub

    
End Class
End Namespace

相应的,有关的AccessApplication文件修改如下:
Namespace  uOffice
    
Public   Class  AccessApplication
        
Inherits  ApplicationBase

        
Protected   Overrides   Sub  SaveDefaultPropertiesWhenApplicationInitialize()

        
End Sub

        
Protected   Overrides   Sub  ResetDefaultPropertiesBeforeApplicationRelease()

        
End Sub

        
Protected   Overrides   Sub  RealseInternalComObjectsBeforeApplicationRelease()

        
End Sub

        
Sub   New ()
            
Me .CreateInstance(ApplicationEnum.Access,  "" )
        
End Sub

        
Sub   New ( ByVal  server  As   String )
            
Me .CreateInstance(ApplicationEnum.Access, server)
        
End Sub

        
Private   Function  CurrentApplication()  As  Microsoft.Office.Interop.Access.Application
            
Return   DirectCast ( Me .gApplicationObject, Microsoft.Office.Interop.Access.Application)
            
' Return Me.gApplicationObject
         End Function

    
End Class
End Namespace

为实现Access数据库的生成、修理压缩和版本转换,增加了以下文件。
AccessApplicationCommon.vb
Namespace  uOffice
    Partial 
Public   Class  AccessApplication

        
' '' <summary>
         ' '' 默认数据库路径
         ' '' </summary>
         Public   Overrides   ReadOnly   Property  DefaultFilePath()  As   String
            
Get
                
' 以下的字串是Default Database Directory
                 Return   Me .CurrentApplication.GetOption(SR.GetString( " Office_Access_Default_Database_Directory " )).ToString
            
End   Get
        
End Property

        
' 取数据库文件全名
         Private   Function  FullFileName( ByVal  file  As   String As   String
            
Dim  mFullfilename  As   String   =  file.Trim

            
If  mFullfilename  =   ""   Then   Return   ""

            
If  mFullfilename.IndexOf( " / " =   - 1   Then   ' 默认目录上
                mFullfilename  =   Me .DefaultFilePath  &  mFullfilename
            
End   If

            
Dim  filename  As   String   =  mFullfilename.Substring(mFullfilename.LastIndexOf( " / " +   1 ' 取文件名称,检查是否有后缀,没有加上.mdb
             If  filename.IndexOf( " . " =   - 1   Then
                mFullfilename 
&=   " .mdb "
            
End   If

            
Return  mFullfilename
        
End Function

    
End Class
End Namespace
AcFileFormatEnum.vb
Namespace  uOffice

    
Public   Enum  AcFileFormatEnum
        Access2 
=   2
        Access2000 
=   9
        Access2002 
=   10
        Access95 
=   7
        Access97 
=   8
    
End Enum

End Namespace

这部分功能实现的主文件
AccessApplicationDatabase.vb
Option   Strict   Off

Namespace  uOffice
    Partial 
Public   Class  AccessApplication

        
' '' <summary>
         ' '' 关闭当前数据库
         ' '' </summary>
         Public   Sub  CloseCurrentDatabase()
            
If   Me .CurrentApplication.CurrentDb IsNot  Nothing   Then
                
Me .CurrentApplication.CloseCurrentDatabase()
            
End   If

            
' 停1秒后执行
            WaitingSeconds( 1 )

        
End Sub

        
' '' <summary>
         ' '' 删除数据库
         ' '' </summary>
         ' '' <param name="file">数据库文件名</param>
         Public   Sub  DeleteDatabase( ByVal  file  As   String )
            file 
=  FullFileName(file).ToLower

            
If   Not  IO.File.Exists(file)  Then   Exit Sub

            
' 如果它是当前打开的数据库,则要关闭
             If   Me .CurrentApplication.CurrentDb IsNot  Nothing   AndAlso  IO.File.Equals(file,  Me .CurrentApplication.CurrentDb.Name.ToLower)  Then
                
Me .CloseCurrentDatabase()
            
End   If

            IO.File.Delete(file)

            
' 停1秒后执行
            WaitingSeconds( 1 )
        
End Sub

        
' '' <summary>
         ' '' 打开数据库
         ' '' </summary>
         ' '' <param name="file">数据库文件名</param>
         ' '' <param name="exclusive">独占打开</param>
         ' '' <param name="password">密码</param>
         ' '' <remarks></remarks>
         Public   Sub  OpenCurrentDatabase( ByVal  file  As   String ByVal  exclusive  As   Boolean ByVal  password  As   String )
            file 
=  FullFileName(file)

            
If   Not  IO.File.Exists(file)  Then   Exit Sub

            
' 关闭当前数据库
            CloseCurrentDatabase()

            
Me .CurrentApplication.OpenCurrentDatabase(file, exclusive, password)

        
End Sub

        
' '' <summary>
         ' '' 共享打开数据库,空密码
         ' '' </summary>
         ' '' <param name="file">数据库文件名</param>
         ' '' <remarks></remarks>
         Public   Sub  OpenCurrentDatabase( ByVal  file  As   String )

            
Me .OpenCurrentDatabase(file,  False "" )

        
End Sub

        
' '' <summary>
         ' '' 创建数据库
         ' '' </summary>
         ' '' <param name="file">数据库文件名.如果网络支持,也可以按以下形式指定网络路径://Server/Share/Folder/Filename</param>
         ' '' <remarks>若已存在相同文件的数据库,则被删除</remarks>
         Public   Sub  CreateDatabase( ByVal  file  As   String )
            file 
=  FullFileName(file).ToLower

            
' 若已存在,则删除
            DeleteDatabase(file)

            
' 关闭当前数据库
             Me .CloseCurrentDatabase()

            
' 生成新数据库并给置为当前数据库
             Me .CurrentApplication.NewCurrentDatabase(file)
        
End Sub

        
' '' <summary>
         ' '' 压缩和修复指定的数据库
         ' '' </summary>
         ' '' <param name="SourceFile">要压缩和修复的数据库或项目文件的完整路径和文件名</param>
         ' '' <param name="DestinationFile">完整的路径和文件名,代表所返回文件的保存位置</param>
         ' '' <returns>如果处理成功,返回 True</returns>
         ' '' <remarks></remarks>
         Public   Function  RepairDatabase( ByVal  SourceFile  As   String ByVal  DestinationFile  As   String As   Boolean

            SourceFile 
=  FullFileName(SourceFile)
            DestinationFile 
=  FullFileName(DestinationFile)

            
' 如果要处理的数据库为当前打开的数据库,则要关闭
             If   Me .CurrentApplication.CurrentDb IsNot  Nothing   AndAlso   Me .CurrentApplication.CurrentDb.Name.ToLower.Equals(SourceFile.ToLower)  Then
                
Me .CloseCurrentDatabase()
            
End   If

            
' 如果目的文件存在,则删除
             If  IO.File.Exists(DestinationFile)  Then  IO.File.Delete(DestinationFile)

            
' 滞1秒后执行
            WaitingSeconds( 1 )

            
Return   Me .CurrentApplication.CompactRepair(SourceFile, DestinationFile,  True )
        
End Function

        
' '' <summary>
         ' '' 转换版本
         ' '' </summary>
         ' '' <param name="SourceFile">待转换的文件名称</param>
         ' '' <param name="DestinationFile">转换后的文件名称</param>
         ' '' <param name="DestinationFileFormat">转换后的文件版本</param>
         ' '' <remarks>并非所有版本都能转换成功</remarks>
         Public   Sub  ConvertAccessProject( ByVal  SourceFile  As   String ByVal  DestinationFile  As   String ByVal  DestinationFileFormat  As  AcFileFormatEnum)
            SourceFile 
=  FullFileName(SourceFile)
            DestinationFile 
=  FullFileName(DestinationFile)

            
Me .CurrentApplication.ConvertAccessProject(SourceFile, DestinationFile, DestinationFileFormat)
        
End Sub

    
End Class
End Namespace

至于其它功能,比如设密码、建用户组,可以参考Access、Dao的帮助文档,并辅以Reflector来做。我不再写这部分的代码了。
至于一些关键参数,比如Default Database Directory是怎么知道的,我是查了注册表。我手头的资料也非常的有限。

对于Access,如何取表,建立和修改表,这部分可以用Sql语句实现了,可以脱离Access.Application来做。当然,上面的部分,可以用别的方法来实现,我只是提供了在Access环境下的一种实现方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值