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

分享

表頭(單元格)查找與定位

 智勇閱覽室 2023-05-29 發(fā)布于廣東

1 Excel的查找功能

  VBA中應(yīng)用于Range對(duì)象的Find方法,實(shí)際上就是Excel中”Ctrl+F”出來的查找窗口。這個(gè)查找功能有一個(gè)bug(應(yīng)該是“參數(shù)After+合并單元格”的設(shè)計(jì)缺陷引發(fā)的),以在Excel中查找為例,如下圖:
查找不到的例子
  故為了在VBA中對(duì)Range使用Find方法的魯棒性,自己封裝個(gè)類Find方法后開發(fā)程序會(huì)更方便,簡化定位單元格時(shí)需要書寫的代碼量。
  不過,開發(fā)這一系列的函數(shù),更主要的原因是解決一些常見麻煩:單元格查找,其實(shí)大部分時(shí)候都是應(yīng)用于表頭查找,而表頭查找會(huì)有個(gè)多級(jí)表頭問題。在處理多工作表數(shù)據(jù)時(shí),還時(shí)常會(huì)遇到邏輯上是一樣的字段,但名稱有差異(如”身份證”、”身份證號(hào)碼”),給數(shù)據(jù)自動(dòng)匯總帶來不便。
  對(duì)bug的修復(fù),只需加個(gè)if語句。而對(duì)于常見麻煩,我采用了一些特殊的設(shè)計(jì)理念來解決,詳見函數(shù)的使用方法。由于功能本身帶有一定模糊性,實(shí)際工作中,遇到比較復(fù)雜的表格時(shí),最好檢查下函數(shù)定位的位置是否正確(筆者也正在思考如何制作小工具進(jìn)行高效快速檢查)。

2 VBA查找功能開發(fā)

  接口主要是findcel,findrow,findcol三個(gè)函數(shù),它們依次返回的是要查找的單元格本身,單元格所在行,單元格所在列。找不到時(shí)findcel返回Nothing,findrow和findcol則返回0。
  輸入?yún)?shù)的規(guī)則是一樣的:第1個(gè)參數(shù)st是要查找的工作表,第2個(gè)參數(shù)name是要查找的值,函數(shù)會(huì)優(yōu)先按照“單元格匹配”的規(guī)則進(jìn)行查找,找不到的情況下,會(huì)去掉“單元格匹配”再進(jìn)行查找。

'代碼更新于2015年07月30日
Function findcol(ByVal st As Worksheet, ByVal name As String, Optional ByVal partName As String) As Long
    Dim t As Range
    Set t = findcel(st, name, partName)
    If t Is Nothing Then
        findcol = 0
    Else
        findcol = t.Column
    End If
End Function

Function findrow(ByVal st As Worksheet, ByVal name As String, Optional ByVal partName As String) As Long
    Dim t As Range
    Set t = findcel(st, name, partName)
    If t Is Nothing Then
        findrow = 0
    Else
        findrow = t.Row
    End If
End Function


'該函數(shù)支持name、partName用分號(hào)隔開,允許按優(yōu)先級(jí)進(jìn)行字段名搜索的多字段查詢
Function findcel(ByVal st As Worksheet, ByVal name As String, Optional ByVal partName As String) As Range
'(1)首先name絕對(duì)不能為空
    If name = '' Then Exit Function

    Dim arr1, arr2
'(2)partName可以為空,但為了后續(xù)遍歷統(tǒng)一處理,需要先預(yù)分析下
    arr1 = Split(partName, ';')
    If isEmptyArr(arr1) Then
        ReDim arr1(1 To 1)
        arr1(1) = ''
    End If

'(3)開始循環(huán)遍歷,只要找到第一組滿足解即可
    arr2 = Split(name, ';')
    For Each a1 In arr1
        For Each A2 In arr2
            Set findcel = findcel_base(st, A2, a1)
            If Not (findcel Is Nothing) Then Exit Function
        Next A2
    Next a1
End Function

Function findcel_base(ByVal st As Worksheet, ByVal name As String, Optional ByVal partName As String) As Range
    Dim rng As Range '查找的范圍
    Set rng = st.UsedRange

    'Debug.Print 'findcel_base查找內(nèi)容所在工作薄', st.Parent.name
    Dim rng2 As Range, t As Range
'(1)先定位高級(jí)表頭的列范圍
    If partName <> '' Then
        Set t = rng.Find(partName, LookAt:=xlPart)
        '如果第一個(gè)是合并單元格,有時(shí)候會(huì)有找不到的bug
        If rng.Cells(1, 1) = partName Then Set t = rng.Cells(1, 1)
        '如果確實(shí)找不到,退出函數(shù)
        If t Is Nothing Then Exit Function

        '否則就是找到了,計(jì)算出找到的(合并)單元格所在列
        Set rng2 = st.Range(rng.Cells(1, t.Column), rng.Cells(st.Rows.Count, t.Offset(0, 1).Column - 1))
        Set rng = Intersect(rng, rng2)  'Range的交
    End If

'(2)然后就可以直接在rng搜索表頭名了
    Set t = rng.Find(name, LookAt:=xlWhole)                        '能單元格匹配找到,則按照單元格結(jié)果
    If t Is Nothing Then Set t = rng.Find(name, LookAt:=xlPart)    '否則進(jìn)行部分查找
    If name = rng.Cells(1, 1) Then Set t = rng.Cells(1, 1)

    'If Not (t Is Nothing) Then Debug.Print name &amp; '在' &amp; t.Address
    Set findcel_base = t
End Function

Private Function isEmptyArr(arr) As Boolean  '
    isEmptyArr = True
    For Each a In arr
        isEmptyArr = False
        Exit For
    Next a
End Function

3 使用舉例

  測(cè)試代碼:

Sub 表頭查找與定位()
    Dim st As Worksheet
    Set st = ActiveSheet

'(1)可以用'格式比較穩(wěn)定'的字段來定位表頭所在行
    Dim p As Range
    Set p = findcel(st, '物理站址編號(hào)')
    Debug.Print '表頭行范圍:', p.Row & '~' & (p.Offset(1, 0).Row - 1)

'(2)定位幾個(gè)字段的位置
    Debug.Print '基本定位功能:'
    Debug.Print findcol(st, '序號(hào)'), '序號(hào)'
    Debug.Print findcol(st, '面積'), '機(jī)房面積(平方米)'    '模糊匹配
    Debug.Print findcol(st, '資產(chǎn)名稱'), '有多個(gè)滿足時(shí),返回第1個(gè)匹配結(jié)果'
    Debug.Print findcol(st, '賬面凈額'), '賬面凈額R-S-T'
    Debug.Print findcol(st, '設(shè)備類型'), '找不到時(shí)返回0值'

    Debug.Print '高級(jí)定位功能:'
    Debug.Print findcol(st, '設(shè)備名稱;資產(chǎn)名稱'), '找不到設(shè)備名稱后,繼續(xù)找資產(chǎn)名稱'
    Debug.Print findcol(st, '原值', '評(píng)估價(jià)值2'), '多級(jí)表頭查找與定位'
    Debug.Print findcol(st, '總值;價(jià)值;原值;凈值', '評(píng)估值;評(píng)估價(jià)值'), '多功能混用'
End Sub

  處理對(duì)象:
舉例表頭

  立即窗口輸出的結(jié)果:

表頭行范圍:  1~2
基本定位功能:
 1            序號(hào)
 5            機(jī)房面積(平方米)
 4            有多個(gè)滿足時(shí),返回第1個(gè)匹配結(jié)果
 6            賬面凈額R-S-T
 0            找不到時(shí)返回0值
高級(jí)定位功能:
 4            找不到設(shè)備名稱后,繼續(xù)找資產(chǎn)名稱
 12           多級(jí)表頭查找與定位
 9            多功能混用

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

    類似文章 更多