国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
VBA編程問(wèn)答(第1輯)

VBA編程問(wèn)答(第1輯)

VBA編程問(wèn)答
(第1輯)
在學(xué)習(xí)ExcelVBA編程的過(guò)程中,經(jīng)常會(huì)遇到一些問(wèn)題,有些可能是新碰到的,有些則是以前已遇到過(guò)但暫時(shí)忘掉了解決辦法的,VBA編程問(wèn)答將把我所收集到的問(wèn)題和自已所遇到的問(wèn)題及解決辦法進(jìn)行歸納整理,以方便查閱和參考。
在下面的內(nèi)容中,有大量的程序代碼,您可以將它們輸入或復(fù)制到VBE編輯器中進(jìn)行調(diào)試,也可以將它們進(jìn)行適當(dāng)?shù)恼{(diào)整和修改后應(yīng)用到自已的程序中。有些問(wèn)答提供了參考示例,您可以直接下載后處理。
本輯目錄
問(wèn)題1:如何優(yōu)化VBA代碼并使程序盡可能快的運(yùn)行?
問(wèn)題2:如何禁用用戶(hù)窗體的關(guān)閉按鈕?
問(wèn)題3:可以撤銷(xiāo)所執(zhí)行的操作嗎?
問(wèn)題4:如何將同一文件夾中的多個(gè)文本文件讀入到工作簿中?
問(wèn)題5:如何使用VBA刪除所有的空工作表
問(wèn)題6:如何獲取計(jì)算機(jī)上可供使用的打印機(jī)列表?
問(wèn)題7:如何基于某個(gè)單元格更新其它單元格的日期
問(wèn)題8:如何編寫(xiě)一個(gè)宏程序運(yùn)行另一個(gè)宏程序特定的次數(shù)?
問(wèn)題9:如何在一個(gè)組合框中列出所有工作表中單元格D3中的值?
問(wèn)題10:如何使工作表中的文本閃爍?
問(wèn)題11:如何將工作簿中其它工作表名導(dǎo)入到指定的工作表中?
問(wèn)題12:如何在單元格中快速輸入帶秒的時(shí)間?
=====================================================================
問(wèn)題1:如何優(yōu)化VBA代碼并使程序盡可能快的運(yùn)行?
解答:

速度問(wèn)題一直是VBA程序值得關(guān)注的一個(gè)方面。當(dāng)您編寫(xiě)了一個(gè)對(duì)大量數(shù)據(jù)進(jìn)行操作的程序后,在運(yùn)行時(shí)可能會(huì)發(fā)現(xiàn)程序運(yùn)行得很慢,有的甚至達(dá)好幾分鐘,就像Excel應(yīng)用程序已崩潰了一樣。但當(dāng)您發(fā)現(xiàn)程序確實(shí)在運(yùn)行,并得到正確的結(jié)果后,您可能就會(huì)想到如何使程序更快的運(yùn)行了。當(dāng)然,代碼運(yùn)行速度慢可能是VBA程序的一個(gè)缺點(diǎn),這也可能是程序語(yǔ)言本身的一個(gè)原因,但我們也可以找到一些方法優(yōu)化VBA代碼并使程序盡可能快的運(yùn)行。
下面是我整理的一些優(yōu)化VBA代碼或提高程序運(yùn)行速度的方法,有些方法是我們?cè)诰幊讨泻玫淖龇ê蛻?yīng)該養(yǎng)成的好習(xí)慣,希望能帶給您一些有益的參考。高質(zhì)量的程序和運(yùn)行效率是需要不斷實(shí)踐,并在實(shí)踐中不斷總結(jié)和積累經(jīng)驗(yàn)的,也希望您能將在編寫(xiě)程序過(guò)程中發(fā)現(xiàn)的一些優(yōu)化方法介紹給大家共享。
1、盡量簡(jiǎn)化代碼
通過(guò)簡(jiǎn)化代碼,可以提高程序的性能。您可以將通用過(guò)程編寫(xiě)為子過(guò)程來(lái)調(diào)用。例如,假設(shè)有一個(gè)應(yīng)用程序需要在不同的地方實(shí)現(xiàn)查找一定范圍內(nèi)的某個(gè)特殊條目,在一個(gè)沒(méi)有簡(jiǎn)化代碼的應(yīng)用程序中,不同的過(guò)程可能需要應(yīng)用各自的算法以實(shí)現(xiàn)在某個(gè)范圍內(nèi)查找某一條目,修改每個(gè)過(guò)程使其采用一個(gè)更有效的算法并不是一件很容易的事。而一個(gè)簡(jiǎn)化的程序則只有一個(gè)查找算法,即將該查找算法編寫(xiě)成通用的子程序,需要查找某個(gè)范圍的過(guò)程都調(diào)用該子程序,通過(guò)在查找方法的子程序中優(yōu)化查找算法,使得調(diào)用該方法的所有過(guò)程都享受性能提高所帶來(lái)的好處。
另外,刪除所有無(wú)關(guān)的代碼,這在所錄制宏中表現(xiàn)得尤為明顯。在錄制宏時(shí),經(jīng)常會(huì)產(chǎn)生一些與所實(shí)現(xiàn)的功能無(wú)關(guān)的代碼,您可以將這些代碼刪除,以使得代碼得以簡(jiǎn)化。
在下面將要講到的設(shè)置對(duì)象變量代替長(zhǎng)對(duì)象引用,使用With…End With語(yǔ)句、執(zhí)行For Each…Next循環(huán)語(yǔ)句,根據(jù)程序環(huán)境盡量減少OLE引用,等等,均是簡(jiǎn)化代碼的好方法。
2、強(qiáng)制聲明變量
在VBE編輯器中的菜單“工具——選項(xiàng)”對(duì)話框中“編輯器”選項(xiàng)卡中,您應(yīng)該始終保持“要求變量聲明”復(fù)選框被選中,這樣將在模塊代碼頂部出現(xiàn)Option Explicit語(yǔ)句,要求您在編寫(xiě)代碼時(shí)對(duì)所有出現(xiàn)的變量均進(jìn)行聲明,這樣,在使用變量時(shí)減少內(nèi)存需求并加速性能。
(1)要節(jié)省內(nèi)存資源,必須始終用特定的數(shù)據(jù)類(lèi)型聲明所有變量。如果不使用特定的數(shù)據(jù)類(lèi)型聲明變量,VBA會(huì)創(chuàng)建Variant類(lèi)型的變量,這將比任何其他數(shù)據(jù)類(lèi)型要求更多的內(nèi)存。
(2)清楚每種數(shù)據(jù)類(lèi)型需要多少內(nèi)存以及它可以存儲(chǔ)的值的范圍。除使用較小的數(shù)據(jù)類(lèi)型會(huì)導(dǎo)致隱性轉(zhuǎn)換的情況外,應(yīng)始終使用盡可能小的數(shù)據(jù)類(lèi)型。例如,因?yàn)镮nteger類(lèi)型的變量將被轉(zhuǎn)換成Long類(lèi)型的變量,應(yīng)該將那些存儲(chǔ)整型值的變量聲明為L(zhǎng)ong類(lèi)型,而不是Integer類(lèi)型。
(3)除非確實(shí)需要,應(yīng)避免使用浮點(diǎn)數(shù)據(jù)類(lèi)型。盡管Currency數(shù)據(jù)類(lèi)型更大,但它比 Single 數(shù)據(jù)類(lèi)型快,因?yàn)镃urrency數(shù)據(jù)類(lèi)型不使用浮點(diǎn)處理器。
(4)如果在一個(gè)過(guò)程中多次引用一個(gè)對(duì)象,可以創(chuàng)建對(duì)象變量,并將對(duì)給對(duì)象的引用指派給它。因?yàn)閷?duì)象變量存儲(chǔ)對(duì)象在內(nèi)存中的位置,VBA將不必再次查找其位置。
(5)將對(duì)象變量聲明為特定的類(lèi)型(不是Object類(lèi)型),以便利用早期綁定。
3、減少變量的作用范圍并及時(shí)釋放變量
主要是對(duì)象變量,在其使用完后,及時(shí)釋放。例如,
Dim TempObj As AnyObject,AnObj As AnyObject
Set TempObj=New AnyObject
Set AnObj=TempObj
Set TempObj=Nothing ‘釋放對(duì)象變量
4、盡可能使用早期綁定
綁定是指將程序調(diào)用與實(shí)際代碼相匹配。為了實(shí)現(xiàn)早期綁定,先應(yīng)創(chuàng)建對(duì)對(duì)象庫(kù)的引用。早期綁定可以在代碼中使用定義在對(duì)象庫(kù)中的常量,可以自動(dòng)列出對(duì)象的方法和屬性,但早期綁定只有在所控制的對(duì)象擁有獨(dú)立的類(lèi)型庫(kù)或?qū)ο髱?kù)文件才適用且還需要已安裝了特定的庫(kù)。而后期綁定則只是在運(yùn)行時(shí)才知道對(duì)象的類(lèi)型并對(duì)對(duì)象進(jìn)行引用,因此不具備上述特點(diǎn)。
使用早期綁定創(chuàng)建對(duì)象通常更有效率,使代碼能獲得更好的性能。因?yàn)閷?duì)象的早期綁定引用在編譯時(shí)可以通過(guò)VBE的解析,而不是通過(guò)運(yùn)行時(shí)模塊解析,因此早期綁定的性能要好得多。雖然在程序設(shè)計(jì)時(shí)不可能總是使用早期綁定,但應(yīng)該盡可能使用它。
5、關(guān)閉屏幕刷新
在Excel中,其ScreenUpdating屬性值的默認(rèn)值為T(mén)rue,這樣當(dāng)寫(xiě)數(shù)據(jù)到工作表或者執(zhí)行任何導(dǎo)致其顯示屬性變化的動(dòng)作時(shí),Excel的屏幕界面將會(huì)不斷的刷新,不僅影響顯示,而且影響程序運(yùn)行的速度。您可以在進(jìn)入主程序運(yùn)行前將屏幕刷新屬性關(guān)閉,即用Application.ScreenUpdating = False語(yǔ)句關(guān)閉屏幕刷新,這樣將大大改善程序的運(yùn)行速度。
但在程序運(yùn)行完成前,要確保將其恢復(fù)為原來(lái)的設(shè)置,即將ScreenUpdating屬性的值設(shè)置為T(mén)rue。因?yàn)槟鷮?duì)該屬性的修改是永久性的修改,Excel不會(huì)為您自動(dòng)恢復(fù)其默認(rèn)值,您必須用語(yǔ)句Application.ScreenUpdating = True恢復(fù)設(shè)置。
6、設(shè)置計(jì)算模式為手動(dòng)
如果您的工作表中含有多個(gè)公式,在每次單元格中的值發(fā)生變化時(shí),公式都將會(huì)重新計(jì)算,這會(huì)影響程序運(yùn)行速度。您可以在進(jìn)入主程序運(yùn)行前,將計(jì)算模式設(shè)置為手動(dòng),即使用如下語(yǔ)句Application.Calculation = xlCalculationManual,以避免不必要的計(jì)算。
當(dāng)程序運(yùn)行結(jié)束前,您要恢復(fù)Excel的默認(rèn)計(jì)算模式設(shè)置,即設(shè)置為自動(dòng)重算,可使用下面的語(yǔ)句Application.Calculation = xlCalculationAutomatic,這同ScreenUpdating屬性一樣,Excel不會(huì)自動(dòng)恢復(fù)其為默認(rèn)值。Calculation屬性是對(duì)所有工作簿進(jìn)行的設(shè)置,您也可以用工作表的EnableCalculation屬性來(lái)設(shè)置對(duì)某個(gè)工作表是否進(jìn)行重新計(jì)算。
7、使用For Each…Next循環(huán)
可以使用For Each…Next循環(huán)來(lái)保證程序代碼更快地執(zhí)行。在使用For Each…Next循環(huán)時(shí),對(duì)于存儲(chǔ)在集合或數(shù)組中的每個(gè)對(duì)象執(zhí)行一組語(yǔ)句,程序更簡(jiǎn)潔,也更容易閱讀、調(diào)試和維護(hù)。當(dāng)For Each…Next語(yǔ)句迭代集合時(shí),自動(dòng)指定一個(gè)對(duì)集合當(dāng)前成員的引用,然后在到達(dá)集合的尾部時(shí)跳出循環(huán)語(yǔ)句。
8、使用With…End With語(yǔ)句
可以使用With…End With語(yǔ)句來(lái)盡量減少對(duì)象引用。使用With語(yǔ)句對(duì)指定的對(duì)象完成一系列的任務(wù),而不用重復(fù)引用對(duì)象。也可以使用嵌套的With語(yǔ)句進(jìn)一步提高程序代碼的效率。例如,下面的使用With…End With語(yǔ)句是在同一個(gè)單元格中執(zhí)行多個(gè)操作。
With Workbooks(“Book1.xls”).Worksheets(“Sheet1”).Range(“A1”)
.Formula=”=SQRT(20)”
With .Font
  .Name=”Arial”
  .Bold=True
  .Size=10
End With
End With
同理,可使用With…End With語(yǔ)句在同一個(gè)單元格區(qū)域中執(zhí)行多個(gè)操作。
9、在執(zhí)行循環(huán)時(shí)考慮如何能夠盡可能地節(jié)省資源
(1)分析循環(huán)以查看是否正在不必要地執(zhí)行一些消耗內(nèi)存的重復(fù)操作。例如,是否可以在循環(huán)外(而不是在循環(huán)中)設(shè)置某些變量?每次都通過(guò)循環(huán)執(zhí)行的轉(zhuǎn)換過(guò)程是否可以在循環(huán)之外執(zhí)行?
(2)考慮是否必須在滿足特定的條件時(shí)才執(zhí)行循環(huán)。如果是,也許可以更早地退出循環(huán)。例如,假設(shè)正在對(duì)一個(gè)不應(yīng)該包含數(shù)字字符的字符串進(jìn)行數(shù)據(jù)驗(yàn)證。如果循環(huán)要檢查字符串中的每個(gè)字符以確定其中是否包含數(shù)字字符,那么您可以在找到第一個(gè)數(shù)字字符時(shí)立即退出循環(huán)。
(3)如果必須在循環(huán)中引用數(shù)組的元素,可以創(chuàng)建一個(gè)臨時(shí)變量存儲(chǔ)該元素的值,而不是引用數(shù)組中的值。從數(shù)組中檢索值比從相同類(lèi)型的變量讀取值要慢。
10、盡量減少OLE引用
可以通過(guò)盡量減少在VBA程序代碼中使用OLE(對(duì)象鏈接與嵌入自動(dòng)識(shí)別)引用來(lái)優(yōu)化程序代碼。VBA語(yǔ)句中所調(diào)用的方法和屬性越多,執(zhí)行語(yǔ)句所用的時(shí)間就越多。例如下面的兩個(gè)語(yǔ)句:
語(yǔ)句1:Workbooks(1).Sheets(1).Range(“A1”).Value=10
語(yǔ)句2:ActiveWindow.Left=200
執(zhí)行時(shí),語(yǔ)句2比語(yǔ)句1快。
同樣,上面所講的對(duì)重復(fù)使用的對(duì)象引用指定一個(gè)變量,通過(guò)調(diào)用變量從而保證避免多次進(jìn)行對(duì)象引用。
11、避免對(duì)象激活或者不需要先進(jìn)行先擇
在使用宏錄制器時(shí),所生成的程序代碼在應(yīng)用任何方法或?qū)傩灾岸紩?huì)激活或者選擇對(duì)象。但是,并不是在所有的情況下都需要這樣做。所以,在您編寫(xiě)VBA程序代碼時(shí),不需要在對(duì)對(duì)象執(zhí)行任何任務(wù)之前都激活或者選擇每個(gè)對(duì)象。
例如,在Excel中,我們?nèi)绻沟谝恍凶兂纱煮w就必須先選項(xiàng)中它。但在VBA中(除在圖表操作時(shí)需要選中圖表對(duì)象外),很少需要這樣做,即VBA可以在不選中第一行的情況下,將它變成粗體。
宏錄制器的代碼:
Rows("1:1").Select
Selection.Font.Bold = True
改編后的代碼為:
Row(“1:1”).Font.Bold=True
這樣做還可以使程序代碼更簡(jiǎn)潔,并且程序可以運(yùn)行得更快。
12、在一個(gè)語(yǔ)句中進(jìn)行復(fù)制或者粘貼
在用宏錄制代碼時(shí),首先是選擇一個(gè)區(qū)域,然后再執(zhí)行ActiveSheet.Paste。在使用Copy方法時(shí),可以在一個(gè)語(yǔ)句中指定復(fù)制的內(nèi)容及要復(fù)制到的目的地。
例如,將B5:C6區(qū)域的內(nèi)容復(fù)制到以單元格B8開(kāi)始的區(qū)域中,使用宏錄制器的代碼為:
Range("B5:C6").Select
Selection.Copy
Range("B8").Select
ActiveSheet.Paste
經(jīng)修改后的最佳代碼是:
Range("B5:C6").Copy Destination:=Range("B8")
13、盡可能少使用“.”
在前面已經(jīng)介紹過(guò)的對(duì)長(zhǎng)對(duì)象引用使用對(duì)象變量以及使用With…End With等都是簡(jiǎn)化”.”的方法。因?yàn)樵诖a中的每個(gè)句點(diǎn)都表示至少一個(gè)(而且可能是多個(gè))過(guò)程調(diào)用,而這些過(guò)程調(diào)用必須在后臺(tái)執(zhí)行。真正好的做法是在局部進(jìn)行緩存對(duì)象引用,例如,應(yīng)該把對(duì)象模型中較高層次的對(duì)象引用保存到局部對(duì)象變量中,然后用這些對(duì)象引用創(chuàng)建其他較低層次的對(duì)象引用。例如,引用某單元格數(shù)據(jù)時(shí),可用如下代碼:
Dim i As Long
For i=1 to 10
  Workbooks(“Book1.xls”).Worksheets(“Sheet1”).Cells(1,i).Value=i
Next i
但下面的代碼運(yùn)行效率更高,因?yàn)榇a中引用Workbook對(duì)象和Worksheet對(duì)象的調(diào)用命令只執(zhí)行一次,而上面的代碼中卻要執(zhí)行10次。
Dim ws As Worksheet
Dim i As Long
Set ws= Workbooks(“Book1.xls”).Worksheets(“Sheet1”)
For i=1 to 10
  ws.Cells(1,i).Value=i
Next i
14、合理地使用消息框和窗體
在一個(gè)很長(zhǎng)的程序中,償試著將消息框或者窗體安排顯示在程序的最開(kāi)始或最后面,避免干擾用戶(hù)。此外,盡管窗體提供了許多功能,但它們能夠?qū)е挛募笮⊙杆僭黾?。還有就是盡量避免給工作表單元格鏈接用戶(hù)窗體控件,因?yàn)檫@樣將會(huì)導(dǎo)致鏈接更新操作,影響程序運(yùn)行速度。
15、盡可能加速對(duì)數(shù)字的運(yùn)算
(1)當(dāng)對(duì)整數(shù)進(jìn)行除法時(shí),您可以使用整型除法運(yùn)算符(\)而不是浮點(diǎn)除法運(yùn)算符(/),因?yàn)闊o(wú)論參與除法運(yùn)算的數(shù)值類(lèi)型如何,浮點(diǎn)除法運(yùn)算符總會(huì)返回Double類(lèi)型的值。
(2)在任何具有整數(shù)值的算術(shù)表達(dá)式中使用Single或Double值時(shí),整數(shù)均將被轉(zhuǎn)換成Single或Double值,最后的結(jié)果將是Single或Double值。如果要對(duì)作為算術(shù)運(yùn)算結(jié)果的數(shù)字執(zhí)行多次操作,可能需要明確地將該數(shù)字轉(zhuǎn)換為較小的數(shù)據(jù)類(lèi)型。
16、提高字符串操作的性能
(1)盡可能少使用連接操作??梢栽诘忍?hào)左邊使用Mid函數(shù)替換字符串中的字符,而不是將它們連接在一起。使用 Mid 函數(shù)的缺點(diǎn)是替換字符串必須與要替換的子字符串的長(zhǎng)度相同。例如,
Dim strText As String
strText = "this is a test"
Mid(strText, 11, 4) = "tent"
(2)VBA提供許多可用來(lái)替換函數(shù)調(diào)用的內(nèi)部字符串常量。例如,可以使用vbCrLf常量來(lái)表示字符串中的回車(chē)/換行組合,而不是使用Chr(13) & Chr(10)。
(3)字符串比較操作的執(zhí)行速度很慢。有時(shí),可以通過(guò)將字符串中的字符轉(zhuǎn)換為 ANSI 值來(lái)避免這些操作。例如,下列代碼會(huì)檢查字符串中的第一個(gè)字符是否為空格:
If Asc(strText) = 32 Then
上面的代碼會(huì)比以下代碼更快:
If Left(strText, 1) = " " Then
17、使用Asc()檢驗(yàn)ANSI的值
在VBA中,可以使用Chr$()函數(shù)把數(shù)轉(zhuǎn)換成字符,并確定ANSI的值,但是更好的是使用Asc()函數(shù)把字符串轉(zhuǎn)換成數(shù)值,然后確定它的ANSI值。如果需要進(jìn)行有限次數(shù)的這種檢驗(yàn),對(duì)程序代碼的效率可能不會(huì)產(chǎn)生很大影響,但是,如果需要在多個(gè)循環(huán)內(nèi)進(jìn)行這種檢驗(yàn)時(shí),這將節(jié)省處理時(shí)間并且有助于程序代碼更快地執(zhí)行。
18、使用Len()檢驗(yàn)空串
盡管有多種方法可檢驗(yàn)空串,但首選的是使用Len()函數(shù)。為了測(cè)試零長(zhǎng)度的串,可以選擇把串與””相比較,或者比較串的長(zhǎng)度是否為0,但這些方法比用Len()函數(shù)要用更多的執(zhí)行時(shí)間。當(dāng)對(duì)字符串應(yīng)用Len()函數(shù)并且函數(shù)返回0值時(shí),說(shuō)明該字符串是空的或者是零長(zhǎng)度的字符串。
并且,因?yàn)樵贗f語(yǔ)句內(nèi)非零值被認(rèn)為是True,所以直接使用Len()函數(shù)而不必與””或0比較,減少了處理時(shí)間,因此執(zhí)行更快。
19、有效地使用數(shù)組
用VBA數(shù)組而不是單元格區(qū)域來(lái)處理數(shù)據(jù),即可以先將數(shù)據(jù)寫(xiě)入到某個(gè)數(shù)組,然后用一個(gè)語(yǔ)句就可以將數(shù)組中的數(shù)據(jù)傳遞到單元格區(qū)域中。
在創(chuàng)建已知元素的確定數(shù)組時(shí),使用Array函數(shù)對(duì)于節(jié)約空間和時(shí)間以及寫(xiě)出更具效率的代碼是非常理想的。例如,
Dim Names As Variant
Names=Array(“Fan”,“Yang”,“Wu”,“Shen”)
此外,應(yīng)該盡量使用固定大小的數(shù)組。如果確實(shí)選擇使用了動(dòng)態(tài)數(shù)組,應(yīng)該避免數(shù)組每增加一個(gè)元素就改變一次數(shù)組的大小,最好是每次增加一定數(shù)量的元素。
20、使用Excel的內(nèi)置函數(shù)
對(duì)于要實(shí)現(xiàn)的某一功能,如果有Excel的內(nèi)置函數(shù)能夠?qū)崿F(xiàn),那么就用Excel的內(nèi)置函數(shù),不需要另外自定義函數(shù),因?yàn)樽远x的函數(shù)總比Excel內(nèi)置的函數(shù)慢。

附件

Ra8JtKDO.rar (9.37 KB)

2006-8-1 23:55, 下載次數(shù): 84

[原創(chuàng)]VBA編程問(wèn)答(第1輯)

RDidpODM.rar (53.87 KB)

2006-8-1 23:56, 下載次數(shù): 79

[原創(chuàng)]VBA編程問(wèn)答(第1輯)

WqtM1Z3M.rar (6.89 KB)

2006-8-1 23:57, 下載次數(shù): 34

[原創(chuàng)]VBA編程問(wèn)答(第1輯)

問(wèn)題2:如何禁用用戶(hù)窗體的關(guān)閉按鈕?
解答:
您可能不想用戶(hù)在單擊窗體右上角的X圖標(biāo)后關(guān)閉窗體,您可以在用戶(hù)窗體代碼模塊中將UserForm_QueryClose過(guò)程的Cancel參數(shù)值設(shè)置為T(mén)rue,此時(shí)雖然X圖標(biāo)仍然存在,但當(dāng)您單擊它時(shí)已不起作用,因此可以防止用戶(hù)通過(guò)單擊該圖標(biāo)按鈕來(lái)關(guān)閉用戶(hù)窗體。例如,下面的示例提示用戶(hù)只能通過(guò)單擊用戶(hù)窗體上的“確定”按鈕來(lái)關(guān)閉該用戶(hù)窗體。您可以在VBE編輯器中插入一個(gè)用戶(hù)窗體,并在用戶(hù)窗體上放置一個(gè)名為“Ok”的按鈕,在用戶(hù)窗體代碼模塊中輸入下面的代碼進(jìn)行調(diào)試。
‘**************************************************
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
  ‘CloseMode參數(shù)表明事件發(fā)生的原因
‘若其值等于vbFormControlMenu則意味著用戶(hù)單擊了X圖標(biāo)按鈕
If CloseMode = vbFormControlMenu Then
    MsgBox "請(qǐng)單擊""確定""按鈕關(guān)閉本窗體"
    Cancel = True
  End If
End Sub
‘**************************************************
Private Sub Ok_Click()
  Unload UserForm1
End Sub
===================================================================
問(wèn)題3:可以撤銷(xiāo)宏所執(zhí)行的操作嗎?
解答:
可以,但不能通過(guò)Excel內(nèi)置的功能自動(dòng)實(shí)現(xiàn)。您可以使用VBA代碼記錄下運(yùn)行宏程序前單元格或單元格區(qū)域原先的內(nèi)容,在“撤銷(xiāo)”命令中調(diào)用以恢復(fù)程序運(yùn)行前的狀態(tài)。
您可以使用Application對(duì)象的OnUndo方法作為宏程序結(jié)束前的最后一個(gè)代碼,該方法允許您指定出現(xiàn)在“撤銷(xiāo)”菜單項(xiàng)中的文本以及點(diǎn)擊該文本后所運(yùn)行的過(guò)程。如下面的代碼所示:
Application.Onundo “撤銷(xiāo)最后一個(gè)宏”,”恢復(fù)宏程序”
為說(shuō)明上述方法,下面列出了一個(gè)完整的示例。示例的完整代碼以及代碼說(shuō)明如下:
‘**************************************************
Type RangeCellInfo '自定義類(lèi)型存儲(chǔ)宏運(yùn)行所作出的改變
    CellContent As Variant
    CellAddress As String
End Type

Public OrgWB As Workbook
Public OrgWS As Worksheet
Public OrgCells() As RangeCellInfo
‘**************************************************
Sub EditRange()
  ' 在所有被選取的單元格中插入X
  Dim i As Integer, cl As Range
  If TypeName(Selection) <> "Range" Then Exit Sub
  Application.ScreenUpdating = False
  ReDim OrgCells(Selection.Count)
  Set OrgWB = ActiveWorkbook
  Set OrgWS = ActiveSheet
  i = 1
  ‘記錄下宏程序?qū)ぷ鞅碜鞒龈淖兦暗臓顟B(tài)
  For Each cl In Selection
    OrgCells(i).CellContent = cl.Formula
    OrgCells(i).CellAddress = cl.Address
    i = i + 1
  Next cl
  ‘在所選單元格中填允X
  Selection.Formula = "X"
  ‘指定在“撤銷(xiāo)”菜單項(xiàng)中的文字及選擇該命令時(shí)所執(zhí)行的宏程序
  Application.OnUndo "撤銷(xiāo)最后運(yùn)行的宏過(guò)程操作", "UndoEditRange"
End Sub
‘**************************************************
‘恢復(fù)工作表原先的狀態(tài)
Sub UndoEditRange()
  Dim i As Integer
  Application.ScreenUpdating = False
  On Error GoTo NoWBorWS
  OrgWB.Activate
  OrgWS.Activate
  On Error GoTo 0
  '恢復(fù)宏運(yùn)行所作的改變
  For i = 1 To UBound(OrgCells)
      Range(OrgCells(i).CellAddress).Formula = OrgCells(i).CellContent
  Next i
  Set OrgWB = Nothing
  Set OrgWS = Nothing
  Erase OrgCells
NoWBorWS:
End Sub
示例文檔見(jiàn)撤銷(xiāo)宏示例.xls。

krV0Zt8k.rar (9.37 KB)


 


問(wèn)題4:如何將同一文件夾中的多個(gè)文本文件讀入到工作簿中?
解答:
通常,我們所看到的例子都是在工作簿中讀入一個(gè)文本文件中的內(nèi)容。假設(shè)有幾個(gè)文本文件,我們把它們放在與工作簿相同的文件夾中,那么,現(xiàn)在如何在該工作簿中一次性讀取這幾個(gè)文本文件的內(nèi)容。下面的程序演示了上述過(guò)程,示例工作簿附后,其中源數(shù)據(jù)引用了lichaobin網(wǎng)友在他的提問(wèn)貼中所附的數(shù)據(jù)。
分兩種情況:
(一)所讀入的文本文件總行數(shù)小于65536行,您可以使用以下代碼。
‘**************************************************
Sub Sample1()
    Dim n As Long, a(), ff As Integer, txt As String, myDir As String, x
    Dim myF As String, i As Long
    myDir = ThisWorkbook.Path & Application.PathSeparator
    myF = Dir(myDir & "*.txt")
    Do While myF <> ""
        ff = FreeFile
        Open myDir & myF For Input As #ff
        Do While Not EOF(ff)
            Line Input #ff, txt
            x = Split(txt, "|")
            n = n + 1
            ReDim Preserve a(1 To n)
            a(n) = x
        Loop
        Close #ff
        myF = Dir()
    Loop
    Cells.Clear
    With ThisWorkbook.Worksheets("Sheet1").Range("a1")
        For i = 1 To UBound(a)
            .Offset(i - 1).Resize(, UBound(a(i)) + 1) = a(i)
        Next
    End With
End Sub
‘**************************************************
(二)所讀入的文本文件總行數(shù)大于65536行,您可以使用以下代碼。其中使用了一個(gè)變量t和一個(gè)判斷語(yǔ)句,當(dāng)多于65536行時(shí),將剩下的數(shù)據(jù)寫(xiě)入另一工作表中。
Sub Sample2()
    Dim n As Long, a(), ff As Integer, txt As String, myDir As String, x
    Dim myF As String, i As Long, t As Integer
    t = 1
    myDir = ThisWorkbook.Path & Application.PathSeparator
    myF = Dir(myDir & "*.txt")
    Do While myF <> ""
        ff = FreeFile
        Open myDir & myF For Input As #ff
        Do While Not EOF(ff)
            Line Input #ff, txt
            x = Split(txt, "|")
            n = n + 1
            ReDim Preserve a(1 To n)
            a(n) = x
            If n = 65536 Then
                With ThisWorkbook.Sheets(t).Range("a1")
                    For i = 1 To UBound(a)
                        .Offset(i - 1).Resize(, UBound(a(i)) + 1) = a(i)
                    Next
                End With
                n = 0: Erase a: t = t + 1
            End If
        Loop
            Close #ff
            myF = Dir()
    Loop
        If n > 0 Then
            With ThisWorkbook.Sheets(t).Range("a1")
                For i = 1 To UBound(a)
                    .Offset(i - 1).Resize(, UBound(a(i)) + 1) = a(i)
                Next
            End With
        End If
End Sub
示例文檔見(jiàn)讀取多個(gè)文本文件.rar。
E27ouF6l.rar (53.87 KB)

問(wèn)題5:如何使用VBA刪除所有的空工作表?
解答:
可以分兩種情形來(lái)對(duì)待。
(一)如果您想刪除同一工作簿中的所有空工作表,可以使用下面的兩個(gè)程序中的其中一個(gè):
‘**************************************************
Sub test1()
Dim ws As Worksheet
  Application.DisplayAlerts = False
  For Each ws In ActiveWorkbook.Worksheets
    ws.Activate
    If ActiveWorkbook.Worksheets.Count > 1 Then
      If IsEmpty(ActiveSheet.UsedRange) Then
          ws.Delete
      End If
     End If
   Next ws
   Application.DisplayAlerts = True
End Sub
‘**************************************************
Sub test2()
Dim ws As Worksheet
On Error GoTo Handdle
  Application.DisplayAlerts = False
  For Each ws In ActiveWorkbook.Worksheets
     ws.Activate
     With ws
       If Application.CountA(.Cells) = 0 Then
         .Delete
       End If
     End With
   Next ws
Handdle:
   Application.DisplayAlerts = True
End Sub
(二)如果您想刪除已打開(kāi)的工作簿中的所有空工作表,可使用下面的程序:
‘**************************************************
Sub test()
Dim ws As Worksheet
Dim wb As Workbook
  Application.DisplayAlerts = False
  For Each wb In Workbooks
    wb.Activate
    For Each ws In ActiveWorkbook.Worksheets
      ws.Activate
      If ActiveWorkbook.Worksheets.Count > 1 Then
        If IsEmpty(ActiveSheet.UsedRange) Then
           ws.Delete
        End If
      End If
    Next ws
  Next wb
  Application.DisplayAlerts = True
End Sub
===================================================================
問(wèn)題6:如何獲取計(jì)算機(jī)上可供使用的打印機(jī)列表?
解答:
您可能有時(shí)想獲取您的計(jì)算機(jī)上可供使用的打印機(jī)列表,然后從中選擇打印機(jī)輸出。最簡(jiǎn)單的方法是,您可以在代碼中添加下面的語(yǔ)句:
Application.Dialogs(xlDialogPrint).Show
===================================================================
問(wèn)題7:如何基于某個(gè)單元格更新其它單元格的日期?
例如:我需要做的一個(gè)例行工作是依賴(lài)于兩個(gè)特定單元格的內(nèi)容添加一些日期到另一個(gè)單元格。例如,在單元格J2中有W(代表每周)或者B(代表Bi周)或者M(jìn)(代表每月),單元格N2中的內(nèi)容為一個(gè)可更新的日期,如果J2中包含一個(gè)W我需要在單元格L2中添加7天,或者如果J2中包含一個(gè)B我需要在單元格L2中添加14天,或者如果J2中包含一個(gè)M則在單元格L2中添加30天,……在單元格J2中包含的信息W,B,或M決定計(jì)算的天數(shù),單元格N2中包含原先約定的日期作為開(kāi)始計(jì)算的日期,單元格L2中的這個(gè)日期基于上面兩個(gè)單元格的日期更新。
解答:可以粘貼下面的兩個(gè)程序之一到工作表代碼模塊中。
(一)區(qū)分大小寫(xiě),您必須在工作表中輸入大寫(xiě)的字母W、B或M。
‘**************************************************
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("J2").Text = "W" Then
Range("L2") = Range("N2").Value + 7
ElseIf Range("J2").Text = "B" Then
Range("L2") = Range("N2").Value + 14
ElseIf Range("J2").Text = "M" Then
Range("L2") = Range("N2").Value + 30
End If
End Sub
(二)不區(qū)分大小寫(xiě),并使用了Select Case選擇語(yǔ)句。
‘**************************************************
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$N$2" Or Target.Address = "$J$2" Then
Dim iDays As Byte
Application.EnableEvents = False
On Error GoTo ERRORHANDLER
Select Case UCase(Range("J2").Value)
        Case "W"
           iDays = 7
        Case "B"
           iDays = 14
        Case "M"
           iDays = 30
End Select
Range("L2").Value = Range("N2").Value + iDays
Application.EnableEvents = True
Exit Sub
ERRORHANDLER:
Application.EnableEvents = True
End If
End Sub
===================================================================
問(wèn)題8:如何編寫(xiě)一個(gè)宏程序運(yùn)行另一個(gè)宏程序特定的次數(shù)?
解答:
可以用一個(gè)簡(jiǎn)單的循環(huán)來(lái)實(shí)現(xiàn)。
‘**************************************************
Sub FirstMacro()
Dim RunCount as Long
Const RunMax As Long=10 ‘定義要運(yùn)行的次數(shù)
For RunCount =1 To RunMax
    Call SecondMacro ‘調(diào)用要運(yùn)行的宏程序
Next
End Sub
===================================================================
問(wèn)題9:如何在一個(gè)組合框中列出所有工作表中單元格D3中的值?
解答:
假設(shè)用戶(hù)窗體中有一個(gè)名為ComboBox1的組合框,您可在用戶(hù)窗體中添加以下代碼,當(dāng)用戶(hù)窗體被激活時(shí),在組合框中將顯示出所有工作表中單元格D3的值。
‘**************************************************
Private Sub UserForm_Activate()
  Dim ws As Worksheet
  For Each ws In Worksheets
    ComboBox1.AddItem ws.Range("D3").Text
  Next ws
End Sub
===================================================================
問(wèn)題10:如何使工作表中的文本閃爍?
解答:
為了使文本閃爍,您需要周期性地執(zhí)行一個(gè)程序來(lái)變換文本的前景色,OnTime方法可以用于周期性地運(yùn)行一個(gè)程序。
‘**************************************************
Public RunWhen As Double
Sub StartBlink()
If Range("A1").Font.ColorIndex = 2 Then
        Range("A1").Font.ColorIndex = xlColorIndexAutomatic
    Else
        Range("A1").Font.ColorIndex = 2
End If
RunWhen = Now + TimeSerial(0, 0, 1)
Application.OnTime RunWhen, "StartBlink", , True
End Sub
‘**************************************************
Sub StopBlink()
Range("A1").Font.ColorIndex = xlColorIndexAutomatic
Application.OnTime RunWhen, "StartBlink", , False
End Sub
在上面的這些程序中,您可以改變參數(shù)A1為您想要使文本閃爍的單元格或單元格區(qū)域。在工作簿打開(kāi)時(shí),您需要初始化這個(gè)程序,因此,您可以放置下面的代碼到ThisWorkbook代碼模塊中。
‘**************************************************
Private Sub Workbook_Open()
StartBlink
End Sub
當(dāng)工作簿關(guān)閉時(shí),您需要取消OnTime事件,因此,您需要放置下面的代碼到ThisWorkbook代碼模塊中。
‘**************************************************
Private Sub Workbook_BeforeClose(Cancel As Boolean)
StopBlink
End Sub
示例文檔見(jiàn)在Excel中閃爍文本.xls。

HL3xux8P.rar (6.89 KB)


===================================================================
問(wèn)題11:如何將工作簿中其它工作表名導(dǎo)入到指定的工作表中?
解答:
本問(wèn)題即將工作簿中除指定的工作表(如名為Name的工作表)外的其它的工作表名導(dǎo)入到指定的工作表中(即Name工作表中)。您可以使用下面的代碼。
‘**************************************************
Sub Test()
  Dim ws As Worksheet
  Dim i As Long, j As Long
  Worksheets("Name").Range("A:A").Clear
i = Worksheets("Name").Range("A65536").End(xlUp).Row
  For Each ws In Worksheets
     If ws.Name <> "Name" Then
        Worksheets("Name").Cells(i, 1) = ws.Name
        i = Worksheets("Name").Range("A65536").End(xlUp).Row + 1
      End If
  Next ws
End Sub
===================================================================
問(wèn)題12:如何在單元格中快速輸入帶秒的時(shí)間?
解答:
一般,在Excel中快速輸入日期和時(shí)間時(shí),可使用快捷鍵,即按Ctrl+:組合鍵將快速在單元格中輸入當(dāng)前日期,按Ctrl+Shift+:組合鍵將快速在單元格中輸入當(dāng)前時(shí)間,但所顯示的時(shí)間為“小時(shí):分鐘”格式,不會(huì)顯示秒。如果您想顯示“小時(shí):分鐘:秒”這樣的格式的話,可以使用Onkey方法修改快捷鍵的缺省設(shè)置,如下所示,運(yùn)行“設(shè)置快捷鍵”代碼即可。
‘**************************************************
Sub 設(shè)置快捷鍵()
    Application.OnKey "+^:", "輸入時(shí)間"
End Sub
‘**************************************************
Sub 恢復(fù)快捷鍵()
    Application.OnKey "+^:"
End Sub
‘**************************************************
Sub 輸入時(shí)間()
    With ActiveCell
    .Value = Time()
      .NumberFormat = "hh:mm:ss"
    End With
End Sub
如果您想恢復(fù)快捷鍵的缺省設(shè)置,運(yùn)行“恢復(fù)快捷鍵”過(guò)程。

 

By fanjy in 2006-8-1

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
VBA新手入門(mén)篇 - excel函數(shù),excel公式,excel學(xué)習(xí),excel基礎(chǔ),ex...
Excel VBA解讀(79):讓Excel動(dòng)起來(lái)——認(rèn)識(shí)事件過(guò)程
Excel編程周末速成班第22課:使用事件
學(xué)習(xí)VBA過(guò)程中歸納積累的幾個(gè)比較實(shí)用的技巧和方法
VBA程序集(第5輯)
用VBA打開(kāi)或禁止單元格拖放(自動(dòng)填充)功能
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服