操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊



    四、利用API函數來處理文件

    通過前面三種方法的介紹,你是否已經覺得足夠了?是的,前面的方法完全可以應付幾乎所有的文件操作。但是為了普及一下API,展示一下API的魅力,最后向大家介紹一下如何利用API函數來處理文件。

    大家對API的強大也是有所耳聞了,在文件操作方面,API自然毫不遜色。

    說明:為了文章簡潔,我們先給出API函數的名稱及功能,其完整的聲明及常數就不再一一細訴,只在示例中給出其完整用法。

    (一)處理驅動器及目錄

    下面是windows中提供的對于目錄進行操作的API函數及其功能:

    CreateDirectory,CreateDirectoryEx 創建一個新目錄

    GetCurrentDirectory 在一個緩沖區中裝載當前目錄

    GetDiskFreeSpace,GetDiskFreeSpaceEx 獲取與一個磁盤的組織有關的信息,以及了解剩余空間的容量

    GetDriveType 判斷一個磁盤驅動器的類型

    GetFullPathName 獲取指定文件的完整路徑名

    GetLogicalDrives 判斷系統中存在哪些邏輯驅動器字母

    GetLogicalDriveStrings 獲取一個字串,其中包含了當前所有邏輯驅動器的根驅動器路徑

    GetSystemDirectory 這個函數能取得Windows系統目錄(System目錄)的完整路徑名。在這個目錄中,包含了所有必要的系統文件。根據微軟的標準,其他定制控件和一些共享組件也可放到這個目錄。通常應避免在這個目錄里創建文件。在網絡環境中,往往需要管理員權限才可對這個目錄進行寫操作

    GetTempPath 獲取為臨時文件指定的路徑

    GetVolumeInformation 獲取與一個磁盤卷有關的信息

    GetWindowsDirectory 這個函數能獲取Windows目錄的完整路徑名。在這個目錄里,保存了大多數windows應用程序文件及初始化文件

    RemoveDirectory 刪除指定目錄

    SetCurrentDirectory 設置當前目錄

    SetVolumeLabel 設置一個磁盤的卷標(Label)

    下面通過幾個例子來詳細的了解一下其中主要的幾個函數及其用法:

    1、GetLogicalDrives

    作用:判斷系統中存在哪些邏輯驅動器字母

    聲明:Declare Function GetLogicalDrives Lib "kernel32" Alias "GetLogicalDrives" () As Long

    說明:此函數的返回值類型為Long,這個結構中的二進制位標志著存在哪些驅動器。其中,位0設為1表示驅動器A:存在于系統中;位1設為1表示存在B:驅動器;以次類推

    示例:

    Public Sub Get_LogicalDrives()

    Dim LDs As Long, Cnt As Long, sDrives As String

    LDs=GetLogicalDrives

    sDrives="Available drives:"

    For Cnt=0 To 25

    If (LDs And 2 ^ Cnt) <> 0 Then

    sDrives=sDrives + " " + Chr$(65 + Cnt)

    End If

    Next Cnt

    MsgBox sDrives

    End Sub

    上面的示例中,我們通過二進制運算,將返回值轉換成字符。如果你的機上有C,D,E,F,G,H這幾個驅動器,那么LDs的值就是252,轉成二進制為11111100,從右往左,依次代表A,B,C,D,...,為0的說明沒有此驅動器字母。大家可以自己試一試。

    2、GetDriveType

    作用:判斷一個磁盤驅動器的類型

    聲明:Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long

    說明:此函數的返回值類型為Long,如驅動器不能識別,則返回零。如指定的目錄不存在,則返回1。如執行成功,則用下述任何一個常數指定驅動器類型:DRIVE_REMOVABLE(表示磁盤可以從驅動器上移走,通常是軟驅), DRIVE_FIXED(磁盤不能從驅動器上移走,通常為本地硬盤), DRIVE_REMOTE(驅動器是遠程網絡驅動器), DRIVE_CDROM(驅動器是CD-ROM驅動器) 或 DRIVE_RAMDISK(驅動器是RAM驅動器)

    參數為String類型,包含了驅動器根目錄路徑的一個字串

    此函數的功能與FSO的Drive對象的DriveType屬性是一樣的。

    示例:

    '定義常數變量

    Private Const DRIVE_CDROM=5 '表示光盤驅動器

    Private Const DRIVE_FIXED=3 '表示硬盤驅動器

    Private Const DRIVE_RAMDISK=6 '表示RAM驅動器

    Private Const DRIVE_REMOTE=4 '表示網絡驅動器

    Private Const DRIVE_REMOVABLE=2 '表示軟盤驅動器


    Private Sub Get_DriveType()

    Dim temp As Long

    temp=GetDriveType("d:\") '取的d:盤驅動器類型

    Select Case temp

    Case DRIVE_CDROM

    MsgBox "DRIVE_CDROM: 光盤驅動器"

    Case DRIVE_FIXED

    MsgBox "DRIVE_FIXED: 硬盤驅動器"

    Case DRIVE_RAMDISK

    MsgBox "DRIVE_RAMDISK: RAM驅動器"

    Case DRIVE_REMOTE

    MsgBox "DRIVE_REMOTE: 網絡驅動器"

    Case DRIVE_REMOVABLE

    MsgBox "DRIVE_REMOVABLE: 軟盤驅動器"

    End Select

    End Sub

    3、GetDiskFreeSpaceEx

    作用:獲取與一個磁盤的組織以及剩余空間容量有關的信息

    聲明:Declare Function GetDiskFreeSpaceEx Lib "kernel32" Alias "GetDiskFreeSpaceExA" (ByVal lpRootPathName As String, lpFreeBytesAvailableToCaller As LARGE_INTEGER, lpTotalNumberOfBytes As LARGE_INTEGER, lpTotalNumberOfFreeBytes As LARGE_INTEGER) As Long

    說明:此函數的返回值類型為Long,非零表示成功,零表示失敗。會設置GetLastError.

    在采用FAT16格式的windows95系統中,如一個驅動器(分區)的容量超過了2GB,則不應使用這個函數。此時,這個函數能識別的最大分區容量只有2GB

    參數說明:

    lpRootPathName String,不包括卷名的磁盤根路徑名

    lpFreeBytesAvailableToCaller LARGE_INTEGER,指定一個變量,用于容納調用者可用的字節數量

    lpTotalNumberOfBytes LARGE_INTEGER,指定一個變量,用于容納磁盤上的總字節數

    lpTotalNumberOfFreeBytes LARGE_INTEGER,指定一個變量,用于容納磁盤上可用的字節數

    LARGE_INTEGER結構用來代表一個64位帶符號的整數值,它的定義如下:

    Type LARGE_INTEGER ' 8 Bytes

     lowpart As Long

     highpart As Long

    End Type

    其中lowpart為 Long,指定低32位,highpart 為 Long,指定高32位。

    示例:雖然此函數能識別的最大分區容量只有2GB,但通過調整,對大于2G的仍然能得出正確容量。以下的調整公式是本人通過逆向推算出來的,至于其中的原理也不是很清楚,大家可一測試一下。

    Private Sub Get_DiskFreeSpaceEx()

    Dim temp As Long, Dms$

    Dim tempa, tempb, tempc

    Dim RootPathName As String

    Dim FreeBytesAvailabletoCaller As LARGE_INTEGER

    Dim TotalNumberOfBytes As LARGE_INTEGER

    Dim TotalNumberOfFreeBytes As LARGE_INTEGER

    RootPathName="d:"

    '取得磁盤空間

    temp=GetDiskFreeSpaceEx(RootPathName, FreeBytesAvailabletoCaller, TotalNumberOfBytes, TotalNumberOfFreeBytes)

    Dms=Dms + "磁盤容量:" + vbCrLf

    tempa=TotalNumberOfBytes.highpart * 2 ^ 32 + IIf(TotalNumberOfBytes.lowpart > 0, TotalNumberOfBytes.lowpart, TotalNumberOfBytes.lowpart + 2 ^ 32) '計算容量

    Dms=Dms + CStr(tempa) + "字節" + vbCrLf

    tempa=Format(tempa / 1024 / 1024 / 1024, "0.00")

    Dms=Dms + tempa + "G" + vbCrLf

    '取得磁盤可用空間

    Dms=Dms + "磁盤可用空間:" + vbCrLf

    tempb=TotalNumberOfFreeBytes.highpart * 2 ^ 32 + IIf(TotalNumberOfFreeBytes.lowpart > 0, TotalNumberOfFreeBytes.lowpart, TotalNumberOfFreeBytes.lowpart + 2 ^ 32) '計算

    Dms=Dms + CStr(tempb) + "字節" + vbCrLf

    tempb=Format(tempb / 1024 / 1024 / 1024, "0.00")

    Dms=Dms + tempb + "G" + vbCrLf

    '取得磁盤已用空間

    Dms=Dms + "磁盤已用空間:" + vbCrLf

    tempc=tempa - tempb

    Dms=Dms + CStr(tempc) + "G" + vbCrLf

    MsgBox Dms

    End Sub

    4、CreateDirectory, CreateDirectoryEx

    作用:創建一個新目錄

    聲明:

    Declare Function CreateDirectory& Lib "kernel32" Alias "CreateDirectoryA" (ByVal lpNewDirectory As String, lpSecurityAttributes As SECURITY_ATTRIBUTES)

    Declare Function CreateDirectoryEx& Lib "kernel32" Alias "CreateDirectoryExA" (ByVal lpTemplateDirectory As String, ByVal lpNewDirectory As String, lpSecurityAttributes As SECURITY_ATTRIBUTES)

    說明:此函數的返回值類型為Long,非零表示成功,零表示失敗。會設置GetLastError

    參數說明:

    lpTemplateDirectory String,指定一個模板目錄的名字,從中復制默認屬性(比如目錄中文件的默認壓縮方式)。如設為vbNullString,則表示不使用模板

    lpNewDirectory String,新目錄的名字

    lpSecurityAttributes SECURITY_ATTRIBUTES,這個結構定義了目錄的安全特性——如果操作系統支持的話

    示例:

    Private Sub Create_Directory()

    Dim Security As SECURITY_ATTRIBUTES

    '創建目錄

    Ret&=CreateDirectory("C:\Directory", Security)

    '若返回0,則失敗。

    If Ret&=0 Then MsgBox "Error : 創建失敗!", vbCritical + vbOKOnly

    End Sub

    5、RemoveDirectory

    作用:移除一個目錄

    聲明:Declare Function RemoveDirectory Lib "kernel32" Alias "RemoveDirectoryA" (ByVal lpPathName As String) As Long

    說明:此函數的返回值類型為Long,非零表示成功,零表示失敗。會設置GetLastError.

    在調用這個函數前,目錄必須為空

    參數說明:

    lpPathName 為String類型,要刪除的那個目錄的名字

    示例:

    Private Sub Remove_Directory()

    Dim Security As SECURITY_ATTRIBUTES

    CreateDirectoryEx "C:\Windows", "C:\Temp", Security

    '移除目錄

    RemoveDirectory "C:\Temp"

    End Sub

    6、SetCurrentDirectory

    作用:設置當前目錄,與VBA語句ChDir類似。

    聲明:Declare Function SetCurrentDirectory Lib "kernel32" Alias "SetCurrentDirectoryA" (ByVal lpPathName As String) As Long

    說明:此函數的返回值類型為Long,非零表示成功,零表示失敗。會設置GetLastError

    參數說明:

    LpPathName String,新當前目錄的路徑

    示例:

    SetCurrentDirectory "d:\" '設置D:為當前目錄

    7、GetSystemDirectory

    作用:這個函數能取得Windows系統目錄(System目錄)的完整路徑名。在這個目錄中,包含了所有必要的系統文件。根據微軟的標準,其他定制控件和一些共享組件也可放到這個目錄。通常應避免在這個目錄里創建文件。在網絡環境中,往往需要管理員權限才可對這個目錄進行寫操作

    聲明:Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long

    說明:此函數的返回值類型為Long,裝載到lpBuffer緩沖區的字符數量。如lpBuffer不夠大,不能容下文件名,則返回要求的緩沖區長度

    參數說明:

    lpBuffer String,用于裝載系統目錄路徑名的一個字串緩沖區。它應事先初始化成nSize+1個字符的長度。通常至少要為這個緩沖區分配MAX_PATH個字符的長度

    nSize Long,lpBuffer字串的最大長度

    示例:

    Private Sub Get_SystemDirectory()

    Dim sSave As String, Ret As Long

    '創建緩沖區

    sSave=Space(255)

    '獲取系統目錄

    Ret=GetSystemDirectory(sSave, 255)

    '移除多余的0

    sSave=Left$(sSave, Ret)

    '顯示路徑

    MsgBox "系統目錄: " + sSave

    End Sub

    (二)處理文件

    下面是windows中提供的對于文件進行操作的API函數及其功能:

    CloseHandle 關閉一個內核對象。其中包括文件、文件映射、進程、線程、安全和同步對象等。

    CompareFileTime 根據FILETIME結構的信息,對比兩個文件的時間

    CopyFile 復制文件。注意:只能復制文件,而不能復制目錄

    CreateFile 這是一個全功能的函數,可打開和創建文件、管道、郵槽、通信服務、設備以及控制臺

    DeleteFile 刪除指定文件

    FindClose 關閉由FindFirstFile函數創建的一個搜索句柄

    FindFirstFile 根據文件名查找文件

    FindNextFile 根據調用FindFirstFile函數時指定的一個文件名查找下一個文件

    FlushFileBuffers 針對指定的文件句柄,刷新內部文件緩沖區

    GetBinaryType 判斷文件是否可以執行

    GetFileAttributes 判斷指定文件的屬性

    GetFileInformationByHandle 該函數能夠獲取上面所有函數所能夠獲取的信息,如大小、屬性等,同時還包括一些其他地方無法獲取的信息,比如:文件卷標、索引和鏈接信息。

    GetFileSize 判斷文件長度

    GetFileTime 取得指定文件的時間信息,有三個文件時間:創建時間、最后訪問時間、最后寫時間。

    GetFileType 在給出文件句柄的前提下,判斷文件類型

    GetFileVersionInfo 從支持版本標記的一個模塊里獲取文件版本信息

    GetFileVersionInfoSize 針對包含了版本資源的一個文件,判斷容納文件版本信息需要一個多大的緩沖區

    GetFullPathName 獲取文件路徑,該函數獲取文件的完整路徑名。注意:只有當該文件在當前目錄下,

    結果才正確。如果要得到真正的路徑。應該用GetModuleFileName函數。

    GetShortPathName 獲取指定文件的短路徑名

    GetTempFileName 這個函數包含了一個臨時文件的名字,它可由應用程序使用

    GetTempPath 獲取Windows臨時目錄路徑

    lclose 關閉指定的文件,請參考CloseHandle函數,了解進一步的情況

    lcreat 創建一個文件。如文件已經存在,就會將其縮短成零長度,并將其打開,以便讀寫

    llseek 設置文件中進行讀寫的當前位置。該函數與vba的seek語句類似。

    LockFile 在windows中,文件可用共享模式打開——在這種情況下,多個進程可同時訪問該文件。

    利用這個函數,要對文件進行讀寫的一個應用程序可將文件的某一部分鎖定起來,使其

    不能由其他應用程序訪問。這樣便避免了同時讀寫時發生的沖突

    LockFileEx 與LockFile相似,只是它提供了更多的功能

    lopen 以二進制模式打開指定的文件

    lread 將文件中的數據讀入內存緩沖區

    lwrite 將數據從內存緩沖區寫入一個文件

    MoveFile, MoveFileEx 移動文件。如dwFlags設為零,則MoveFile完全等價于MoveFileEx

    OpenFile 這個函數能執行大量不同的文件操作。和這個函數相比,請優先考慮CreateFile函數

    (它能打開命名管道和控制Unicode文件名,同時不受128個字符的路徑名稱的限制)

    ReadFile 從文件中讀出數據。與lread函數相比,這個函數要明顯靈活的多。該函數能夠操作

    通信設備、管道、套接字以及郵槽

    ReadFileEx 與ReadFile相似,只是它只能用于異步讀操作,并包含了一個完整的回調

    SearchPath 查找指定文件

    SetEndOfFile 針對一個打開的文件,將當前文件位置設為文件末尾

    SetFileAttributes 設置文件屬性

    SetFilePointer 在一個文件中設置當前的讀寫位置

    SetFileTime 設置文件的創建、訪問及上次修改時間

    UnlockFile 解除對一個文件的鎖定

    UnlockFileEx 解除對一個文件的鎖定

    WriteFile 將數據寫入一個文件。該函數比lwrite函數要靈活的多。也可將這個函數應用于對

    通信設備、管道、套接字以及郵槽的處理

    WriteFileEx 與WriteFile類似,只是它只能用于異步寫操作,并包括了一個完整的回調


    文件的壓縮和解壓縮

    LZOpenFile 打開壓縮文件以讀取

    LZSeek 查找壓縮文件中的一個位置

    LZRead 讀一個壓縮文件

    LZClose 關閉一個壓縮文件

    LZCopy 復制壓縮文件并在處理過程中展開

    GetExpandedName 從壓縮文件中返回文件名稱。


    下面通過幾個例子來詳細的了解一下其中主要的幾個函數及其用法:

    1、CreateFile

    作用:這是一個全功能的例程,可打開和創建文件、管道、郵槽、通信服務、設備以及控制臺

    聲明:

    Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

    說明:

    此函數的返回值類型為Long,如執行成功,則返回文件句柄。INVALID_HANDLE_VALUE表示出錯,會設置GetLastError。即使函數成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也會設為ERROR_ALREADY_EXISTS

    打開一個通信端口時(如COM1),無論如何都要設置成 OPEN_EXISTING。

    這個函數代替了lOpen 和 lCreate函數,應該是我們的首選

    參數說明:

    ?lpFileName String,要打開的文件的名字

    ?dwDesiredAccess Long,如果為 GENERIC_READ 表示允許對設備進行讀訪問;如果為 GENERIC_WRITE 表示允許對設備進行寫訪問(可組合使用);如果為零,表示只允許獲取與一個設備有關的信息

    ?dwShareMode Long,零表示不共享; FILE_SHARE_READ 和/或 FILE_SHARE_WRITE 表示允許對文件進行共享訪問

    ?lpSecurityAttributes SECURITY_ATTRIBUTES,指向一個SECURITY_ATTRIBUTES結構的指針,定義了文件的安全特性(如果操作系統支持的話)


    ?dwCreationDisposition

    Long,下述常數之一:

    CREATE_NEW 創建文件;如文件存在則會出錯

    CREATE_ALWAYS 創建文件,會改寫前一個文件

    OPEN_EXISTING 文件必須已經存在。由設備提出要求

    OPEN_ALWAYS 如文件不存在則創建它

    TRUNCATE_EXISTING 講現有文件縮短為零長度

    ?dwFlagsAndAttributes

    Long,一個或多個下述常數

    FILE_ATTRIBUTE_ARCHIVE 標記歸檔屬性

    FILE_ATTRIBUTE_COMPRESSED 將文件標記為已壓縮,或者標記為文件在目錄中的默認壓縮方式

    FILE_ATTRIBUTE_NORMAL 默認屬性

    FILE_ATTRIBUTE_HIDDEN 隱藏文件或目錄

    FILE_ATTRIBUTE_READONLY 文件為只讀

    FILE_ATTRIBUTE_SYSTEM 文件為系統文件

    FILE_FLAG_WRITE_THROUGH 操作系統不得推遲對文件的寫操作

    FILE_FLAG_OVERLAPPED 允許對文件進行重疊操作

    FILE_FLAG_NO_BUFFERING 禁止對文件進行緩沖處理。文件只能寫入磁盤卷的扇區塊

    FILE_FLAG_RANDOM_ACCESS 針對隨機訪問對文件緩沖進行優化

    FILE_FLAG_SEQUENTIAL_SCAN 針對連續訪問對文件緩沖進行優化

    FILE_FLAG_DELETE_ON_CLOSE 關閉了上一次打開的句柄后,將文件刪除。特別適合臨時文件

    也可在Windows NT下組合使用下述常數標記:

    SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITY_IMPERSONATION, SECURITY_DELEGATION, SECURITY_CONTEXT_TRACKING, SECURITY_EFFECTIVE_ONLY


    ?hTemplateFile Long,如果不為零,則指定一個文件句柄。新文件將從這個文件中復制擴展屬性

    示例如下:

    lngHandle=CreateFile("c:\text.txt", GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_ALWAYS, 0, 0)

    '上面代碼以寫方法打開文件,如文件不存在則創建它。

    2、lcreat

    作用:創建一個文件。如文件已經存在,就會將其縮短成零長度,并將其打開,以便讀寫

    聲明:Declare Function lcreat Lib "kernel32" Alias "_lcreat" (ByVal lpPathName As String, ByVal iAttribute As Long) As Long

    說明:此函數的返回值類型為Long,如執行成功,返回打開文件的句柄。如果出錯,則返回HFILE_ERROR

    該函數會打開已由其他應用程序打開的文件,所以使用它時要小心。win32的CreateFile函數已取代了這個函數。這個函數與vb的open語句作用相同

    參數說明:

    lpPathName String,欲創建的文件的名字

    iAttribute Long,下述值之一:

    0——文件能夠讀寫

    1——創建只讀文件

    2——創建隱藏文件

    3——創建系統文件


    示例:

    下面的語句打開c:\test.txt文件

    lcreat “c:\test.txt”,0

    3、lopen

    作用:以二進制模式打開指定的文件

    聲明:Declare Function lopen Lib "kernel32" Alias "_lopen" (ByVal lpPathName As String, ByVal iReadWrite As Long) As Long

    說明:此函數的返回值類型為Long,如執行成功,返回打開文件的句柄。HFILE_ERROR表示出錯。會設置GetLastError

    參數說明:

    lpPathName String,欲打開文件的名字

    iReadWrite Long,訪問模式和共享模式常數的一個組合,如下所示:

    1、訪問模式

    READ 打開文件,讀取其中的內容

    READ_WRITE 打開文件,對其進行讀寫

    WRITE 打開文件,在其中寫入內容

    2、共享模式(參考OpenFile函數的標志常數表)

    OF_SHARE_COMPAT, OF_SHARE_DENY_NONE, OF_SHARE_DENY_READ, OF_SHARE_DENY_WRITE, OF_SHARE_EXCLUSIVE

    示例:

    lopen “c:\test.txt”,READ

    4、GetFileTime

    作用:取得指定文件的時間信息

    聲明:Declare Function GetFileTime Lib "kernel32" Alias "GetFileTime" (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long

    說明:Long,非零表示成功,零表示失敗。會設置GetLastError

    如果不需要特定的信息,那么lpCreationTime,lpLastAccessTime,lpLastWriteTime都可以設置為零(用ByVal As Long)。這個函數返回的文件時間采用UTC格式

    參數說明:

    hFile Long,文件的句柄

    lpCreationTime FILETIME,用于裝載文件的創建時間

    lpLastAccessTime FILETIME,用于裝載文件上一次訪問的時間(FAT文件系統不支持這一特性)

    lpLastWriteTime FILETIME,用于裝載文件上一次修改的時間

    示例:

    Dim file As Long

    Dim CreationTime As FileTime

    Dim lastaccesstime As FileTime

    Dim lastaccesstime As FileTime

    '定義結構

    Private Type FileTime

     dwLowDateTime As Long

     dwHighDateTime As Long

    End Type

     str1="c:\text.txt"

     file=lopen(str1, READ_WRITE) ‘打開文件

     temp=GetFileTime(file, CreationTime, lastaccesstime, lastwritetime)’得到文件相關信息

    以上代碼獲取的時間信息是Long型的,還需要時間轉換函數進行轉換,完整的示例見附件。

    5、CopyFile

    作用:復制文件。與vb的filecopy命令相似

    聲明:Declare Function CopyFile Lib "kernel32" Alias "CopyFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal bFailIfExists As Long) As Long

    說明:Long,非零表示成功,零表示失敗。會設置GetLastError

    參數說明:

    lpExistingFileName String,源文件名

    lpNewFileName String,目標文件名

    bFailIfExists Long,如果設為TRUE(非零),那么一旦目標文件已經存在,則函數調用會失敗。否則目標文件被改寫


    示例:

    CopyFile "c:\test1.txt", "c:\test2.txt", 1

    以上代碼將c:\test1.txt 拷貝到c:\test2.txt,完整的示例見附件。

    6、MoveFile, MoveFileEx

    作用:移動文件。如dwFlags設為零,則MoveFile完全等價于MoveFileEx

    聲明:

    Declare Function MoveFile Lib "kernel32" Alias "MoveFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String)

    Declare Function MoveFileEx Lib "kernel32" Alias "MoveFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal dwFlags As Long)

    說明:Long,非零表示成功,零表示失敗。會設置GetLastError

    這兩個函數通常不能將文件從一個卷移動到另一個卷。但如設置了MOVEFILE_COPY_ALLOWED標記,MoveFileEx可以做到這一點.

    參數說明:

    lpExistingFileName String,欲移動的文件名

    lpNewFileName String,新文件名

    dwFlags Long,一個或多個下述常數

    MOVEFILE_REPLACE_EXISTING 如目標文件存在,則將其替換

    MOVEFILE_COPY_ALLOWED 如移動到一個不同的卷,則復制文件并刪除原來的文件

    MOVEFILE_DELAY_UNTIL_REBOOT 移動操作在系統下次重新啟動時正式進行。這樣便可在Windows NT中改換系統文件

    示例:

    Private Const MOVEFILE_COPY_ALLOWED=&H2

    Private Const MOVEFILE_DELAY_UNTIL_REBOOT=&H4

    Private Const MOVEFILE_REPLACE_EXISTING=&H1

     MoveFile "c:\test.txt", "d:\test1.txt" ‘移動文件

     MoveFileEx "d:\test1.txt", "c:\test.txt", MOVEFILE_COPY_ALLOWED ‘再一次移動

    以上代碼實現了文件的移動,兩次移動後,文件不變

    7、DeleteFile

    作用:刪除指定文件

    聲明:Declare Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long

    說明:Long,非零表示成功,零表示失敗。會設置GetLastError

    與vba的kill語句相似,在windows 95下使用這個函數要小心——即使文件當前正由一個應用程序打開,該函數也會將其刪除.

    參數說明:

    lpFileName String,欲刪除文件的名字

    示例:

    DeleteFile "c:\test.txt" '刪除c:\test.txt文件

    完整的示例見附件。

    8、ReadFile

    作用:從文件中讀出數據。與lread函數相比,這個函數要明顯靈活的多。該函數能夠操作通信設備、管道、套接字以及郵槽

    聲明:Private Declare Function ReadFile Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long

    說明:Long,非零表示成功,零表示失敗。會設置GetLastError。如啟動的是一次異步讀操作,則函數會返回零值,并將ERROR_IO_PENDING設置成GetLastError的結果。如結果不是零值,但讀入的字節數小于nNumberOfBytesToRead參數指定的值,表明早已抵達了文件的結尾

    參數:

    hFile ---- Long,文件的句柄

    lpBuffer --- Any,用于保存讀入數據的一個緩沖區

    nNumberOfBytesToRead - Long,要讀入的字符數

    lpNumberOfBytesRead - Long,從文件中實際讀入的字符數

    lpOverlapped --- OVERLAPPED,如文件打開時指定了FILE_FLAG_OVERLAPPED,那么必須用這個參數引用一個特殊的結構。那個結構定義了一次異步讀取操作。否則,應將這個參數設為NULL(將函數聲明成ByVal As Long,并傳遞零值)

    示例:完整的示例見附件。

    9、WriteFile

    作用:將數據寫入一個文件。該函數比lwrite函數要靈活的多。也可將這個函數應用于對通信設備、管道、套接字以及郵槽的處理

    聲明:Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long

    說明:Long,TRUE(非零)表示成功,否則返回零。會設置GetLastError

    參數:

    hFile --- Long,一個文件的句柄

    lpBuffer --- Any,要寫入的一個數據緩沖區

    nNumberOfBytesToWrite - Long,要寫入數據的字節數量。如寫入零字節,表示什么都不寫入,但會更新文件的“上一次修改時間”。針對位于遠程系統的命名管道,限制在65535個字節以內

    lpNumberOfBytesWritten - Long,實際寫入文件的字節數量

    lpOverlapped --- OVERLAPPED,倘若在指定FILE_FLAG_OVERLAPPED的前提下打開文件,這個參數就必須引用一個特殊的結構。那個結構定義了一次異步寫操作。否則,該參數應置為空(將聲明變為ByVal As Long,并傳遞零值)

    示例:完整的示例見附件。


    10、SHFileOperation

    作用:此函數的功能很強大,能對文件或文件夾進行復制、移動、重命名、刪除的全部操作。

    聲明:Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

    說明:Long,TRUE(非零)表示成功,否則返回零。

    參數:

    lpFileOp --SHFILEOPSTRUCT類型,指定文件的操作。

    Type SHFILEOPSTRUCT

    hwnd As Long

    wFunc As Long '對文件的操作指令

    pFrom As String '源文件或路徑

    pTo As String '目的文件或路徑

    fFlags As Integer '操作標志

    fAnyOperationsAborted As Long

    hNameMappings As Long

    lpszProgressTitle As String

    End Type

    示例:見附件。


    (三)總結

    通過以上的介紹,我們可以看到API在文件操作方面功能十分強大,能夠完成一些前面方法所不能完成的任務。FileSystemObject對象模型的內部可能就是用API寫的,即便不是我們也可以用API寫出一個FSO類來。API是一個巨大的寶庫,當你為實現某個功能而愁眉不展的時候,查查API可能就能找到滿意的答案。

    寫的這么多,希望對大家有所幫助,至少操作文件是沒有什么問題了。

    ****************

    * 定制模塊行為 *

    ****************

    (1) Option Explicit '強制對模塊內所有變量進行聲明

    Option Private Module '標記模塊為私有,僅對同一工程中其它模塊有用,在宏對話框中不顯示

    Option Compare Text '字符串不區分大小寫

    Option Base 1 '指定數組的第一個下標為 1

    (2) On Error Resume Next '忽略錯誤繼續執行 VBA代碼,避免出現錯誤消息

    (3) On Error GoTo ErrorHandler '當錯誤發生時跳轉到過程中的某個位置

    (4) On Error GoTo 0 '恢復正常的錯誤提示

    (5) Application.DisplayAlerts=False '在程序執行過程中使出現的警告框不顯示

    (6) Application.ScreenUpdating=False '關閉屏幕刷新

    Application.ScreenUpdating=True '打開屏幕刷新

    (7) Application.Enable.CancelKey=xlDisabled '禁用 Ctrl+Break 中止宏運行的功能

    **********

    * 工作簿 *

    **********

    (8) Workbooks.Add() '創建一個新的工作簿

    (9) Workbooks("book1.xls").Activate '激活名為 book1的工作簿

    (10) ThisWorkbook.Save '保存工作簿

    (11) ThisWorkbook.close '關閉當前工作簿

    (12) ActiveWorkbook.Sheets.Count '獲取活動工作薄中工作表數

    (13) ActiveWorkbook.name '返回活動工作薄的名稱

    (14) ThisWorkbook.Name '返回當前工作簿名稱

    ThisWorkbook.FullName '返回當前工作簿路徑和名稱

    (15) ActiveWindow.EnableResize=False '禁止調整活動工作簿的大小

    (16) Application.Window.Arrange xlArrangeStyleTiled '將工作簿以平鋪方式排列

    (17) ActiveWorkbook.WindowState=xlMaximized '將當前工作簿最大化

    **********

    * 工作表 *

    **********

    (18) ActiveSheet.UsedRange.Rows.Count '當前工作表中已使用的行數

    (19) Rows.Count '獲取工作表的行數(注:考慮向前兼容性)

    (20) Sheets(Sheet1).Name="Sum" '將 Sheet1命名為 Sum

    (21) ThisWorkbook.Sheets.Add Before:=Worksheets(1) '添加一個新工作表在第一工作表前

    (22) ActiveSheet.Move After:=ActiveWorkbook. _

    Sheets(ActiveWorkbook.Sheets.Count) '將當前工作表移至工作表的最后

    (23) Worksheets(Array("sheet1","sheet2")).Select '同時選擇工作表 1和工作表 2

    (24) Sheets("sheet1").Delete或 Sheets(1).Delete '刪除工作表 1

    (25) ActiveWorkbook.Sheets(i).Name '獲取工作表 i的名稱

    (26) ActiveWindow.DisplayGridlines=Not ActiveWindow.DisplayGridlines '切換工作表中的網格線顯示,這種方法也可以用在其它方面進

    行相互切換,即相當于開關按鈕

    (27) ActiveWindow.DisplayHeadings=Not ActiveWindow.DisplayHeadings '切換工作表中的行列邊框顯示

    (28) ActiveSheet.UsedRange.FormatConditions.Delete '刪除當前工作表中所有的條件格式

    (29) Cells.Hyperlinks.Delete '取消當前工作表所有超鏈接

    (30) ActiveSheet.PageSetup.Orientation=xlLandscape

    或 ActiveSheet.PageSetup.Orientation=2 '將頁面設置更改為橫向

    (31) ActiveSheet.PageSetup.RightFooter=ActiveWorkbook.FullName '在頁面設置的表尾中輸入文件路徑

    ActiveSheet.PageSetup.LeftFooter=Application.UserName '將用戶名放置在活動工作表的頁腳

    **********************

    * 單元格/單元格區域 *

    **********************

    (32) ActiveCell.CurrentRegion.Select 或 Range(ActiveCell.End(xlUp),ActiveCell.End(xlDown)).Select '選擇當前活動單元格所

    包含的范圍,上下左右無空行

    (33) Cells.Select '選定當前工作表的所有單元格

    (34) Range("A1").ClearContents '清除活動工作表上單元格 A1中的內容

    Selection.ClearContents '清除選定區域內容

    Range("A1:D4").Clear '徹底清除 A1至 D4 單元格區域的內容,包括格式

    (35) Cells.Clear '清除工作表中所有單元格的內容

    (36) ActiveCell.Offset(1,0).Select '活動單元格下移一行,同理,可下移一列

    (37) Range("A1").Offset(ColumnOffset:=1)或 Range("A1").Offset(,1) '偏移一列

    Range("A1").Offset(Rowoffset:=-1)或 Range("A1").Offset(-1) '向上偏移一行

    (38) Range("A1").Copy Range("B1") '復制單元格 A1,粘貼到單元格 B1中

    Range("A1:D8").Copy Range("F1") '將單元格區域復制到單元格 F1開始的區域中

    Range("A1:D8").Cut Range("F1") '剪切單元格區域 A1至 D8,復制到單元格 F1開始的區域中

    Range("A1").CurrentRegion.Copy Sheets("Sheet2").Range("A1") '復制包含 A1 的單元格區域到工作表 2中以 A1起始的單元格區域

    注:CurrentRegion屬性等價于定位命令,由一個矩形單元格塊組成,周圍是一個或多個空行或列

    (39) ActiveWindow.RangeSelection.Value=XX '將值 XX 輸入到所選單元格區域中

    (40) ActiveWindow.RangeSelection.Count '活動窗口中選擇的單元格數

    (41) Selection.Count '當前選中區域的單元格數

    (42) GetAddress=Replace(Hyperlinkcell.Hyperlinks(1).Address,mailto:,"") '返回單元格中超級鏈接的地址并賦值

    (43) TextColor=Range("A1").Font.ColorIndex '檢查單元格 A1的文本顏色并返回顏色索引

    Range("A1").Interior.ColorIndex '獲取單元格 A1背景色

    (44) cells.count '返回當前工作表的單元格數

    (45) Selection.Range("E4").Select '激活當前活動單元格下方 3行,向右 4列的單元格

    (46) Cells.Item(5,"C") '引單元格 C5

    Cells.Item(5,3) '引單元格 C5

    (47) Range("A1").Offset(RowOffset:=4,ColumnOffset:=5)

    或 Range("A1").Offset(4,5) '指定單元格 F5

    (48) Range("B3").Resize(RowSize:=11,ColumnSize:=3)

    Rnage("B3").Resize(11,3) '創建 B3:D13 區域

    (49) Range("Data").Resize(,2) '將 Data 區域擴充 2列

    (50) Union(Range("Data1"),Range("Data2")) '將 Data1 和 Data2 區域連接

    (51) Intersect(Range("Data1"),Range("Data2")) '返回 Data1 和 Data2 區域的交叉區域

    (52) Range("Data").Count '單元格區域Data 中的單元格數

    Range("Data"). Columns.Count '單元格區域 Data 中的列數

    Range("Data"). Rows.Count '單元格區域 Data 中的行數

    (53) Selection.Columns.Count '當前選中的單元格區域中的列數

    Selection.Rows.Count '當前選中的單元格區域中的行數

    (54) Selection.Areas.Count '選中的單元格區域所包含的區域數

    (55) ActiveSheet.UsedRange.Row '獲取單元格區域中使用的第一行的行號

    (56) Rng.Column '獲取單元格區域 Rng 左上角單元格所在列編號

    (57) ActiveSheet.Cells.SpecialCells(xlCellTypeAllFormatConditions) '在活動工作表中返回所有符合條件格式設置的區域

    (58) Range("A1").AutoFilter Field:=3,VisibleDropDown:=False '關閉由于執行自動篩選命令產生的第 3個字段的下拉列表

    ********

    * 名稱 *

    ********

    (59) Range("A1:C3").Name="computer" '命名 A1:C3 區域為 computer

    或 Range("D1:E6").Name="Sheet1!book" '命名局部變量,即 Sheet1上區域 D1:E6為 book

    或 Names("computer").Name="robot" '將區域 computer 重命名為 robot

    (60) Names("book").Delete '刪除名稱

    (61) Names.Add Name:="ContentList",RefersTo:="=OFFSET(Sheet1!A2,0,0,COUNTA(Sheet2!$A:$A))" '動態命名列

    (62) Names.Add Name:="Company",RefersTo:="CompanyCar" '命名字符串 CompanyCar

    (63) Names.Add Name:="Total",RefersTo:=123456 '將數字 123456 命名為 Total。注意數字不能加引號,否則就是命名字符串了。

    (64) Names.Add Name:="MyArray",RefersTo:=ArrayNum '將數組 ArrayNum 命名為 MyArray。

    (65) Names.Add Name:="ProduceNum",RefersTo:="=$B",Visible:=False '將名稱隱藏

    (66) ActiveWorkbook.Names("Com").Name '返回名稱字符串

    **************

    * 公式與函數 *

    **************

    (67) Application.WorksheetFunction.IsNumber("A1") '使用工作表函數檢查 A1單元格中的數據是否為數字

    (68) Range("A:A").Find(Application.WorksheetFunction.Max(Range("A:A"))).Activate

    '激活單元格區域 A 列中最大值的單元格

    (69) Cells(8,8).FormulaArray="=SUM(R2C[-1]:R[-1]C[-1]*R2C:R[-1]C)" '在單元格中輸入數組公式。注意必須使用 R1C1 樣式的表達式

    ********

    * 圖表 *

    ********

    (70) ActiveSheet.ChartObjects.Count '獲取當前工作表中圖表的個數

    (71) ActiveSheet.ChartObjects("Chart1").Select '選中當前工作表中圖表 Chart1

    (72) ActiveSheet.ChartObjects("Chart1").Activate

    ActiveChart.ChartArea.Select '選中當前圖表區域

    (73) WorkSheets("Sheet1").ChartObjects("Chart2").Chart.ChartArea.Interior.ColorIndex=2 '更改工作表中圖表的圖表區的顏色

    (74) Sheets("Chart2").ChartArea.Interior.ColorIndex=2 '更改圖表工作表中圖表區的顏色

    (75) Charts.Add '添加新的圖表工作表

    (76) ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("A1:D5"),PlotBy:=xlColumns '指定圖表數據源并按列排列

    (77) ActiveChart.Location Where:=xlLocationAsNewSheet '新圖表作為新圖表工作表

    (78) ActiveChart.PlotArea.Interior.ColorIndex=xlNone '將繪圖區顏色變為白色

    (79) WorkSheets("Sheet1").ChartObjects(1).Chart.Export FileName:="C:MyChart.gif",FilterName:="GIF" '將圖表 1 導出到 C 盤

    上并命名為MyChart.gif

    ********

    * 窗體 *

    ********

    (80) MsgBox "Hello!" '消息框中顯示消息 Hello

    (81) Ans=MsgBox("Continue?",vbYesNo) '在消息框中點擊"是"按鈕,則 Ans 值為 vbYes;點擊"否"按鈕,則 Ans 值為 vbNo。

    If MsgBox("Continue?",vbYesNo)<>vbYes Then Exit Sub '返回值不為"是",則退出

    (82) Config=vbYesNo+vbQuestion+vbDefaultButton2 '使用常量的組合,賦值組 Config變量,并設置第二個按鈕為缺省按鈕

    (83) MsgBox "This is the first line." & vbNewLine & "Second line." '在消息框中強制換行,可用vbCrLf 代替 vbNewLine。

    (84) MsgBox "the average is :"&Format(Application.WorksheetFunction.Average(Selection),"#,##0.00"),vbInformation,

    "selection count average" & Chr(13) '應用工作表函數返回所選區域的平均值并按指定格式顯示

    (85) Userform1.Show '顯示用戶窗體

    (86) Load Userform1 '加載一個用戶窗體,但該窗體處于隱藏狀態

    (87) Userform1.Hide '隱藏用戶窗體

    (88) Unload Userform1 或 Unload Me '卸載用戶窗體

    (89) (圖像控件).Picture=LoadPicture("圖像路徑") '在用戶窗體中顯示圖形

    (90) UserForm1.Show 0 或 UserForm1.Show vbModeless '將窗體設置為無模式狀態

    (91) Me.Height=Int(0.88*ActiveWindow.Height) '窗體高度為當前活動窗口高度的 0.88

    Me.Width=Int(0.88*ActiveWindow.Width) '窗體寬度為當前活動窗口高度的 0.88

    ********

    * 事件 *

    ********

    (92) Application.EnableEvents=False '禁用所有事件

    Application.EnableEvents=True '啟用所有事件

    注:不適用于用戶窗體控件觸發的事件

    ********

    * 對象 *

    ********

    (93) Set ExcelSheet=CreateObject("Excel.Sheet") '創建一個 Excel 工作表對象

    ExcelSheet.Application.Visible=True '設置 Application 對象使 Excel 可見

    ExcelSheet.Application.Cells(1, 1).Value="Data" '在表格的第一個單元中輸入文本

    ExcelSheet.SaveAs "C:\TEST.XLS" '將該表格保存到 C:\test.xls 目錄

    ExcelSheet.Application.Quit '關閉 Excel

    Set ExcelSheet=Nothing '釋放該對象變量

    (94) '聲明并創建一個 Excel 對象引用

    Dim xlApp As Excel.Application

    Dim xlBook As Excel.Workbook

    Dim xlSheet As Excel.WorkSheet

    Set xlApp=CreateObject("Excel.Application")

    Set xlBook=xlApp.Workbooks.Add

    Set xlSheet=xlBook.Worksheets(1)

    (95) '創建并傳遞一個 Excel.Application 對象的引用

    Call MySub (CreateObject("Excel.Application"))

    (96) Set d=CreateObject(Scripting.Dictionary) '創建一個 Dictionary 對象變量

    (97) d.Add "a", "Athens" '為對象變量添加關鍵字和條目

    ********

    * 其他 *

    ********

    (98) Application.OnKey "^I","macro" '設置 Ctrl+I 鍵為 macro 過程的快捷鍵

    (99) Application.CutCopyMode=False '退出剪切/復制模式

    (100) Application.Volatile True '無論何時工作表中任意單元格重新計算,都會強制計算該函數

    Application.Volatile False '只有在該函數的一個或多個參數發生改變時,才會重新計算該函數

    ****************

    * 定制模塊行為 *

    ****************

    (101) Err.Clear '清除程序運行過程中所有的錯誤

    **********

    * 工作簿 *

    **********

    (102) ThisWorkbook.BuiltinDocumentProperties(""Last Save Time")

    或 Application.Caller.Parent.Parent.BuiltinDocumentProperties(""Last Save Time") '返回上次保存工作簿的日期和時間

    (103) ThisWorkbook.BuiltinDocumentProperties("Last Print Date")

    或 Application.Caller.Parent.Parent.BuiltinDocumentProperties(""Last Print Date") '返回上次打印或預覽工作簿的日期和時間

    (104) Workbooks.Close '關閉所有打開的工作簿

    (105) ActiveWorkbook.LinkSources(xlExcelLinks)(1) '返回當前工作簿中的第一條鏈接

    (106) ActiveWorkbook.CodeName

    ThisWorkbook.CodeName '返回工作簿代碼的名稱

    (107) ActiveWorkbook.FileFormat

    ThisWorkbook.FileFormat '返回當前工作簿文件格式代碼

    (108) ThisWorkbook.Path

    ActiveWorkbook.Path '返回當前工作簿的路徑(注:若工作簿未保存,則為空)

    (109) ThisWorkbook.ReadOnly

    ActiveWorkbook.ReadOnly '返回當前工作簿的讀/寫值(為 False)

    (110) ThisWorkbook.Saved

    ActiveWorkbook.Saved '返回工作簿的存儲值(若已保存則為 False)

    (111) Application.Visible=False '隱藏工作簿

    Application.Visible=True '顯示工作簿

    注:可與用戶窗體配合使用,即在打開工作簿時將工作簿隱藏,只顯示用戶窗體.可設置控制按鈕控制工作簿可見

    **********

    * 工作表 *

    **********

    (112) ActiveSheet.Columns("B").Insert '在A 列右側插入列,即插入 B 列

    ActiveSheet.Columns("E").Cut

    ActiveSheet.Columns("B").Insert '以上兩句將 E 列數據移至 B 列,原 B 列及以后的數據相應后移

    ActiveSheet.Columns("B").Cut

    ActiveSheet.Columns("E").Insert '以上兩句將 B列數據移至 D列,原 C列和 D列數據相應左移一列

    (113) ActiveSheet.Calculate '計算當前工作表

    (114) ThisWorkbook.Worksheets(""sheet1").Visible=xlSheetHidden '正常隱藏工作表,同在 Excel 菜單中選擇""格式--工作表--隱藏"操

    作一樣

    ThisWorkbook.Worksheets(""sheet1").Visible=xlSheetVeryHidden '隱藏工作表,不能通過在 Excel 菜單中選擇""格式--工作表--

    取消隱藏"來重新顯示工作表

    ThisWorkbook.Worksheets(""sheet1").Visible=xlSheetVisible '顯示被隱藏的工作表

    (115) ThisWorkbook.Sheets(1).ProtectContents '檢查工作表是否受到保護

    (116) ThisWorkbook.Worksheets.Add Count:=2, Before:=ThisWorkbook.Worksheets(2)

    或 ThisWorkbook.Workshees.Add ThisWorkbook.Worksheets(2), , 2 '在第二個工作表之前添加兩個新的工作表

    (117) ThisWorkbook.Worksheets(3).Copy '復制一個工作表到新的工作簿

    (118) ThisWorkbook.Worksheets(3).Copy ThisWorkbook.Worksheets(2) '復制第三個工作表到第二個工作表之前

    (119) ThisWorkbook.ActiveSheet.Columns.ColumnWidth=20 '改變工作表的列寬為 20

    ThisWorkbook.ActiveSheet.Columns.ColumnWidth=ThisWorkbook.ActiveSheet.StandardWidth '將工作表的列寬恢復為標準值

    ThisWorkbook.ActiveSheet.Columns(1).ColumnWidth=20 '改變工作表列 1的寬度為 20

    (120) ThisWorkbook.ActiveSheet.Rows.RowHeight=10 '改變工作表的行高為 10

    ThisWorkbook.ActiveSheet.Rows.RowHeight=ThisWorkbook.ActiveSheet.StandardHeight '將工作表的行高恢復為標準值

    ThisWorkbook.ActiveSheet.Rows(1).RowHeight=10 '改變工作表的行 1的高度值設置為 10

    (121) ThisWorkbook.Worksheets(1).Activate '當前工作簿中的第一個工作表被激活

    (122) ThisWorkbook.Worksheets("Sheet1").Rows(1).Font.Bold=True '設置工作表Sheet1中的行1數據為粗體

    (123) ThisWorkbook.Worksheets("Sheet1").Rows(1).Hidden=True '將工作表Sheet1中的行1隱藏

    ActiveCell.EntireRow.Hidden=True '將當前工作表中活動單元格所在的行隱藏

    注:同樣可用于列。

    (124) ActiveSheet.Range(""A:A").EntireColumn.AutoFit '自動調整當前工作表 A 列列寬

    (125) ActiveSheet.Cells.SpecialCells(xlCellTypeConstants,xlTextValues) '選中當前工作表中常量和文本單元格

    ActiveSheet.Cells.SpecialCells(xlCellTypeConstants,xlErrors+xlTextValues) '選中當前工作表中常量和文本及錯誤值單元格

    **************

    * 公式與函數 *

    **************

    (126) Application.MacroOptions Macro:="SumPro",Category:=4 '將自定義的 SumPro 函數指定給Excel 中的""統計函數"類別

    (127) Application.MacroOptions Macro:="SumPro", Description:="First Sum,then Product" '為自定義函數 SumPro 進行了功能說明

    (128) Application.WorksheetFunction.CountA(Range(""A:A"))+1 '獲取 A 列的下一個空單元格

    (129) WorksheetFunction.CountA(Cell.EntireColumn) '返回該單元格所在列非空單元格的數量

    WorksheetFunction.CountA(Cell.EntireRow) '返回該單元格所在行非空單元格的數量

    (130) WorksheetFunction.CountA(Cells) '返回工作表中非空單元格數量

    (131) ActiveSheet.Range(""A20:D20").Formula=""=Sum(R[-19]C:R[-1]C"’對 A 列至 D列前 19個數值求和

    ********

    * 圖表 *

    ********

    (132) ActiveWindow.Visible=False

    或 ActiveChart.Deselect '使圖表處于非活動狀態

    (133) TypeName(Selection)="Chart" '若選中的為圖表,則該語句為真,否則為假

    (134) ActiveSheet.ChartObjects.Delete '刪除工作表上所有的 ChartObject對象

    ActiveWorkbook.Charts.Delete '刪除當前工作簿中所有的圖表工作表

    **************

    * 窗體和控件 *

    **************

    (135) UserForms.Add(MyForm).Show '添加用戶窗體 MyForm 并顯示

    (136)TextName.SetFocus '設置文本框獲取輸入焦點

    (137) SpinButton1.Value=0 '將數值調節鈕控件的值改為 0

    (138) TextBox1.Text=SpinButton1.Value '將數值調節鈕控件的值賦值給文本框控件

    SpinButton1.Value=Val(TextBox1.Text) '將文本框控件值賦給數值調節鈕控件

    CStr(SpinButton1.Value)=TextBox1.Text '數值調節鈕控件和文本框控件相比較

    (139) UserForm1.Controls.Count '顯示窗體 UserForm1 上的控件數目

    (140) ListBox1.AddItem ""Command1" '在列表框中添加 Command1

    (141) ListBox1.ListIndex '返回列表框中條目的值,若為-1,則表明未選中任何列表框中的條目

    (142) RefEdit1.Text '返回代表單元格區域地址的文本字符串

    RefEdit1.Text=ActiveWindow.RangeSelection.Address '初始化 RefEdit 控件顯示當前所選單元格區域

    Set FirstCell=Range(RefEdit1.Text).Range(""A1") '設置某單元格區域左上角單元格

    (143) Application.OnTime Now + TimeValue("00:00:15"), "myProcedure" '等待 15 秒后運行 myProcedure過程

    (144) ActiveWindow.ScrollColumn=ScrollBarColumns.Value ' 將滾動條控件的值賦值給ActiveWindow 對象的 ScrollColumn 屬性

    ActiveWindow.ScrollRow=ScrollBarRows.Value '將滾動條控件的值賦值給ActiveWindow對象的ScrollRow 屬性

    (145) UserForm1.ListBox1.AddItem Sheets(""Sheet1").Cells(1,1) '將單元格 A1 中的數據添加到列表框中

    ListBox1.List=Product '將一個名為 Product 數組的值添加到 ListBox1 中

    ListBox1.RowSource="Sheet2!SumP" '使用工作表Sheet2中的 SumP 區域的值填充列表框

    (146) ListBox1.Selected(0) '選中列表框中的第一個條目(注:當列表框允許一次選中多個條目時,必須使用Selected屬性)

    (147) ListBox1.RemoveItem ListBox1.ListIndex '移除列表框中選中的條目

    ********

    * 對象 *

    ********

    ********************

    * Application 對象 *

    ********************

    (148) Application.UserName '返回應用程序的用戶名

    (149) Application.Caller '返回代表調用函數的單元格

    (150) Application.Caller.Parent.Parent '返回調用函數的工作簿名稱

    (151) Application.StatusBar="請等待……" '將文本寫到狀態欄

    Application.StatusBar="請等待……" & Percent & ""% Completed" '更新狀態欄文本,以變量Percent 代表完成的百分比

    Application.StatusBar=False '將狀態欄重新設置成正常狀態

    (152) Application.Goto Reference:=Range(""A1:D4") '指定單元格區域 A1至 D4,等同于選擇""編輯--定位",指定單元格區域為 A1至 D4,

    不會出現""定位"對話框

    (153) Application.Dialogs(xlDialogFormulaGoto).Show '顯示""定位"對話框,但定位條件按鈕無效

    (154) Application.Dialogs(xlDialogSelectSpecial).Show '顯示""定位條件"對話框

    (155) Application.Dialogs(xlDialogFormatNumber).show '顯示""單元格格式"中的""數字"選項卡

    Application.Dialogs(xlDialogAlignment).show '顯示""單元格格式"中的""對齊"選項卡

    Application.Dialogs(xlDialogFontProperties).show '顯示""單元格格式"中的""字體"選項卡

    Application.Dialogs(xlDialogBorder).show '顯示""單元格格式"中的""邊框"選項卡

    Application.Dialogs(xlDialogPatterns).show '顯示""單元格格式"中的""圖案"選項卡

    Application.Dialogs(xlDialogCellProtection).show '顯示""單元格格式"中的""保護"選項卡

    注:無法一次顯示帶選項卡的""單元格格式"對話框,只能一次顯示一個選項卡。

    (156) Application.Dialogs(xlDialogFormulaGoto).show Range("b2"), True '顯示""引用位置"的默認單元格區域并顯示引用使其出現在窗

    口左上角(注:內置對話框參數的使用)

    (157) Application.CommandBars(1).Controls(2).Controls(16).Execute '執行""定位"話框,相當于選擇菜單""編輯--定位"命令

    (158) Application.Transpose(Array(""Sun","Mon","Tur","Wed","Thu","Fri","Sat")) '返回一個垂直的數組

    (159) Application.Version '返回使用的 Excel 版本號

    (160) Application.Cursor=xlNorthwestArrow '設置光標形狀為北西向箭頭

    Application.Cursor=xlIBeam '設置光標形狀為Ⅰ字形

    Application.Cursor=xlWait '設置光標形狀為沙漏(等待)形

    Application.Cursor=xlDefault '恢復光標的默認設置

    (161) Application.WindowState '返回窗口當前的狀態

    Application.WindowState=xlMinimized '窗口最小化

    Application.WindowState=xlMaximized '窗口最大化

    Application.WindowState=xlNormal '窗口正常狀態

    (162) Application.UsableHeight '獲取當前窗口的高度

    Application.UsableWidth '獲取當前窗口的寬度

    (163) Application.ActiveCell.Address '返回活動單元格的地址(注:返回的是絕對地址)

    (164) Application.ActivePrinter '返回當前打印機的名稱

    (165) Application.ActiveSheet.Name '返回活動工作表的名稱

    (166) Application.ActiveWindow.Caption '返回活動窗口的標題

    (167) Application.ActiveWorkbook.Name '返回活動工作簿的名稱

    (168) Application.Selection.Address '返回所選區域的地址

    (169) Application.ThisWorkbook.Name '返回當前工作簿的名稱

    (170) Application.CalculationVersion '返回 Excel計算引擎版本(右邊四位)及 Excel 版本(左邊兩位)

    (171) Application.MemoryFree '以字節為單位返回Excel允許使用的內存數(不包括已經使用的內存)

    (172) Application.MemoryUsed '以字節為單位返回 Excel 當前使用的內存數

    (173) Application.MemoryTotal '以字節為單位返回 Excel 可以使用的內存數(包括已使用的內存,是MemoryFree和 MemoryUsed 的總和)

    (174) Application.OperatingSystem '返回所使用的操作系統的名稱和版本

    (175) Application.OrganizationName '返回 Excel產品登記使用的組織機構的名稱

    (176) Application.FindFormat '查找的格式種類

    Application.ReplaceFormat '替換查找到的內容的格式種類

    ActiveSheet.Cells.Replace What:=" "", Replacement:=" "",SearchFormat:=True,ReplaceFormat:=True '替換查找到的格式

    (177) Application.Interactive=False '忽略鍵盤或鼠標的輸入

    (178) Application.Evaluate("Rate") '若在工作表中定義了常量 0.06 的名稱為"Rate",則本語句將返回值 0.06

    (179) Application.OnUndo ""Undo Option",""Undo Procedure" '選擇 UndoOption 后,將執行 Undo Procedure 過程

    *************

    * Range對象 *

    *************

    (180) Range(A1:A10).Value=Application.WorksheetFunction.Transpose(MyArray) '將一個含有 10個元素的數組轉置成垂直方向的工作表

    單元格區域(A1至 A10)

    注:因為當把一維數組的內容傳遞給某個單元格區域時,該單元格區域中的單元格必須是水平方向的,即含有多列的一行。若必須使用垂直方向的單

    元格區域,則必須先將數組進行轉置,成為垂直的。

    (181) Range(""A65536").End(xlUp).Row+1 '返回 A 列最后一行的下一行

    (182) rng.Range(""A1") '返回區域左上角的單元格

    (183) cell.Parent.Parent.Worksheets '訪問當前單元格所在的工作簿

    (184) Selection.Font.Bold=Not Selection.Font.Bold '切換所選單元格是否加粗

    (185) ActiveSheet.Range("A:B").Sort Key1:=Columns("B"), Key2:=Columns("A"), Header:=xlYes '兩個關鍵字排序,相鄰兩列,B列為主

    關鍵字,A 列為次關鍵字,升序排列

    (186) cell.Range(""A1").NumberFormat '顯示單元格或單元格區域中的第一個單元格的數字格式

    (187) cell.Range(""A1").HasFormula '檢查單元格或單元格區域中的第一個單元格是否含有公式

    或 cell.HasFormula '工作表中單元格是否含有公式

    (188) Cell.EntireColumn '單元格所在的整列

    Cell.EntireRow '單元格所在的整行

    (189) rng.Name.Name '顯示 rng區域的名稱

    (190) rng.Address '返回 rng 區域的地址

    (191) cell.Range(""A1").Formula '返回包含在 rng區域中左上角單元格中的公式。

    注:若在一個由多個單元格組成的范圍內使用 Formula 屬性,會得到錯誤;若單元格中沒有公式,會得到一個字符串,在公式欄中顯示該單元格的

    值。

    (192) Range(""D5:D10").Cells(1,1) '返回單元格區域 D5:D10 中左上角單元格

    (193) ActiveCell.Row '活動單元格所在的行數

    ActiveCell.Column '活動單元格所在的列數

    (194) Range("A1:B1").HorizontalAlignment=xlLeft '當前工作表中的單元格區域數據設置為左對齊

    (195) ActiveSheet.Range(""A2:A10").NumberFormat="#,##0" '設置單元格區域 A2至 A10中數值格式

    (196) rng.Replace "" "","0" '用 0替換單元格區域中的空單元格

    ************************

    * Collection 與 object *

    ************************

    (197) Dim colMySheets As New Collection

    Public colMySheets As New Collection '聲明新的集合變量

    (198) Set MyRange=Range(""A1:A5") '創建一個名為 MyRange 的對象變量

    (199) <object>.Add Cell.Value CStr(Cell.Value) '向集合中添加惟一的條目(即將重復的條目忽略)

    ***************

    * Windows API *

    ***************

    (200) Declare Function GetWindowsDirectoryA Lib ""kernel32" (ByVal lpBuffer As String,ByVal nSize As Long) As Long 'API

    函數聲明。返回安裝 Windows 所在的目錄名稱,調用該函數后,安裝 Windows 的目錄名稱將在第一個參數 lpBuffer中,該目錄名稱的字符串長度

    包含在第二個參數 nSize 中

    (201) Set objExcel=CreateObject("Excel.Application")objExcel.Workbooks.Add '創建Excel 工作簿

    (202) Application.ActivateMicrosoftApp xlMicrosoftWord '開啟Word應用程序

    (203) Application.TemplatesPath '獲取工作簿模板的位置

    (204) Application.Calculation=xlCalculationManual '設置工作簿手動計算

    Application.Calculation=xlCalculationAutomatic '工作簿自動計算

    (205) Worksheets(1).EnableCalculation=False '不對第一張工作表自動進行重算

    (206) Application.CalculateFull '重新計算所有打開的工作簿中的數據

    (207) Application.RecentFiles.Maximum=5 '將最近使用的文檔列表數設為5

    (208) Application.RecentFiles(4).Open '打開最近打開的文檔中的第4個文檔

    (209) Application.OnTime DateSerial(2006,6,6)+TimeValue(""16:16:16"),""BaoPo" '在2006年6月6日的16:16:16開始運行BaoPo過程

    (210) Application.Speech.Speak ("Hello" & Application.UserName) '播放聲音,并使用用戶的姓名問候用戶

    (211) MsgBox Application.PathSeparator '獲取"\"號

    (212) MsgBox Application.International(xlCountrySetting) '返回應用程序當前所在國家的設置信息

    (213) Application.AutoCorrect.AddReplacement "葛洲壩", "三峽" '自動將在工作表中進行輸入的"葛洲壩"更正為"三峽"

    (214) Beep '讓計算機發出聲音

    (215) Err.Number '返回錯誤代碼

    (216) MsgBox IMEStatus '獲取輸入法狀態

    (217) Date=#6/6/2006#Time=#6:16:16 AM# '將系統時間更改為2006年6月6日上午6時16分16秒

    (218) Application.RollZoom=Not Application.RollZoom '切換是否能利用鼠標中間的滑輪放大/縮小工作表

    (219) Application.ShowWindowsInTaskba=True '顯示任務欄中的窗口,即各工作簿占用各自的窗口

    (220) Application.DisplayScrollBars=True '顯示窗口上的滾動條

    (221) Application.DisplayFormulaBar=Not Application.DisplayFormulaBar '切換是否顯示編輯欄

    (222) Application.Dialogs(xlDialogPrint).Show '顯示打印內容對話框

    (223) Application.MoveAfterReturnDirection=xlToRight '設置按Enter鍵后單元格的移動方向向右

    (224) Application.FindFile '顯示打開對話框

    (225) ThisWorkbook.FollowHyperlink http://fanjy.blog.excelhome.net '打開超鏈接文檔,呵呵,作者的Blog

    ThisWorkbook.FollowHyperlink http://www.excelba.com '偶的小站*~_~*

    (226) ActiveWorkbook.ChangeFileAccess Mode:=xlReadOnly '將當前工作簿設置為只讀

    (227) ActiveWorkbook.AddToFavorites '將當前工作簿添加到收藏夾文件夾中

    (228) ActiveSheet.CheckSpelling '在當前工作表中執行"拼寫檢查"

    (229) ActiveSheet.Protect userinterfaceonly:=True '保護當前工作表

    (230) ActiveSheet.PageSetup.LeftHeader=ThisWorkbook.FullName '在當前工作表的左側頁眉處打印出工作簿的完整路徑和文件名

    (231) Worksheets("Sheet1").Range("A1:G37").Locked=FalseWorksheets("Sheet1").Protect

    '解除對工作表Sheet1中A1:G37區域單元格的鎖定

    '以便當該工作表受保護時也可對這些單元格進行修改

    (232) Worksheets("Sheet1").PrintPreview '顯示工作表sheet1的打印預覽窗口

    (233) ActiveSheet.PrintPreview Enablechanges:=False '禁用顯示在Excel 的""打印預覽"窗口中的""設置"和""頁邊距"按鈕

    (234) ActiveSheet.PageSetup.PrintGridlines=True '在打印預覽中顯示網格線

    ActiveSheet.PageSetup.PrintHeadings=True '在打印預覽中顯示行列編號

    (235) ActiveSheet.ShowDataForm '開啟數據記錄單

    (236) Worksheets("Sheet1").Columns("A").Replace What:="SIN", Replacement:="COS", SearchOrder:=xlByColumns, MatchCase:

    =True '將工作表sheet1中A列的SIN替換為COS

    (237) Rows(2).Delete '刪除當前工作表中的第2行

    Columns(2).Delete '刪除當前工作表中的第2列

    (238) ActiveWindow.SelectedSheets.VPageBreaks.Add before:=ActiveCell '在當前單元格左側插入一條垂直分頁符

    ActiveWindow.SelectedSheets.HPageBreaks.Add before:=ActiveCell '在當前單元格上方插入一條垂直分頁符

    (239) ActiveWindow.ScrollRow=14 '將當前工作表窗口滾動到第14行

    ActiveWindow.ScrollColumn=13 '將當前工作表窗口滾動到第13列

    (240) ActiveWindow.Close '關閉當前窗口

    (241) ActiveWindow.Panes.Count '獲取當前窗口中的窗格數

    (242) Worksheets("sheet1").Range("A1:D2").CreateNames Top:=True '將A2至D2的單元格名稱設定為A1到D1單元格的內容

    (243) Application.AddCustomList listarray:=Range("A1:A8") '自定義當前工作表中單元格A1至A8中的內容為自動填充序列

    (244) Worksheets("sheet1").Range("A1:B2").CopyPicture xlScreen, xlBitmap '將單元格A1至B2的內容復制成屏幕快照

    (245) Selection.Hyperlinks.Delete '刪除所選區域的所有鏈接

    Columns(1).Hyperlinks.Delete '刪除第1列中所有的鏈接

    Rows(1).Hyperlinks.Delete '刪除第1行中所有的鏈接

    Range("A1:Z30").Hyperlinks.Delete '刪除指定范圍所有的鏈接

    (246) ActiveCell.Hyperlinks.Add Anchor:=ActiveCell, Address:="C:\Windows\System32\Calc.exe", ScreenTip:=" 按下我, 就會開

    啟Windows 計算器", TextToDisplay:="Windows 計算器" '在活動單元格中設置開啟Windows計算器鏈接

    (247) ActiveCell.Value=Shell("C:\Windows\System32\Calc.exe", vbNormalFocus) '開啟Windows計算器

    (248) ActiveSheet.Rows(1).AutoFilter '打開自動篩選。若再運行一次,則關閉自動篩選

    (249) Selection.Autofilter '開啟/關閉所選區域的自動篩選

    (250) ActiveSheet.ShowAllData '關閉自動篩選

    (251) ActiveSheet.AutoFilterMode '檢查自動篩選是否開啟,若開啟則該語句返回True

    (252) ActiveSheet.Columns("A").ColumnDifferences(Comparison:=ActiveSheet. Range("A2")).Delete '在A列中找出與單元格A2內容不

    同的單元格并刪除

    (253) ActiveSheet.Range("A6").ClearNotes '刪除單元格A6中的批注,包括聲音批注和文字批注

    (254) ActiveSheet.Range("B8").ClearComments '刪除單元格B8中的批注文字

    (255) ActiveSheet.Range("A1:D10").ClearFormats '清除單元格區域A1至D10中的格式

    (256) ActiveSheet.Range("B2:D2").BorderAround ColorIndex:=5, Weight:=xlMedium, LineStyle:=xlDouble '將單元格B2至D2區域設置

    為藍色雙線

    (257) Range("A1:B2").Item(2, 3)或Range("A1:B2")(2, 3) '引用單元格C2的數據

    Range("A1:B2")(3) '引用單元格A2

    (258) ActiveSheet.Cells(1, 1).Font.Bold=TRUE '設置字體加粗

    ActiveSheet.Cells(1, 1).Font.Size=24 '設置字體大小為24磅

    ActiveSheet.Cells(1, 1).Font.ColorIndex=3 '設置字體顏色為紅色

    ActiveSheet.Cells(1, 1).Font.Italic=TRUE '設置字體為斜體

    ActiveSheet.Cells(1, 1).Font.Name="Times New Roman" '設置字體類型

    ActiveSheet.Cells(1, 1).Interior.ColorIndex=3 '將單元格的背景色設置為紅色

    (259) ActiveSheet.Range("C2:E6").AutoFormat Format:=xlRangeAutoFormatColor3 '將當前工作表中單元格區域C2至E6格式自動調整為彩

    色3格式

    (260) Cells.SpecialCells(xlCellTypeLastCell) '選中當前工作表中的最后一個單元格

    (261) ActiveCell.CurrentArray.Select '選定包含活動單元格的整個數組單元格區域.假定該單元格在數據單元格區域中

    (262) ActiveCell.NumberFormatLocal="0.000; [紅色] 0.000" '將當前單元格數字格式設置為帶3位小數,若為負數則顯示為紅色

    (263) IsEmpty (ActiveCell.Value) '判斷活動單元格中是否有值

    (264) ActiveCell.Value=LTrim(ActiveCell.Value) '刪除字符串前面的空白字符

    (265) Len(ActiveCell.Value) '獲取活動單元格中字符串的個數

    (266) ActiveCell.Value=UCase(ActiveCell.Value) '將當前單元格中的字符轉換成大寫

    (267) ActiveCell.Value=StrConv(ActiveCell.Value, vbLowerCase) '將活動單元格中的字符串轉換成小寫

    (268) ActiveSheet.Range("C1").AddComment '在當前工作表的單元格C1中添加批注

    (269) Weekday(Date) '獲取今天的星期,以數值表示,1-7分別對應星期日至星期六

    (270) ActiveSheet.Range("A1").AutoFill Range(Cells(1, 1), Cells(10, 1)) '將單元格A1的數值填充到單元格A1至A10區域中

    (271) DatePart("y", Date) '獲取今天在全年中的天數

    (272) ActiveCell.Value=DateAdd("yyyy", 2, Date) '獲取兩年后的今天的日期

    (273) MsgBox WeekdayName(Weekday(Date)) '獲取今天的星期數

    (274) ActiveCell.Value=Year(Date) '在當前單元格中輸入今年的年份數

    ActiveCell.Value=Month(Date) '在當前單元格中輸入今天所在的月份數

    ActiveCell.Value=Day(Date) '在當前單元格中輸入今天的日期數

    (275) ActiveCell.Value=MonthName(1) '在當前單元格中顯示月份的名稱,本句為顯示"一月"

    (276) ActiveCell.Value=Hour(Time) '在當前單元格中顯示現在時間的小時數

    ActiveCell.Value=Minute(Time) '在當前單元格中顯示現在時間的分鐘數

    ActiveCell.Value=Second(Time) '在當前單元格中顯示現在時間的秒數

    (277) ActiveSheet.Shapes(1).Delete '刪除當前工作表中的第一個形狀

    (278) ActiveSheet.Shapes.Count '獲取當前工作表中形狀的數量

    (279) ActiveSheet.Shapes(1).TextEffect.ToggleVerticalText '改變當前工作表中第一個藝術字的方向

    (280) ActiveSheet.Shapes(1).TextEffect.FontItalic=True '將當前工作表中第一個藝術字的字體設置為斜體

    (281) ActiveSheet.Shapes.AddTextEffect(msoTextEffect21, "三峽", "Arial Black", 22#, msoFalse, msoFalse, 66#, 80).Select

    '在當前工作表中創建一個名為"三峽"的藝術字并對其進行格式設置和選中

    (282) ActiveSheet.Shapes.AddLine(BeginX:=10, BeginY:=10, EndX:=250, EndY:=100).Select '在當前工作表中以(10,10)為起點

    (250,100)為終點畫一條直線并選中

    (283) ActiveSheet.Shapes.AddShape(Type:=msoShapeRightTriangle, Left:=70, Top:=40, Width:=130, Height:=72).Select '在當前

    工作表中畫一個左上角在(70,40),寬為130高為72的三角形并選中

    (284) ActiveSheet.Shapes.AddShape(Type:=msoShapeRectangle, Left:=70, Top:=40, Width:=130, Height:=72).Select '在當前工作

    表中畫一個以點(70,40)為起點,寬130高72的矩形并選中

    (285) ActiveSheet.Shapes.AddShape(Type:=msoShapeOval, Left:=70, Top:=40, Width:=130, Height:=72).Select '在當前工作表中畫

    一個左上角在(70,40),寬為130高為72的橢圓

    (286) ActiveSheet.Shapes(1).Line.ForeColor.RGB=RGB(0, 0, 255) '將當前工作表中第一個形狀的線條顏色變為藍色

    (287) ActiveSheet.Shapes(2).Fill.ForeColor.RGB=RGB(255, 0, 0) '將當前工作表中第2個形狀的前景色設置為紅色

    (288) ActiveSheet.Shapes(1).Rotation=20 '將當前工作表中的第1個形狀旋轉20度

    (289) Selection.ShapeRange.Flip msoFlipHorizontal '將當前選中的形狀水平翻轉

    Selection.ShapeRange.Flip msoFlipVertical '將當前選中的形狀垂直翻轉

    (290) Selection.ShapeRange.ThreeD.SetThreeDFormat msoThreeD1 '將所選取的形狀設置為第1種立體樣式

    (291) ActiveSheet.Shapes(1).ThreeD.Depth=20 '將當前工作表中第一個立體形狀的深度設置為20

    (292) ActiveSheet.Shapes(1).ThreeD.ExtrusionColor.RGB=RGB(0, 0, 255) '將當前工作表中第1個立體形狀的進深部分的顏色設為藍色

    (293) ActiveSheet.Shapes(1).ThreeD.RotationX=60 '將當前工作表中的第1個立體形狀沿X軸旋轉60度

    ActiveSheet.Shapes(1).ThreeD.RotationY=60 '將當前工作表中的第1個立體形狀沿Y軸旋轉60度

    (294) Selection.ShapeRange.ThreeD.Visible=msoFalse '將所選擇的立體形狀轉換為平面形狀

    (295) Selection.ShapeRange.ConnectorFormat.BeginDisconnect '在形狀中讓指定的連接符起點脫離原來所連接的形狀

    (296) ActiveSheet.Shapes(1).PickUp '復制當前工作表中形狀1的格式

    (297) ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, 260, 160, 180, 30). TextFrame.Characters.Text=

    "fanjy.blog.excelhome.net" '在工作簿中新建一個文本框并輸入內容

    (298) ActiveSheet.Shapes.AddLabel(msoTextOrientationHorizontal, 20, 80, 100, 200). TextFrame.Characters.Text=

    "fanjy.blog.excelhome.net" '在當前工作表中建立一個水平文本框并輸入內容

    (299) ActiveSheet.Shapes.AddPicture "d:\sx.jpg", True, True, 60, 20, 400, 300 '在當前工作表中插入一張d盤中名為sx 的圖片

    (300) ActiveChart.ApplyCustomType xl3DArea '將當前圖表類型改為三維面積圖

    部分- 保證數據完整性

    討論如何保持數據庫的清晰和健壯,如何把有害數據降低到最小程度。

    第 5 部分- 各種小技巧

    不包括在以上 4 個部分中的其他技巧,五花八門,有了它們希望你的數據庫開發工作會更輕松一些。

    第 1 部分- 設計數據庫之前

    1. 考察現有環境

    在設計一個新數據庫時,你不但應該仔細研究業務需求而且還要考察現有的系統。大多數數據庫項目都不是從頭開始建立的;通常,機構內總會存

    在用來滿足特定需求的現有系統(可能沒有實現自動計算)。顯然,現有系統并不完美,否則你就不必再建立新系統了。但是對舊系統的研究可以

    讓你發現一些可能會忽略的細微問題。一般來說,考察現有系統對你絕對有好處。我曾經接手過一個為地區運輸公司開發的數據庫項目,活不難,

    用的是Access 數據庫。我設置

    了一些項目設計參數,而且同客戶一道對這些參數進行了評估,事先還查看了開發環境下所采取的工作模式,等到最后部署應用的時候,只見終端

    上出了幾個提示符然后立馬在我面前翹辮子了!抓耳撓腮的折騰了好幾個小時,我才意識到,原來這家公司的網絡上跑著兩個數據庫應用,而對網

    絡的訪問需要明確和嚴格的用戶帳號及其訪問權限。明白了這一點,問題迎刃而解:只需采用客戶的系統即可。這個項目給我的教訓就是:記住,

    假如你在諸如Access 或者Interbase 這類公共環境下開發應用程序,一定要從表面下手深入系統內部搞清楚你面臨的環境到底是怎么回事。

    2. 定義標準的對象命名規范

    一定要定義數據庫對象的命名規范。對數據庫表來說,從項目一開始就要確定表名是采用復數還是單數形式。此外還要給表的別名定義簡單規則

    (比方說,如果表名是一個單詞,別名就取單詞的前4 個字母;如果表名是兩個單詞,就各取兩個單詞的前兩個字母組成4 個字母長的別名;如果

    表的名字由3 個單詞組成,你不妨從頭兩個單詞中各取一個然后從最后一個單詞中再取出兩個字母,結果還是組成4 字母長的別名,其余依次類

    推)對工作用表來說,表名可以加上前綴WORK_ 后面附上采用該表的應用程序的名字。表內的列要針對鍵采用一整套設計規則。比如,如果鍵是數

    字類型,你可以用_NO 作為后綴;如果是字符類型則可以采用 _CODE 后綴。對列名應該采用標準的前綴和后綴。再如,假如你的表里有好多

    “money”字段,你不妨給每個列增加一個_AMT 后綴。還有,日期列最好以DATE_作為名字打頭。檢查表名、報表名和查詢名之間的命名規范。你

    可能會很快就被這些不同的數據庫要素的名稱搞糊涂了。假如你堅持統一地命名這些數據庫的不同組成部分,至少你應該在這些對象名字的開頭用

    table、query 或者report 等前綴加以區別。如果采用了 Microsoft Access,你可以用qry、rpt、tbl 和mod 等符號來標識對象(比如

    tbl_Employees)。我在和SQL Server(或者Oracle)打交道的時候還用過tbl 來索引表,但我用sp_company (現在用sp_feft_)標識存儲過

    程,因為在有的時候如果我發現了更好的處理辦法往往會保存好幾個拷貝。我在實現 SQL Server 2000 時用udf_ (或者類似的標記)標識我編

    寫的函數。

    3. 預先計劃

    上個世紀 80 年代初,我還在使用資產帳目系統和System 38 平臺,那時我負責設計所有的日期字段,這樣在不費什么力氣的情況下將來就可以輕

    松處理2000 年問題了。許多人給我說就別去解決這一問題了,因為要處理起來太麻煩了(這在世人皆知的Y2K 問題之前很久了)。我回擊說只要

    預先計劃今后就不會遇到大麻煩。結果我只用了兩周的時間就把程序全部改完了。因為預先計劃的好,后來Y2K 問題對該系統的危害降到了最低程

    度(最近聽說該程序甚至到了1995 年都還運行在AS/400 系統上,唯一出現的小問題是從代碼中刪除注釋費了點工夫)。

    4. 獲取數據模式資源手冊

    正在尋求示例模式的人可以閱讀《數據模式資源手冊 》一書,該書由Len Silverston、W. H.Inmon 和Kent Graziano 編寫,是一本值得擁有的

    最佳數據建模圖書。該書包括的章節涵蓋多種數據領域,比如人員、機構和工作效能等。5. 暢想未來,但不可忘了過去的教訓我發現詢問用戶如

    何看待未來需求變化非常有用。這樣做可以達到兩個目的:首先,你可以清楚地了解應用設計在哪個地方應該更具靈活性以及如何避免性能瓶頸;

    其次,你知道發生事先沒有確定的需求變更時用戶將和你一樣感到吃驚。一定要記住過去的經驗教訓!我們開發人員還應該通過分享自己的體會和

    經驗互相幫助。即使用戶認為他們再也不需要什么支持了,我們也應該對他們進行這方面的教育,我們都曾經面臨過這樣的時刻“當初要是這么做

    了該多好??”。

    6. 在物理實踐之前進行邏輯設計

    在深入物理設計之前要先進行邏輯設計。隨著大量的 CASE 工具不斷涌現出來,你的設計也可以達到相當高的邏輯水準,你通常可以從整體上更好

    地了解數據庫設計所需要的方方面面。

    7. 了解你的業務

    在你百分百地確定系統從客戶角度滿足其需求之前不要在你的ER(實體關系)模式中加入哪怕一個數據表(怎么,你還沒有模式?那請你參看技巧

    9)。了解你的企業業務可以在以后的開發階段節約大量的時間。一旦你明確了業務需求,你就可以自己做出許多決策了。一旦你認為你已經明確

    了業務內容,你最好同客戶進行一次系統的交流。采用客戶的術語并且向他們解釋你所想到的和你所聽到的。同時還應該用可能、將會和必須等詞

    匯表達出系統的關系基數。這樣你就可以讓你的客戶糾正你自己的理解然后做好下一步的ER 設計。

    8. 創建數據字典和ER 圖表

    一定要花點時間創建ER 圖表和數據字典。其中至少應該包含每個字段的數據類型和在每個表內的主外鍵。創建ER 圖表和數據字典確實有點費時但

    對其他開發人員要了解整個設計卻是完全必要的。越早創建越能有助于避免今后面臨的可能混亂,從而可以讓任何了解數據庫的人都明確如何從數

    據庫中獲得數據。

    有一份諸如 ER 圖表等最新文檔其重要性如何強調都不過分,這對表明表之間關系很有用,而數據字典則說明了每個字段的用途以及任何可能存在

    的別名。對SQL 表達式的文檔化來說這是完全必要的。

    9. 創建模式

    一張圖表勝過千言萬語:開發人員不僅要閱讀和實現它,而且還要用它來幫助自己和用戶對話。模式有助于提高協作效能,這樣在先期的數據庫設

    計中幾乎不可能出現大的問題。模式不必弄的很復雜;甚至可以簡單到手寫在一張紙上就可以了。只是要保證其上的邏輯關系今后能產生效益。

    10. 從輸入輸出下手

    在定義數據庫表和字段需求(輸入)時,首先應檢查現有的或者已經設計出的報表、查詢和視圖(輸出)以決定為了支持這些輸出哪些是必要的表

    和字段。舉個簡單的例子:假如客戶需要一個報表按照郵政編碼排序、分段和求和,你要保證其中包括了單獨的郵政編碼字段而不要把郵政編碼糅

    進地址字段里。

    11. 報表技巧

    要了解用戶通常是如何報告數據的:批處理還是在線提交報表?時間間隔是每天、每周、每月、每個季度還是每年?如果需要的話還可以考慮創建

    總結表。系統生成的主鍵在報表中很難管理。用戶在具有系統生成主鍵的表內用副鍵進行檢索往往會返回許多重復數據。這樣的檢索性能比較低而

    且容易引起混亂。

    12. 理解客戶需求

    看起來這應該是顯而易見的事,但需求就是來自客戶(這里要從內部和外部客戶的角度考慮)。不要依賴用戶寫下來的需求,真正的需求在客戶的

    腦袋里。你要讓客戶解釋其需求,而且隨著開發的繼續,還要經常詢問客戶保證其需求仍然在開發的目的之中。一個不變的真理是:“只有我看見

    了我才知道我想要的是什么”必然會導致大量的返工,因為數據庫沒有達到客戶從來沒有寫下來的需求標準。而更糟的是你對他們需求的解釋只屬

    于你自己,而且可能是完全錯誤的。

    第 2 部分- 設計表和字段1. 檢查各種變化

    我在設計數據庫的時候會考慮到哪些數據字段將來可能會發生變更。比方說,姓氏就是如此(注意是西方人的姓氏,比如女性結婚后從夫姓等)。

    所以,在建立系統存儲客戶信息時,我傾向于在單獨的一個數據表里存儲姓氏字段,而且還附加起始日和終止日等字段,這樣就可以跟蹤這一數據

    條目的變化。

    2. 采用有意義的字段名有一回我參加開發過一個項目,其中有從其他程序員那里繼承的程序,那個程序員喜歡用屏幕上顯示數據指示用語命名字

    段,這也不賴,但不幸的是,她還喜歡用一些奇怪的命名法,其命名采用了匈牙利命名和控制序號的組合形式,比如cbo1、 txt2、txt2_b 等

    等。除非你在使用只面向你的縮寫字段名的系統,否則請盡可能地把字段描述的清楚些。當然,也別做過頭了,比如

    Customer_Shipping_Address_Street_Line_1 I 雖然很富有說明性,但沒人愿意鍵入這么長的名字,具體尺度就在你的把握中。

    3. 采用前綴命名

    如果多個表里有好多同一類型的字段(比如FirstName),你不妨用特定表的前綴(比如CusLastName)來幫助你標識字段。時效性數據應包括

    “最近更新日期/時間”字段。時間標記對查找數據問題的原因、按日期重新處理/重載數據和清除舊數據特別有用。

    5. 標準化和數據驅動

    數據的標準化不僅方便了自己而且也方便了其他人。比方說,假如你的用戶界面要訪問外部數據源(文件、XML 文檔、其他數據庫等),你不妨把

    相應的連接和路徑信息存儲在用戶界面支持表里。還有,如果用戶界面執行工作流之類的任務(發送郵件、打印信箋、修改記錄狀態等),那么產

    生工作流的數據也可以存放在數據庫里。預先安排總需要付出努力,但如果這些過程采用數據驅動而非硬編碼的方式,那么策略變更和維護都會方

    便得多。事實上,如果過程是數據驅動的,你就可以把相當大的責任推給用戶,由用戶來維護自己的工作流過程。

    6. 標準化不能過頭

    對那些不熟悉標準化一詞(normalization )的人而言,標準化可以保證表內的字段都是最基礎的要素,而這一措施有助于消除數據庫中的數據冗

    余。標準化有好幾種形式,但Third NormalForm(3NF)通常被認為在性能、擴展性和數據完整性方面達到了最好平衡。簡單來說,3NF 規定:

    · 表內的每一個值都只能被表達一次。

    · 表內的每一行都應該被唯一的標識(有唯一鍵)。

    · 表內不應該存儲依賴于其他鍵的非鍵信息。

    遵守 3NF 標準的數據庫具有以下特點:有一組表專門存放通過鍵連接起來的關聯數據。比方說,某個存放客戶及其有關定單的3NF 數據庫就可能

    有兩個表:Customer 和Order。Order 表不包含定單關聯客戶的任何信息,但表內會存放一個鍵值,該鍵指向Customer 表里包含該客戶信息的那

    一行。

    更高層次的標準化也有,但更標準是否就一定更好呢?答案是不一定。事實上,對某些項目來說,甚至就連3NF 都可能給數據庫引入太高的復雜

    性。

    為了效率的緣故,對表不進行標準化有時也是必要的,這樣的例子很多。曾經有個開發財務分析軟件的活就是用非標準化表把查詢時間從平均40

    秒降低到了兩秒左右。雖然我不得不這么做,但我絕不把數據表的非標準化當作當然的設計理念。而具體的操作不過是一種派生。所以如果表出了

    問題重新產生非標準化的表是完全可能的。

    7. Microsoft Access 報表技巧

    如果你正在使用Microsoft Access,你可以用對用戶友好的字段名來代替編號的名稱:比如用Customer Name 代替txtCNaM。這樣,當你用向導

    程序創建表單和報表時,其名字會讓那些不是程序員的人更容易閱讀。

    8. 不活躍或者不采用的指示符

    增加一個字段表示所在記錄是否在業務中不再活躍挺有用的。不管是客戶、員工還是其他什么人,這樣做都能有助于再運行查詢的時候過濾活躍或

    者不活躍狀態。同時還消除了新用戶在采用數據時所面臨的一些問題,比如,某些記錄可能不再為他們所用,再刪除的時候可以起到一定的防范作

    用。

    9. 使用角色實體定義屬于某類別的列

    在需要對屬于特定類別或者具有特定角色的事物做定義時,可以用角色實體來創建特定的時間關聯關系,從而可以實現自我文檔化。這里的含義不

    是讓 PERSON 實體帶有Title 字段,而是說,為什么不用PERSON 實體和PERSON_TYPE 實體來描述人員呢?然后,比方說,當 John Smith,

    Engineer 提升為JohnSmith, Director 乃至最后爬到John Smith, CIO 的高位,而所有你要做的不過是改變兩個表PERSON 和PERSON_TYPE 之

    間關系的鍵值,同時增加一個日期/時間字段來知道變化是何時發生的。這樣,你的PERSON_TYPE 表就包含了所有PERSON 的可能類型,比如

    Associate、

    Engineer、Director、CIO 或者CEO 等。

    還有個替代辦法就是改變PERSON 記錄來反映新頭銜的變化,不過這樣一來在時間上無法跟蹤個人所處位置的具體時間。

    10. 采用常用實體命名機構數據

    組織數據的最簡單辦法就是采用常用名字,比如:PERSON、ORGANIZATION、ADDRESS 和PHONE 等等。當你把這些常用的一般名字組合起來或者創

    建特定的相應副實體時,你就得到了自己用的特殊版本。開始的時候采用一般術語的主要原因在于所有的具體用戶都能對抽象事物具體化。

    有了這些抽象表示,你就可以在第2 級標識中采用自己的特殊名稱,比如,PERSON 可能是Employee、Spouse、Patient、Client、Customer、

    Vendor 或者Teacher 等。同樣的,ORGANIZATION 也可能是MyCompany、MyDepartment、Competitor、Hospital、Warehouse、Government

    等。最后ADDRESS 可以具體為Site、Location、Home、Work、Client、Vendor、Corporate 和FieldOffice 等。

    采用一般抽象術語來標識“事物”的類別可以讓你在關聯數據以滿足業務要求方面獲得巨大的靈活性,同時這樣做還可以顯著降低數據存儲所需的

    冗余量。

    11. 用戶來自世界各地

    在設計用到網絡或者具有其他國際特性的數據庫時,一定要記住大多數國家都有不同的字段格式,比如郵政編碼等,有些國家,比如新西蘭就沒有

    郵政編碼一說。

    12. 數據重復需要采用分立的數據表

    如果你發現自己在重復輸入數據,請創建新表和新的關系。

    13. 每個表中都應該添加的3 個有用的字段

    · dRecordCreationDate,在VB 下默認是Now(),而在SQL Server 下默認為GETDATE()

    · sRecordCreator,在SQL Server 下默認為NOT NULL DEFAULT USER

    · nRecordVersion,記錄的版本標記;有助于準確說明記錄中出現null 數據或者丟失數據的原

    14. 對地址和電話采用多個字段

    描述街道地址就短短一行記錄是不夠的。Address_Line1、Address_Line2 和Address_Line3 可以提供更大的靈活性。還有,電話號碼和郵件地

    址最好擁有自己的數據表,其間具有自身的類型和標記類別。過分標準化可要小心,這樣做可能會導致性能上出現問題。雖然地址和電話表分離通

    常可以達到最佳狀態,但是如果需要經常訪問這類信息,或許在其父表中存放“首選”信息(比如Customer 等)更為妥當些。非標準化和加速訪

    問之間的妥協是有一定意義的。

    15. 使用多個名稱字段

    我覺得很吃驚,許多人在數據庫里就給name 留一個字段。我覺得只有剛入門的開發人員才會這么做,但實際上網上這種做法非常普遍。我建議應

    該把姓氏和名字當作兩個字段來處理,然后在查詢的時候再把他們組合起來。Klempan 不是唯一一個注意到使用單個name 字段的人,要把這種情

    況變得對用戶更為友好有好些方法。我最常用的是在同一表中創建一個計算列,通過它可以自動地連接標準化后的字段,這樣數據變動的時候它也

    跟著變。不過,這樣做在采用建模軟件時得很機靈才行。總之,采用連接字段的方式可以有效的隔離用戶應用和開發人員界面。

    16. 提防大小寫混用的對象名和特殊字符

    過去最令我惱火的事情之一就是數據庫里有大小寫混用的對象名,比如CustomerData。這一問題從Access 到Oracle 數據庫都存在。我不喜歡采

    用這種大小寫混用的對象命名方法,結果還不得不手工修改名字。想想看,這種數據庫/應用程序能混到采用更強大數據庫的那一天嗎?采用全部

    大寫而且包含下劃符的名字具有更好的可讀性(CUSTOMER_DATA),絕對不要在對象名的字符之間留空格。

    17. 小心保留詞

    要保證你的字段名沒有和保留詞、數據庫系統或者常用訪問方法沖突,比如,最近我編寫的一個ODBC 連接程序里有個表,其中就用了DESC 作為說

    明字段名。后果可想而知!DESC 是DESCENDING 縮寫后的保留詞。表里的一個SELECT *語句倒是能用,但我得到的卻是一大堆毫無用處的信息。

    18. 保持字段名和類型的一致性

    在命名字段并為其指定數據類型的時候一定要保證一致性。假如字段在某個表中叫做“agreement_number”,你就別在另一個表里把名字改成

    “ref1”。假如數據類型在一個表里是整數,那在另一個表里可就別變成字符型了。記住,你干完自己的活了,其他人還要用你的數據庫呢。

    19. 仔細選擇數字類型

    在SQL 中使用smallint 和tinyint 類型要特別小心,比如,假如你想看看月銷售總額,你的總額字段類型是smallint,那么,如果總額超過了

    ,767 你就不能進行計算操作了。

    20. 刪除標記

    在表中包含一個“刪除標記”字段,這樣就可以把行標記為刪除。在關系數據庫里不要單獨刪除

    某一行;最好采用清除數據程序而且要仔細維護索引整體性。

    21. 避免使用觸發器

    觸發器的功能通常可以用其他方式實現。在調試程序時觸發器可能成為干擾。假如你確實需要采用觸發器,你最好集中對它文檔化。

    22. 包含版本機制

    建議你在數據庫中引入版本控制機制來確定使用中的數據庫的版本。無論如何你都要實現這一要求。時間一長,用戶的需求總是會改變的。最終可

    能會要求修改數據庫結構。雖然你可以通過檢查新字段或者索引來確定數據庫結構的版本,但我發現把版本信息直接存放到數據庫中不更為方便

    嗎?。

    23. 給文本字段留足余量

    ID 類型的文本字段,比如客戶ID 或定單號等等都應該設置得比一般想象更大,因為時間不長你多半就會因為要添加額外的字符而難堪不已。比方

    說,假設你的客戶ID 為10 位數長。那你應該把數據庫表字段的長度設為12 或者13 個字符長。這算浪費空間嗎?是有一點,但也沒你想象的那么

    多:一個字段加長3 個字符在有1 百萬條記錄,再加上一點索引的情況下才不過讓整個數據庫多占據3MB 的空間。但這額外占據的空間卻無需將來

    重構整個數據庫就可以實現數據庫規模的增長了。

    24. 列命名技巧

    我們發現,假如你給每個表的列名都采用統一的前綴,那么在編寫SQL 表達式的時候會得到大大的簡化。這樣做也確實有缺點,比如破壞了自動表

    連接工具的作用,后者把公共列名同某些數據庫聯系起來,不過就連這些工具有時不也連接錯誤嘛。舉個簡單的例子,假設有兩個表:Customer

    和Order。Customer 表的前綴是cu_,所以該表內的子段名如下:cu_name_id、cu_surname、cu_initials 和cu_address 等。Order 表的前綴

    是or_,所以子段名是:or_order_id、or_cust_name_id、or_quantity 和or_description 等。

    這樣從數據庫中選出全部數據的 SQL 語句可以寫成如下所示:

    Select * from Customer, Order

    Where cu_surname="MYNAME"

    and cu_name_id=or_cust_name_id

    and or_quantity=1;

    在沒有這些前綴的情況下則寫成這個樣子:

    Select * from Customer, Order

    Where Customer.surname="MYNAME"

    and Customer.name_id=Order.cust_name_id

    and Order.quantity=1

    第 1 個SQL 語句沒少鍵入多少字符。但如果查詢涉及到5 個表乃至更多的列你就知道這個技巧多有用了。

    第 3 部分- 選擇鍵和索引

    1. 數據采掘要預先計劃

    我所在的市場部門一度要處理8 萬多份聯系方式,同時填寫每個客戶的必要數據(這絕對不是小活)。我從中還要確定出一組客戶作為市場目標。

    當我從最開始設計表和字段的時候,我試圖不在主索引里增加太多的字段以便加快數據庫的運行速度。然后我意識到特定的組查詢和信息采掘既不

    準確速度也不快。結果只好在主索引中重建而且合并了數據字段。我發現有一個指示計劃相當關鍵--當我想創建系統類型查找時為什么要采用號碼

    作為主索引字段呢?我可以用傳真號碼進行檢索,但是它幾乎就象系統類型一樣對我來說并不重要。采用后者作為主字段,數據庫更新后重新索引

    和檢索就快多了。可操作數據倉庫(ODS)和數據倉庫(DW)這兩種環境下的數據索引是有差別的。在DW 環境下,你要考慮銷售部門是如何組織銷

    售活動的。他們并不是數據庫管理員,但是他們確定表內的鍵信息。這里設計人員或者數據庫工作人員應該分析數據庫結構從而確定出性能和正確

    輸出之間的最佳條件。

    2. 使用系統生成的主鍵

    這一天類同技巧1,但我覺得有必要在這里重復提醒大家。假如你總是在設計數據庫的時候采用系統生成的鍵作為主鍵,那么你實際控制了數據庫

    的索引完整性。這樣,數據庫和非人工機制就有效地控制了對存儲數據中每一行的訪問。

    采用系統生成鍵作為主鍵還有一個優點:當你擁有一致的鍵結構時,找到邏輯缺陷很容易。

    3. 分解字段用于索引

    為了分離命名字段和包含字段以支持用戶定義的報表,請考慮分解其他字段(甚至主鍵)為其組成要素以便用戶可以對其進行索引。索引將加快

    SQL 和報表生成器腳本的執行速度。比方說,我通常在必須使用SQL LIKE 表達式的情況下創建報表,因為 case number 字段無法分解為year、

    serial number、case type 和defendant code 等要素。性能也會變壞。假如年度和類型字段可以分解為索引字段那么這些報表運行起來就會快

    多了。

    4. 鍵設計4 原則

    · 為關聯字段創建外鍵。

    · 所有的鍵都必須唯一。

    · 避免使用復合鍵。

    · 外鍵總是關聯唯一的鍵字段。

    5. 別忘了索引

    索引是從數據庫中獲取數據的最高效方式之一。95%的數據庫性能問題都可以采用索引技術得到解決。作為一條規則,我通常對邏輯主鍵使用唯一

    的成組索引,對系統鍵(作為存儲過程)采用唯一的非成組索引,對任何外鍵列采用非成組索引。不過,索引就象是鹽,太多了菜就篌了。你得考

    慮數據庫的空間有多大,表如何進行訪問,還有這些訪問是否主要用作讀寫。大多數數據庫都索引自動創建的主鍵字段,但是可別忘了索引外鍵,

    它們也是經常使用的鍵,比如運行查詢顯示主表和所有關聯表的某條記錄就用得上。還有,不要索引memo/note 字段,不要索引大型字段(有很多

    字符),這樣作會讓索引占用太多的存儲空間。

    6. 不要索引常用的小型表

    不要為小型數據表設置任何鍵,假如它們經常有插入和刪除操作就更別這樣作了。對這些插入和刪除操作的索引維護可能比掃描表空間消耗更多的

    時間。

    7. 不要把社會保障號碼(SSN)選作鍵

    永遠都不要使用SSN 作為數據庫的鍵。除了隱私原因以外,須知政府越來越趨向于不準許把SSN 用作除收入相關以外的其他目的,SSN 需要手工輸

    入。永遠不要使用手工輸入的鍵作為主鍵,因為一旦你輸入錯誤,你唯一能做的就是刪除整個記錄然后從頭開始。上個世紀 70 年代我還在讀大學

    的時候,我記得那時SSN 還曾被用做學號,當然盡管這么做是非法的。而且人們也都知道這是非法的,但他們已經習慣了。后來,隨著盜取身份犯

    罪案件的增加,我現在的大學校園正痛苦地從一大攤子數據中把SSN 刪除。

    8. 不要用用戶的鍵

    在確定采用什么字段作為表的鍵的時候,可一定要小心用戶將要編輯的字段。通常的情況下不要選擇用戶可編輯的字段作為鍵。這樣做會迫使你采

    取以下兩個措施:

    · 在創建記錄之后對用戶編輯字段的行為施加限制。假如你這么做了,你可能會發現你的應用程序在商務需求突然發生變化,而用戶需要編輯那些

    不可編輯的字段時缺乏足夠的靈活性。當用戶在輸入數據之后直到保存記錄才發現系統出了問題他們該怎么想?刪除重建?假如記錄不可重建是否

    讓用戶走開?

    · 提出一些檢測和糾正鍵沖突的方法。通常,費點精力也就搞定了,但是從性能上來看這樣做的代價就比較大了。還有,鍵的糾正可能會迫使你突

    破你的數據和商業/用戶界面層之間的隔離。

    所以還是重提一句老話:你的設計要適應用戶而不是讓用戶來適應你的設計。不讓主鍵具有可更新性的原因是在關系模式下,主鍵實現了不同表之

    間的關聯。比如,Customer 表有一個主鍵CustomerID,而客戶的定單則存放在另一個表里。Order 表的主鍵可能是 OrderNo 或者OrderNo、

    CustomerID 和日期的組合。不管你選擇哪種鍵設置,你都需要在Order 表中存放CustomerID 來保證你可以給下定單的用戶找到其定單記錄。

    假如你在 Customer 表里修改了CustomerID,那么你必須找出Order 表中的所有相關記錄對其進行修改。否則,有些定單就會不屬于任何客戶--

    數據庫的完整性就算完蛋了。如果索引完整性規則施加到表一級,那么在不編寫大量代碼和附加刪除記錄的情況下幾乎不可能改變某一條記錄的鍵

    和數據庫內所有關聯的記錄。而這一過程往往錯誤叢生所以應該盡量避免。

    9. 可選鍵有時可做主鍵

    記住,查詢數據的不是機器而是人。假如你有可選鍵,你可能進一步把它用做主鍵。那樣的話,你就擁有了建立強大索引的能力。這樣可以阻止使

    用數據庫的人不得不連接數據庫從而恰當的過濾數據。在嚴格控制域表的數據庫上,這種負載是比較醒目的。如果可選鍵真正有用,那就是達到了

    主鍵的水準。我的看法是,假如你有可選鍵,比如國家表內的state_code,你不要在現有不能變動的唯一鍵上創建后續的鍵。你要做的無非是創建

    毫無價值的數據。比如以下的例子:

    Select count(*)

    from address, state_ref

    where

    address.state_id=state_ref.state_id

    and state_ref.state_code='TN'

    我的做法是這樣的:

    Select count(*)

    from address

    where

    and state_code='TN'

    如你因為過度使用表的后續鍵建立這種表的關聯,操作負載真得需要考慮一下了。

    10. 別忘了外鍵

    大多數數據庫索引自動創建的主鍵字段。但別忘了索引外鍵字段,它們在你想查詢主表中的記錄及其關聯記錄時每次都會用到。還有,不要索引

    memo/notes 字段而且不要索引大型文本字段(許多字符),這樣做會讓你的索引占據大量的數據庫空間。。

    第 4 部分- 保證數據的完整性

    1. 用約束而非商務規則強制數據完整性

    如果你按照商務規則來處理需求,那么你應當檢查商務層次/用戶界面:如果商務規則以后發生變化,那么只需要進行更新即可。假如需求源于維

    護數據完整性的需要,那么在數據庫層面上需要施加限制條件。如果你在數據層確實采用了約束,你要保證有辦法把更新不能通過約束檢查的原因

    采用用戶理解的語言通知用戶界面。除非你的字段命名很冗長,否則字段名本身還不夠。只要有可能,請采用數據庫系統實現數據的完整性。這不

    但包括通過標準化實現的完整性而且還包括數據的功能性。在寫數據的時候還可以增加觸發器來保證數據的正確性。不要依賴于商務層保證數據完

    整性;它不能保證表之間(外鍵)的完整性所以不能強加于其他完整性規則之上。

    2. 分布式數據系統

    對分布式系統而言,在你決定是否在各個站點復制所有數據還是把數據保存在一個地方之前應該估計一下未來5 年或者10 年的數據量。當你把數

    據傳送到其他站點的時候,最好在數據庫字段中設置一些標記。在目的站點收到你的數據之后更新你的標記。為了進行這種數據傳輸,請寫下你自

    己的批處理或者調度程序以特定時間間隔運行而不要讓用戶在每天的工作后傳輸數據。本地拷貝你的維護數據,比如計算常數和利息率等,設置版

    本號保證數據在每個站點都完全一致。

    3. 強制指示完整性

    沒有好辦法能在有害數據進入數據庫之后消除它,所以你應該在它進入數據庫之前將其剔除。激活數據庫系統的指示完整性特性。這樣可以保持數

    據的清潔而能迫使開發人員投入更多的時間處理錯誤條件。

    4. 關系

    如果兩個實體之間存在多對一關系,而且還有可能轉化為多對多關系,那么你最好一開始就設置成多對多關系。從現有的多對一關系轉變為多對多

    關系比一開始就是多對多關系要難得多。

    5. 采用視圖

    為了在你的數據庫和你的應用程序代碼之間提供另一層抽象,你可以為你的應用程序建立專門的視圖而不必非要應用程序直接訪問數據表。這樣做

    還等于在處理數據庫變更時給你提供了更多的自由。

    6. 給數據保有和恢復制定計劃

    考慮數據保有策略并包含在設計過程中,預先設計你的數據恢復過程。采用可以發布給用戶/開發人員的數據字典實現方便的數據識別同時保證對

    數據源文檔化。編寫在線更新來“更新查詢”供以后萬一數據丟失可以重新處理更新。

    7. 用存儲過程讓系統做重活

    解決了許多麻煩來產生一個具有高度完整性的數據庫解決方案之后,我所在的團隊決定封裝一些關聯表的功能組,提供一整套常規的存儲過程來訪

    問各組以便加快速度和簡化客戶程序代碼的開發。在此期間,我們發現3GL 編碼器設置了所有可能的錯誤條件,比如以下所示:

    SELECT Cnt=COUNT (*)

    FROM [<Table>]

    WHERE [<primary key column>]=<new value>

    IF Cnt=0

    BEGIN

    INSERT INTO [<Table>]

    ( [< primary key column>] )

    VALUES ( <New value> )

    END

    ELSE

    BEGIN

    <indicate duplication error>

    END

    而一個非 3GL 編碼器是這樣做的:

    INSERT INTO [<Table>]

    ( [< primary key column>] )

    VALUES

    ( <New value> )

    IF @@ERROR=2627 -- Literal error code for Primary Key Constraint

    BEGIN

    <indicate duplication error>

    END

    第 2 個程序簡單多了,而且事實上,利用了我們給數據庫的功能。雖然我個人不喜歡使用嵌入文字(2627)。但是那樣可以很方便地用一點預先

    處理來代替。數據庫不只是一個存放數據的地方,它也是簡化編碼之地。

    8. 使用查找

    控制數據完整性的最佳方式就是限制用戶的選擇。只要有可能都應該提供給用戶一個清晰的價值列表供其選擇。這樣將減少鍵入代碼的錯誤和誤解

    同時提供數據的一致性。某些公共數據特別適合查找:國家代碼、狀態代碼等。

    第 5 部分- 各種小技巧

    1. 文檔、文檔、文檔

    對所有的快捷方式、命名規范、限制和函數都要編制文檔。采用給表、列、觸發器等加注釋的數據庫工具。是的,這有點費事,但從長遠來看,這

    樣做對開發、支持和跟蹤修改非常有用。取決于你使用的數據庫系統,可能有一些軟件會給你一些供你很快上手的文檔。你可能希望先開始在說,

    然后獲得越來越多的細節。或者你可能希望周期性的預排,在輸入新數據同時隨著你的進展對每一部分細節化。不管你選擇哪種方式,總要對你的

    數據庫文檔化,或者在數據庫自身的內部或者單獨建立文檔。這樣,當你過了一年多時間后再回過頭來做第2 個版本,你犯錯的機會將大大減少。

    2. 使用常用英語(或者其他任何語言)而不要使用編碼

    為什么我們經常采用編碼(比如9935A 可能是墨水筆的供應代碼,4XF788-Q 可能是帳目編碼)?理由很多。但是用戶通常都用英語進行思考而不

    是編碼。工作5 年的會計或許知道4XF788-Q 是什么東西,但新來的可就不一定了。在創建下拉菜單、列表、報表時最好按照英語名排序。假如你

    需要編碼,那你可以在編碼旁附上用戶知道的英語。

    3. 保存常用信息

    讓一個表專門存放一般數據庫信息非常有用。我常在這個表里存放數據庫當前版本、最近檢查/修復(對Access)、關聯設計文檔的名稱、客戶等

    信息。這樣可以實現一種簡單機制跟蹤數據庫,當客戶抱怨他們的數據庫沒有達到希望的要求而與你聯系時,這樣做對非客戶機/服務器環境特別

    有用。

    4. 測試、測試、反復測試

    建立或者修訂數據庫之后,必須用用戶新輸入的數據測試數據字段。最重要的是,讓用戶進行測試并且同用戶一道保證你選擇的數據類型滿足商業

    要求。測試需要在把新數據庫投入實際服務之前完成。

    5. 檢查設計

    在開發期間檢查數據庫設計的常用技術是通過其所支持的應用程序原型檢查數據庫。換句話說,針對每一種最終表達數據的原型應用,保證你檢查

    了數據模型并且查看如何取出數據。

    6. Access 設計技巧

    對復雜的Microsoft Access 數據庫應用程序而言,可以把所有的主表放在一個數據庫文件里,然后增加其他數據庫文件和裝載同原有數據庫有關

    的特殊函數。根據需要用這些函數連接到主文件中的主表。比如數據輸入、數據QC、統計分析、向管理層或者政府部門提供報表以及各類只讀查詢

    等。這一措施簡化了用戶和組權限的分配,而且有利于應用程序函數的分組和劃分,從而在程序必須修改的時候易于管理。

    Made by e-Stack Room

    http://www.mycnknow.com

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有