午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

VBA一例:如何保持文本框焦點(diǎn)

 Excel實(shí)用知識(shí) 2021-11-20
二樓Robot兄弟已經(jīng)提供了更優(yōu)秀的解決辦法,此文只為立此存照,記錄樓豬分析思路,請(qǐng)尋找答案的童鞋直接大跨步跳過~~
  • 緣起

在Excel的VBA編程中,設(shè)計(jì)一個(gè)用于錄入的用戶窗體,該窗體包含1個(gè)文本框和2個(gè)按鈕,文本框用于掃描槍的錄入。

要求掃描槍可以連續(xù)錄入,即每掃描完一個(gè)條碼,文本框自動(dòng)清空,文本框繼續(xù)獲得焦點(diǎn)。

 

我們知道掃描槍錄入實(shí)際上等同于往文本框錄入一段字符串并回車, 那么剛才的要求理論上可以在文本框的KeyDown事件子過程中編程,先判斷錄入的字符是否回車鍵,如果是則清空文本框。

復(fù)制代碼
1 Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
2     If KeyCode = 13 Then TextBox1.Value = ''
3 End Sub
復(fù)制代碼

至此,如果是VB編程,要求本應(yīng)完成。但實(shí)際運(yùn)行發(fā)現(xiàn),掃描槍錄入后,文本框雖然自動(dòng)清空,但是焦點(diǎn)卻跑到下一個(gè)按鈕上去了。

  • 求因

未及細(xì)想,手動(dòng)用SetFocuse方法來設(shè)置文本框獲得焦點(diǎn)。

復(fù)制代碼
1 Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
2     If KeyCode = 13 Then 
3         TextBox1.Value = ''
4         TextBox1.SetFocus
5     End If
6 End Sub
復(fù)制代碼

程序再運(yùn)行,焦點(diǎn)還是跑到按鈕上。不解,遂跟蹤之,發(fā)現(xiàn)是在執(zhí)行完KeyDown事件子過程后(End Sub語句后)發(fā)生的焦點(diǎn)轉(zhuǎn)移,難怪SetFocus方法顯得沒有起作用。

為什么執(zhí)行完KeyDown事件后會(huì)發(fā)生焦點(diǎn)自動(dòng)轉(zhuǎn)移呢?百思不得其解,遂清除代碼反復(fù)測試,終于搞清楚一個(gè)結(jié)論:在Excel VBA編程中,文本框控件接收到回車鍵以后,會(huì)將焦點(diǎn)移到Tab鍵順序的下一個(gè)對(duì)象。(這一結(jié)論通過參閱文本框控件的EnterKeyBehavior屬性說明也可側(cè)面印證)

之所以特別強(qiáng)調(diào)是在Excel VBA編程中,是因?yàn)槲乙老》路鹩浀迷赩B6里面,系統(tǒng)是不會(huì)“聰明的”幫文本框做焦點(diǎn)轉(zhuǎn)移的。(多年不用VB6了,回憶的事情未必正確!但是,其它許多面向事件的UI編程里面,系統(tǒng)是不會(huì)自動(dòng)幫忙文本框做焦點(diǎn)轉(zhuǎn)移的。)

  • 證果

既然查明原委,自然應(yīng)找尋解決之道,且看我折騰。從文本框按下回車鍵到Button1按鈕獲得焦點(diǎn),依次產(chǎn)生如下事件:

復(fù)制代碼
1 TextBox1_KeyDown( ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As fmShiftState)
2 
3 TextBox1_Exit( ByVal Cancel As MSForms.ReturnBoolean)
4 
5 Button1_Enter( )
6 
7 Button1_KeyPress( ByVal KeyANSI As MSForms.ReturnInteger)
8 
9 Button1_KeyUp( ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As fmShiftState)
復(fù)制代碼

我的初步想法既然焦點(diǎn)轉(zhuǎn)移是不可干預(yù)的系統(tǒng)行為,那就“事后”將它逆轉(zhuǎn)回來,如此從Exit事件開始往后都可以用SetFocus方法將焦點(diǎn)重新設(shè)回文本框(此處說法不嚴(yán)謹(jǐn),如果在Exit事件里面實(shí)現(xiàn),不適用SetFocus方法,而是用Cancel=True,個(gè)中原因請(qǐng)自查VBA幫助)。但這樣帶來一個(gè)邏輯問題,從業(yè)務(wù)上判斷,只有在文本框輸入操作時(shí),才需要讓文本框保持焦點(diǎn),其它時(shí)候不需要,否則會(huì)導(dǎo)致除了文本框之外的其它控件都得不到焦點(diǎn),無法操作!因此干預(yù)焦點(diǎn)轉(zhuǎn)移的代碼邏輯只能在KeyDown事件中實(shí)現(xiàn)。

既然不能“事后”逆轉(zhuǎn),那就只能從中打斷了。我又嘗試了在KeyDown事件中用 Exit Sub 或 Call 跳出子過程,未果,系統(tǒng)仍然會(huì)自動(dòng)做焦點(diǎn)轉(zhuǎn)移。

靈光乍現(xiàn)間,我想到既然不能打斷子過程,何不打斷事件。方法是再做一個(gè)UserForm2窗體,當(dāng)在文本框按回車時(shí),隱藏現(xiàn)有窗體,顯示

UserForm2窗體,這時(shí)會(huì)觸發(fā)UserForm2的Activate事件, 同時(shí)窗體顯示的切換也打斷了文本框向按鈕轉(zhuǎn)移焦點(diǎn),那么只要在Activate事件中再隱藏UserForm2窗體,顯示原窗體,設(shè)置焦點(diǎn)到文本框就OK了。這個(gè)事件是在KeyDown事件子過程中通過代碼人為產(chǎn)生的,是受控的,因此可以將其看作是KeyDown事件代碼邏輯的一部分。

復(fù)制代碼
1 'UserForm1窗體
2 
3 Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
4     If KeyCode = 13 Then
5         TextBox1.Value = ''
6         UserForm1.Hide
7         UserForm2.Show
8     End If
9 End Sub
復(fù)制代碼
復(fù)制代碼
1 'UserForm2窗體
2 
3 Private Sub UserForm_Activate()
4     UserForm2.Hide
5     UserForm1.Show
6     UserForm1.TextBox1.SetFocus
7 End Sub
復(fù)制代碼

實(shí)測效果非常理想,窗體切換的速度肉眼根本察覺不到,感覺就是文本框保持焦點(diǎn),用條碼槍連續(xù)輸入,不需要鍵盤和鼠標(biāo)輔助定位。

這是我的解決之道,可能比較繁瑣,如果你有更高明的方法,歡迎蒞臨指導(dǎo)!

    本站是提供個(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)論公約

    類似文章 更多