我們根據(jù)某個關(guān)鍵詞在Excel中查找某項數(shù)據(jù),焦點(diǎn)會被放置到某個單元格,但是想定位到具體位置還需要有個追蹤的過程,這在數(shù)據(jù)量小的時候自然不在話下,而一旦大起來,看似很簡單的問題很可能會成為我們的最大障礙,至少會降低效率,增加許多無謂的精力消耗!
這在MatoVBA的結(jié)果中也得到了驗證,尤其是訂單和會員詳情數(shù)據(jù),有沒有什么方法可以解決這個痛點(diǎn)呢?
有,聚光燈!
02
聚光燈介紹
聚光燈其實是一種形象的說法,
excel官方并沒有此概念,
直觀起見,先看看效果:
其實就是通過行列差異化的著色,使目標(biāo)位置(行:列)能夠快速的被識別出來一種小技巧。
03
實現(xiàn)方法
核心事件:
Worksheet_SelectionChange(Excel.Range)
該事件是Excel內(nèi)置的Event,表示當(dāng)工作簿上的選擇發(fā)生改變時而觸發(fā)的事件。工作表內(nèi)的目標(biāo)區(qū)域做參數(shù)。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error Resume Next
Application.ScreenUpdating = False
Cells.Interior.ColorIndex = -4142 '取消原色
Rows(Target.Row).Interior.ColorIndex = 17 '整行著色
Columns(Target.Column).Interior.ColorIndex = 17 '整列著色
Range("A1:W1").Interior.ColorIndex = 43 '首行header復(fù)原
Application.ScreenUpdating = True
End Sub
另外,這段代碼需要放到對應(yīng)sheet的代碼模塊內(nèi),使其在整個的workbooks工作簿中僅對個別的worksheet工作表有效。
※ 當(dāng)然也可以根據(jù)需要讓它對整個工作簿有效,相應(yīng)事件需要改成:
Workbook_SheetSelectionChange(Object,Excel.Range)
也可以僅對數(shù)據(jù)區(qū)域內(nèi)的行列著色,而不是整行整列,有興趣的朋友可以自行試驗。
其實以上實現(xiàn)方法并不復(fù)雜,從用戶體驗的角度能想到加上這個功能才是關(guān)鍵。
04
注意事項
因為事件是針對某個工作表有效,所以必須把上述方法寫到對應(yīng)的表模塊里才可以,如果你的VBA project是脫離固定的工作簿的,就需要想辦法把代碼寫入到目標(biāo)位置,通過VBProject.VBComponents來實現(xiàn)。
下面是筆者寫的一個通用的函數(shù),在不同的場景下通過傳參調(diào)用即可。
'聚光燈效果(將代碼直接寫入到對應(yīng)的工作簿)-全區(qū)域
Function CRColorSet(ByVal TargetBook As Workbook, sheetName As String, CEnd As String)
'工具引用勾選 Microsoft Visual Basic For Applications Extensibility 5.3
'信任中心需要勾選“信任對VBA工程對象模型的訪問”
With TargetBook.VBProject.VBComponents(sheetName).CodeModule
If Not .Find("Worksheet_SelectionChange", 1, 1, -1, -1) Then '避免重復(fù)寫入產(chǎn)生二義性
.InsertLines 1, "Private Sub Worksheet_SelectionChange(ByVal Target As Range)"
.InsertLines 2, " On Error Resume Next"
.InsertLines 3, " Application.ScreenUpdating = False"
.InsertLines 4, " Cells.Interior.ColorIndex = -4142"
.InsertLines 5, " Rows(Target.Row).Interior.ColorIndex = 17"
.InsertLines 6, " Columns(Target.Column).Interior.ColorIndex = 17"
.InsertLines 7, " Range(" & Chr(34) & "A1:" & CEnd & "1" & Chr(34) & ").Interior.ColorIndex = 43"
.InsertLines 8, " Application.ScreenUpdating = True"
.InsertLines 9, " End Sub"
End If
End With
End Function
其中下面的這段代碼就是把事件逐行寫入到工作表sheetname的模塊內(nèi)。
如果你也走到了這一步,肯定會遇到另一個問題:入?yún)heetname的值是通過
Worksheets("test").CodeName獲取的,但是對于多個工作表同時存在的情況下在首次執(zhí)行時取不到值(見下圖),再次執(zhí)行就會正常
通過調(diào)試可以看到,源是有值的,賦值過程也沒問題,但是目標(biāo)卻是空,筆者推測源的值是后來才有的,在往目標(biāo)變量賦值的時候可能是空的!
下面這段代碼暫時解決了這個問題,但肯定不是最優(yōu)方法,作為待解決問題。
'解決首次執(zhí)行取不到codename的問題
If sheetCodename = "" Then
If InStr(Sheets(1).Name, "詳情") > 0 Then
sheetCodename = "Sheet1"
ElseIf InStr(Sheets(2).Name, "詳情") > 0 Then
sheetCodename = "Sheet2"
End If
End If
05
寫在最后
1、Excel內(nèi)置的很多函數(shù)就是一座寶藏,用心去挖掘會有令人驚喜的發(fā)現(xiàn);
2、不怕做不到,就怕想不到;
3、很多事情會比預(yù)計的時間長,這是由墨菲定律決定的;
4、及時總結(jié)很重要,時間一長不是不想總結(jié),而是想不起來總結(jié)啥;
5、完美的解決方案可能是存在的,但有時候完成比完美更重要;
6、再簡單的事情如果深入進(jìn)去都會有海量的細(xì)節(jié),所以不要輕言“簡單”。
聯(lián)系客服