小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 yuxinrong 2010-01-15
VBA編程問(wèn)答(第3輯)
fanjy 發(fā)表于 2007-1-20 20:18:00
在學(xué)習(xí)ExcelVBA編程的過(guò)程中,經(jīng)常會(huì)遇到一些問(wèn)題,有些可能是新碰到的,有些則是以前已遇到過(guò)但暫時(shí)忘掉了解決辦法的,VBA編程問(wèn)答將把我所收集到的問(wèn)題和自已所遇到的問(wèn)題及解決辦法進(jìn)行歸納整理,以方便查閱和參考。
在下面的內(nèi)容中,有大量的程序代碼,并附有簡(jiǎn)單的說(shuō)明,您可以將它們輸入或復(fù)制到VBE編輯器中進(jìn)行調(diào)試,也可以將它們進(jìn)行適當(dāng)?shù)恼{(diào)整和修改后應(yīng)用到自已的程序中。有些問(wèn)答提供了參考示例,您可以直接下載后處理。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
本輯目錄
問(wèn)題26:如何實(shí)現(xiàn)單元格在指定區(qū)域內(nèi)自動(dòng)跳轉(zhuǎn)?
問(wèn)題27:如何將多個(gè)工作簿中的工作表一次性合到一個(gè)工作簿里面?
問(wèn)題28:關(guān)于Excel單元格填充顏色......?
問(wèn)題29:如何實(shí)現(xiàn)在Sheet1中輸入后,在Sheet2中相應(yīng)的單元格中顯示?
問(wèn)題30:如何實(shí)現(xiàn)當(dāng)某一單元格滿(mǎn)足非空條件時(shí),輸入的數(shù)據(jù)不能修改?
問(wèn)題31:如何用Vba方法導(dǎo)出Xls文件至Txt文件? 
=====================================================================
問(wèn)題26:如何實(shí)現(xiàn)單元格在指定區(qū)域內(nèi)自動(dòng)跳轉(zhuǎn)?
例如,在單元格區(qū)域A1:C100中,無(wú)論何時(shí)在其中的某個(gè)單元格中輸入完一個(gè)單個(gè)的字符后,自動(dòng)按規(guī)律跳轉(zhuǎn)到下一單元格,即在單元格B1中輸完后,跳轉(zhuǎn)到單元格C1,在單元格C1中輸入完單個(gè)字符后,自動(dòng)跳轉(zhuǎn)到單元格A2,……
解答:可以在工作表事件中使用下面的代碼:
‘***********************************
Private Sub Worksheet_Change(ByVal Target As Range)
    Const WS_RANGE As String = "A1:C100" '<== 按需要改變單元格區(qū)域
    
    On Error GoTo ws_exit
    Application.EnableEvents = False
    
    If Not Intersect(Target, Me.Range(WS_RANGE)) Is Nothing Then
        With Target
            If Len(.Value) = 1 Then
                Me.Cells(.Row - (.Column Mod 3 = 0), .Column Mod 3 + 1).Select
                If Intersect(ActiveCell, Me.Range(WS_RANGE)) Is Nothing Then
                    Me.Range(WS_RANGE).Cells(1, 1).Select
                End If
            End If
        End With
    End If
    
ws_exit:
    Application.EnableEvents = True
End Sub
‘***********************************
說(shuō)明:該代碼中的單元格區(qū)域可按您的需要改為合適的單元格區(qū)域,但必須是3列。
不限于列的代碼如下:
‘***********************************
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Rng As Range
    Dim Ix As Long, Ad As String
    
    Set Rng = Range("F4:G50") '<== 按需要改變單元格區(qū)域
    
    On Error GoTo ws_exit
    Application.EnableEvents = False
    
    If Not Intersect(Target, Rng) Is Nothing Then
       If Len(Target.Value) = 1 Then
         Ad = Target.Address(False, False, xlR1C1, , Rng)
         Ix = Val(Mid(Ad, 3)) * Rng.Columns.Count + Val(Mid(Ad, InStr(Ad, "C") + 2)) + 1
         Rng((Ix Mod Rng.Cells.Count) + 1).Select
       End If
    End If
    
ws_exit:
    Application.EnableEvents = True
End Sub
‘***********************************
說(shuō)明:上面的代碼中,單元格區(qū)域可不限于2列。
=====================================================================
問(wèn)題27:如何將多個(gè)工作簿中的工作表一次性合到一個(gè)工作簿里面?
解答:關(guān)于如何將多個(gè)工作簿(xls文件)中的工作表(worksheet)復(fù)制到同一個(gè)工作簿中的解決。下面的代碼可以將某個(gè)磁盤(pán)目錄下的多個(gè)xls文件的復(fù)制到含有這段代碼的xls文件中,而且xls文件可以根據(jù)處理worksheet的數(shù)量自動(dòng)的增加xls文件中worksheet的數(shù)量。使用時(shí)將代碼復(fù)制到xls文件的宏內(nèi),然后運(yùn)行宏main即可。
代碼中運(yùn)用了filesystemobject對(duì)象和excel的range對(duì)象的copy方法以及worksheet和workbook對(duì)象的add方法。這里就不在贅述,可以在excel vba的幫助中找到。
‘***********************************
Sub Mergesheet(ByVal sPath As String)

   Dim fs, fd, fl As Object
   Dim xlbook As Workbook
   Dim xlsheet As Worksheet
   Dim i_cnt As Integer

   i_cnt = 1

   Set fs = CreateObject("scripting.filesystemobject") '建立filesystemobject

   If Not fs.FolderExists(sPath) Then
      MsgBox "目錄不存在!", vbCritical
      Exit Sub
   End If

    Set fd = fs.getfolder(sPath)   '或取文件夾
    For Each fl In fd.Files        '依此處理文件夾中的文件
      If Right(Trim(fl.Name), 3) = "xls" Then     '只處理xls文件
        Set xlbook = Application.Workbooks.Open(sPath + "\" + fl.Name)  '打開(kāi)xls文件
        If i_cnt <> 3 Then         '默認(rèn)的worksheet數(shù)量是3,如果超過(guò)就自動(dòng)的增加
          Set xlsheet = Application.Workbooks(1).Worksheets.Add
        Else
          Set xlsheet = Application.Workbooks(1).Worksheets(i_cnt)
        End If
        xlbook.Worksheets(1).Rows.Copy xlsheet.Cells(1, 1) '復(fù)制worksheet
        i_cnt = i_cnt + 1
        xlbook.Close             '關(guān)閉已經(jīng)打開(kāi)的xls文件
      End If
    Next
    Set fl = Nothing           '關(guān)閉file,folder,filesystemobject對(duì)象
    Set fd = Nothing
    Set fs = Nothing
End Sub

Sub main()
  Dim sPath As String
  sPath = InputBox("請(qǐng)輸入目錄!如C:", "合并目錄下xls文件的sheet1")  '顯示輸入框獲取磁盤(pán)目錄
  If sPath = " " Then Exit Sub
  Mergesheet (sPath)
End Sub
‘***********************************
===================================================================
問(wèn)題28:關(guān)于Excel單元格填充顏色......?
有五種可能的計(jì)算結(jié)果,比如結(jié)果會(huì)是1,2,3,4,5,不同的值給單元格填充不同顏色。條件格式最多只能定義三個(gè)條件,即只能填充最多三種顏色,不知用什么方法可以填上三種以上的顏色?
解答: 如果所有的結(jié)果集合只是在1,2,3,4,5中間,那么寫(xiě)個(gè)宏就OK。
假設(shè)對(duì)于$B這一整列的情況如下:
B1=0或空時(shí),單元格B1無(wú)填充顏色;
B1=1 時(shí),給單元格B1填充紅色;
B1=2 時(shí),給單元格B1填充藍(lán)色;
B1=3 時(shí),給單元格B1填充綠色;
B1=4 時(shí),給單元格B1填充黃色;
B1=5 時(shí),給單元格B1填充紫色。
B2=0或空時(shí),單元格B2無(wú)填充顏色;
B2=1 時(shí),給單元格B2填充紅色;
B2=2 時(shí),給單元格B2填充藍(lán)色;
B2=3 時(shí),給單元格B2填充綠色;
B2=4 時(shí),給單元格B2填充黃色;
B2=5 時(shí),給單元格B2填充紫色。
……
代碼:
‘***********************************
Sub Macro1()
  For i = 1 To 4096 ‘要填充顏色的單元格,可修改為所需要的
    Range("B" + CStr(i)).Select
    Select Case Range("B" + CStr(i)).Cells.Value
    Case 1
      Selection.Interior.ColorIndex = 3
    Case 2
      Selection.Interior.ColorIndex = 4
    Case 3
      Selection.Interior.ColorIndex = 5
    Case 4
      Selection.Interior.ColorIndex = 6
    Case 5
      Selection.Interior.ColorIndex = 7
    End Select
    With Selection.Interior
      .Pattern = xlSolid
      .PatternColorIndex = xlAutomatic
    End With
  Next
End Sub
‘***********************************
---------------------------------------------------------------------
如果要做到單元格的值改變后填充的顏色自動(dòng)更新,這個(gè)宏該改成怎樣?
如果單元格的值是計(jì)算得來(lái)的,用 worksheet Calculate Event 應(yīng)該可以。
代碼:
‘***********************************
Private Sub Worksheet_Calculate()
  Dim vValue As Integer
  Dim vColor As Integer
  Dim cRange As Range
  Dim cell As Range

  For Each cell In Intersect(Columns("B"), ActiveSheet.UsedRange)
    vValue = cell.Value
    '默認(rèn)值無(wú)填充色
    vColor = 0
    Select Case vValue
    Case 1
      vColor = 3
    Case 2
      vColor = 5
    Case 3
      vColor = 4
    Case 4
      vColor = 6
    Case 5
      vColor = 13
    End Select
    Application.EnableEvents = False
    cell.Interior.ColorIndex = vColor
    Application.EnableEvents = True
  Next cell
End Sub
‘***********************************
( 如果單元格的值不是計(jì)算得來(lái)的,是直接輸入的,可以改用 Worksheet Change Event )
---------------------------------------------------------------------
還想問(wèn)一下,這個(gè)宏的功能能否用自定義函數(shù)做到?
想用自定義函數(shù)的原因:?jiǎn)卧矜i定時(shí),自定義函數(shù)依然可以正常運(yùn)行,而宏不行。
這個(gè)可以利用 UserInterfaceOnly = TRUE 參數(shù)去解決。將 UserInterfaceOnly 參數(shù)設(shè)置為 True 可以允許通過(guò)代碼修改,但是不允許通過(guò)用戶(hù)界面修改。默認(rèn)值為 False,這意味著通過(guò)代碼和用戶(hù)界面項(xiàng)都不可以修改受保護(hù)的工作表。這個(gè)屬性設(shè)置只適用于當(dāng)前會(huì)話(huà)。如果您想讓代碼可以在任何會(huì)話(huà)中都可以操作工作表,那么您需要每次工作簿打開(kāi)的時(shí)候添加設(shè)置這個(gè)屬性的代碼。
注意紅色那段字,由于這個(gè)原因,所以加一個(gè)宏在 workbook open event 讓每次開(kāi)啟檔案時(shí)去設(shè)定UserInterfaceOnly 參數(shù)。
代碼;
‘***********************************
Private Sub Workbook_Open()
  '如果每個(gè)工作表都有不同的密碼
  Sheets(1).Protect Password:="secret1", UserInterFaceOnly:=True
  Sheets(2).Protect Password:="secret2", UserInterFaceOnly:=True
'按需要重復(fù)
'**如果所有工作表密碼相同
   'Dim wSheet As Worksheet
   'For Each wSheet In Worksheets
   '    wSheet.Protect Password:="secret", UserInterFaceOnly:=True
   'Next wSheet
'****
End Sub
‘***********************************
必須了解的一些相關(guān)概念(陳希章,微軟中文新聞組專(zhuān)家)
一般我們?cè)谥付伾珪r(shí)喜歡用ColorIndex這個(gè)屬性,通常情況下是沒(méi)有問(wèn)題的。
但必須知道的一些概念是:ColorIndex是相對(duì)于調(diào)色盤(pán)中(調(diào)色盤(pán)有56中顏色)的某個(gè)位置的顏色,而調(diào)色盤(pán)是屬于工作簿級(jí)的對(duì)象,也就是說(shuō)很有可能這樣一種情況就是,在這個(gè)工作簿中3代表紅色(假設(shè)),而到另一個(gè)工作簿中卻不是。
所以,如果要精確定義顏色,是不推薦用ColorIndex的,往往有些同志在調(diào)試程序時(shí)的疑惑也在于此(明明在自己電腦上是紅色,到用戶(hù)電腦上就不是了)。
還有兩種方法來(lái)返回顏色:
1.用Excel常量,如vbred,vbblue,vbgreen等。
2.用RGB函數(shù)。
用以上的方法,VBA語(yǔ)句也應(yīng)相應(yīng)更改。
例:Target.Offset(0, 1).Interior.ColorIndex = vColor 改成'Target.Offset(0, 1).Interior.Color = vbred 等等。
另從本例而言,建議統(tǒng)一用change事件。
===================================================================
問(wèn)題29:如何實(shí)現(xiàn)在Sheet1中輸入后,在Sheet2中相應(yīng)的單元格中顯示?
即,如何實(shí)現(xiàn)在
sheet1中輸入a1=abc,sheet2中顯示a1=abc;
   輸入b1=xyz,sheet2中顯示a2=xyz;
       再輸入a2=123,sheet2中顯示a5=123;
             輸入b2=qwe, sheet2中顯示a6=qwe;
       不停的輸入后,sheet2中數(shù)字每四行四行不停填充。
解答:
代碼說(shuō)明,這個(gè)需求的關(guān)鍵是,需要建立sheet1的行列值與sheet2的行值之間的函數(shù)關(guān)系,綜合看就是一個(gè)代數(shù)系統(tǒng)內(nèi)的等差數(shù)列的關(guān)系。 這個(gè)代數(shù)式就是:
j=(i-1)*4+t   j代表sheet2的行值,i代表sheet1的行值,t代表sheet1的列值。
所以能夠按照所描述的功能的vba代碼如下:
‘***********************************
'這是sheet1的worksheet_change事件(觸發(fā)的條件就是在sheet1輸入數(shù)據(jù))
Private Sub Worksheet_Change(ByVal Target As Range) 
    If Target.Column > 2 Then   '這里限定最大只可以輸入到每行的第2列,否則就不處理
      MsgBox "輸錯(cuò)了位置", vbCritical '這里是錯(cuò)誤的提示信息
    Exit Sub                         '退出代碼的執(zhí)行
    End If
   '按照sheet1與sheet2行列的特定算法填充數(shù)據(jù)
   Sheet2.Cells((Target.Row - 1) * 4 + Target.Column, 1) = Target.Value
End Sub
‘***********************************
===================================================================
問(wèn)題30:如何實(shí)現(xiàn)當(dāng)某一單元格滿(mǎn)足非空條件時(shí),輸入的數(shù)據(jù)不能修改?
如果在excel中寫(xiě)如此要求的一個(gè)函數(shù):某一單元格滿(mǎn)足非空條件時(shí),輸入的數(shù)據(jù)不能修改。就是當(dāng)我往一個(gè)單元格內(nèi)輸入數(shù)據(jù)后,其中的數(shù)據(jù)無(wú)法再次修改!
解答:代碼如下:
‘***********************************
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error Resume Next
If Target <> "" Then
   Target.Locked = True
   ActiveSheet.Protect password:="123"
End If
If Target = "" Then
   ActiveSheet.Unprotect password:="123"
End If
End Sub
‘***********************************
===================================================================
問(wèn)題31:如何用Vba方法導(dǎo)出Xls文件至Txt文件?
即如何以一定的格式輸出Excel文件的數(shù)據(jù)。
解答:
這是個(gè)常見(jiàn)的問(wèn)題,因?yàn)樵S多不同應(yīng)用系統(tǒng)之間報(bào)送數(shù)據(jù)時(shí),最好的方法就是報(bào)送統(tǒng)一格式的數(shù)據(jù)文件,而帶有特殊分割符號(hào)的文本文件應(yīng)該說(shuō)是最適用的。
下面的代碼將輸出的文件改為“文件名”+“Worksheet名”組合的TXT文件。代碼的適當(dāng)說(shuō)明:生成Txt文件需要使用FileSystemObject對(duì)象,關(guān)于該對(duì)象的說(shuō)明,可以參閱msdn或vba幫助中的相關(guān)內(nèi)容。這段程序可以在將xls文件中任意的sheet中的內(nèi)容導(dǎo)出成txt文本文件。
如下就是代碼。可以將其復(fù)制到任何一個(gè)xls文件中。使用時(shí),只要打開(kāi)某個(gè)sheet,然后運(yùn)行這個(gè)宏(菜單內(nèi):工具-〉宏-〉運(yùn)行宏OutPutXlsToTxt),即可將該sheet內(nèi)的數(shù)據(jù)導(dǎo)出生成TXT文件,文件名是由Excel文件名和Sheet名組合而成的。
‘***********************************
Sub OutPutXlsToTxt()
  Dim fs, myFile As Object
  Dim i_row, i_col, i_MaxCol As Integer 'xls工作表的行列坐標(biāo)變量和最大列數(shù)變量
  Dim myfileline As String'txtfile的行數(shù)據(jù)
 
  Set fs = CreateObject("Scripting.FileSystemObject")  '建立filesytemobject
 '通過(guò)filesystemobject新建一個(gè)和xls文件同名的txt文件
  Set myFile = fs.createtextfile(Workbooks(1).Path + "\" + _
    Mid(Trim(Workbooks(1).Name), 1, Len(Trim(Workbooks(1).Name)) - 4) + "之" + _
    Trim(Workbooks(1).ActiveSheet.Name) + ".txt") 
  i_row = 1
  i_MaxCol = 0
  Do
    i_MaxCol = i_MaxCol + 1
  Loop Until Workbooks(1).ActiveSheet.Cells(1, i_MaxCol) = ""
  i_MaxCol = i_MaxCol - 1    '獲得整個(gè)sheet的最大列數(shù)
  If i_MaxCol = 0 Then       '對(duì)沒(méi)有數(shù)據(jù)的表不做處理并退出程序
    MsgBox "該表無(wú)數(shù)據(jù),不能導(dǎo)出!", vbCritical
    Exit Sub
  End If
  Do
    myfileline = ""
    For i_col = 1 To i_MaxCol
      myfileline = myfileline + _
       Trim(CStr(Workbooks(1).ActiveSheet.Cells(i_row, i_col))) + "," '生成每行數(shù)據(jù)
    Next
    myFile.writeline (Mid(myfileline, 1, Len(myfileline) - 1))  '將每行數(shù)據(jù)寫(xiě)入txtfile
    i_row = i_row + 1
  Loop Until Workbooks(1).ActiveSheet.Cells(i_row, 1) = ""
 
  Set myFile = Nothing
  Set fs = Nothing                   '關(guān)閉文件和filesystemobject對(duì)象
End Sub
‘***********************************

By fanjy in 2007-1-20

注:本輯編程問(wèn)答資源整理歸納于vbaexpress、微軟中文技術(shù)社區(qū)等。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(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)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多