久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

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

 yuxinrong 2010-01-15

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:如何禁用用戶窗體的關(guān)閉按鈕?
問(wèn)題3:可以撤銷所執(zhí)行的操作嗎,?
問(wèn)題4:如何將同一文件夾中的多個(gè)文本文件讀入到工作簿中,?
問(wèn)題5:如何使用VBA刪除所有的空工作表
問(wèn)題6:如何獲取計(jì)算機(jī)上可供使用的打印機(jī)列表,?
問(wèn)題7:如何基于某個(gè)單元格更新其它單元格的日期,?
問(wèn)題8:如何編寫一個(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)您編寫了一個(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)的,,也希望您能將在編寫程序過(guò)程中發(fā)現(xiàn)的一些優(yōu)化方法介紹給大家共享,。
1,、盡量簡(jiǎn)化代碼
通過(guò)簡(jiǎn)化代碼,可以提高程序的性能,。您可以將通用過(guò)程編寫為子過(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è)查找算法,,即將該查找算法編寫成通用的子程序,需要查找某個(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ǔ)句,,要求您在編寫代碼時(shí)對(duì)所有出現(xiàn)的變量均進(jìn)行聲明,這樣,,在使用變量時(shí)減少內(nèi)存需求并加速性能。
(1)要節(jié)省內(nèi)存資源,,必須始終用特定的數(shù)據(jù)類型聲明所有變量,。如果不使用特定的數(shù)據(jù)類型聲明變量,VBA會(huì)創(chuàng)建Variant類型的變量,,這將比任何其他數(shù)據(jù)類型要求更多的內(nèi)存,。
(2)清楚每種數(shù)據(jù)類型需要多少內(nèi)存以及它可以存儲(chǔ)的值的范圍,。除使用較小的數(shù)據(jù)類型會(huì)導(dǎo)致隱性轉(zhuǎn)換的情況外,應(yīng)始終使用盡可能小的數(shù)據(jù)類型,。例如,,因?yàn)镮nteger類型的變量將被轉(zhuǎn)換成Long類型的變量,應(yīng)該將那些存儲(chǔ)整型值的變量聲明為L(zhǎng)ong類型,,而不是Integer類型,。
(3)除非確實(shí)需要,應(yīng)避免使用浮點(diǎn)數(shù)據(jù)類型,。盡管Currency數(shù)據(jù)類型更大,,但它比 Single 數(shù)據(jù)類型快,因?yàn)镃urrency數(shù)據(jù)類型不使用浮點(diǎn)處理器,。
(4)如果在一個(gè)過(guò)程中多次引用一個(gè)對(duì)象,,可以創(chuàng)建對(duì)象變量,并將對(duì)給對(duì)象的引用指派給它,。因?yàn)閷?duì)象變量存儲(chǔ)對(duì)象在內(nèi)存中的位置,,VBA將不必再次查找其位置。
(5)將對(duì)象變量聲明為特定的類型(不是Object類型),,以便利用早期綁定,。
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ú)立的類型庫(kù)或?qū)ο髱?kù)文件才適用且還需要已安裝了特定的庫(kù),。而后期綁定則只是在運(yùn)行時(shí)才知道對(duì)象的類型并對(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)值為True,,這樣當(dāng)寫數(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è)置為True,。因?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ù)組中檢索值比從相同類型的變量讀取值要慢。
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ì)象,。但是,并不是在所有的情況下都需要這樣做,。所以,,在您編寫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)始或最后面,避免干擾用戶,。此外,,盡管窗體提供了許多功能,但它們能夠?qū)е挛募笮⊙杆僭黾?。還有就是盡量避免給工作表單元格鏈接用戶窗體控件,,因?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ù)值類型如何,浮點(diǎn)除法運(yùn)算符總會(huì)返回Double類型的值,。
(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ù)類型。
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)表示字符串中的回車/換行組合,,而不是使用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ù)寫入到某個(gè)數(shù)組,然后用一個(gè)語(yǔ)句就可以將數(shù)組中的數(shù)據(jù)傳遞到單元格區(qū)域中,。
在創(chuàng)建已知元素的確定數(shù)組時(shí),,使用Array函數(shù)對(duì)于節(jié)約空間和時(shí)間以及寫出更具效率的代碼是非常理想的。例如,,
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輯)

資料庫(kù)http://fanjy.blog.
博客網(wǎng)http://www.
Excel財(cái)務(wù)管理

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


 


資料庫(kù)http://fanjy.blog.
博客網(wǎng)http://www.
問(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ù)寫入另一工作表中,。
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)
資料庫(kù)http://fanjy.blog.
博客網(wǎng)http://www.
Excel會(huì)計(jì)實(shí)務(wù)

問(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è)例行工作是依賴于兩個(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ū)分大小寫,您必須在工作表中輸入大寫的字母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ū)分大小寫,并使用了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:如何編寫一個(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è)用戶窗體中有一個(gè)名為ComboBox1的組合框,,您可在用戶窗體中添加以下代碼,,當(dāng)用戶窗體被激活時(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

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多