Excel Application.InputBox位置

有了这个function的Top和Left参数,有一个中心屏幕选项,还是一直是一个数字?

我使用这个而不是一个常规的input框,因为它更好地处理了cancel事件,但是它总是出现在屏幕的右下方,

您可以testing常规input框来查看是否按下了取消,并且有额外的总是居中的好处。 只需使用StrPtr(variables)= 0来testing它。 简单!

另一种避免用户敲打OK而没有input任何内容的方法是在input框中添加一个默认值来启动,这样你就知道如果它返回一个空string,很可能是由于按下了取消button。

如果select取消,StrPtr将返回0(对于vbNullString,btw也返回0)。 请注意,StrPtr在VB5,VB6和VBA中工作,但由于它没有官方的支持,它可能会在几年内变得不可用。 我非常怀疑他们会摆脱它,但值得考虑,如果这是你计划分发的应用程序。

Sub CancelTest() Dim temp As String temp = InputBox("Enter your name", "Cancel Test") If StrPtr(temp) = 0 Then ' You pressed cancel Else If temp = "" Then 'You pressed OK but entered nothing Else 'Do your thing End If End If End Sub 

有关strptr的更多信息: StrPtr(S)返回一个指向当前存储在S中的实际string数据的指针。这是将string传递给Unicode API调用时所需的。 你得到的指针指向数据string字段,而不是长度前缀字段。 在COM术语中,StrPtr返回BSTR指针的值。 (来自奇妙的网站: http : //www.aivosto.com/vbtips/stringopt2.html )

没有中心屏幕选项。 你必须计算它。 但是,假设您正在使用Excel 2007或更高版本,还有另一个问题…

这是我的新闻,但在谷歌search和testing中,我发现在Excel 2007和2010 Application.Inputbox恢复到最后的位置,无视顶部和左侧的设置。 即使从新的工作表调用一个新的input框,此问题似乎仍然存在。 当我在XL 2​​003中试用它时,它可以正常工作,并且Inputbox被放置在正确的左右坐标处。

你也许可以把Inputbox拖到你想要的位置然后保存。 除非有人拖后,否则会在同一地方重新开放。

这里有一个解决scheme的链接,这个解决scheme可以帮助某个人恢复正确的行为,并且解决了input框居中的问题。 它确实需要API调用,所以在你尝试之前保存你的工作。

编辑 – 根据JMax的评论,这是上面的链接代码。 这是在vbforums.com网站上的一个叫做KoolSid的用户:

 Private Declare Function UnhookWindowsHookEx Lib "user32" _ (ByVal hHook As Long) As Long Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long Private Declare Function SetWindowsHookEx Lib "user32" _ Alias "SetWindowsHookExA" (ByVal idHook As Long, _ ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long Private Declare Function SetWindowPos Lib "user32" _ (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _ ByVal x As Long, ByVal y As Long, ByVal cx As Long, _ ByVal cy As Long, ByVal wFlags As Long) As Long '~~> Handle to the Hook procedure Private hHook As Long '~~> Hook type Private Const WH_CBT = 5 Private Const HCBT_ACTIVATE = 5 '~~> SetWindowPos Flags Private Const SWP_NOSIZE = &H1 '<~~ Retains the current size Private Const SWP_NOZORDER = &H4 '<~~ Retains the current Z order Dim InputboxTop As Long, InputboxLeft As Long Sub TestInputBox() Dim stringToFind As String, MiddleRow As Long, MiddleCol As Long hHook = SetWindowsHookEx(WH_CBT, _ AddressOf MsgBoxHookProc, 0, GetCurrentThreadId) '~~> Get the center cell (keeping the excel menus in mind) MiddleRow = ActiveWindow.VisibleRange.Rows.Count / 1.2 '~~> Get the center column MiddleCol = ActiveWindow.VisibleRange.Columns.Count / 2 InputboxTop = Cells(MiddleRow, MiddleCol).Top InputboxLeft = Cells(MiddleRow, MiddleCol).Left '~~> Show the InputBox. I have just used "Sample" Change that... stringToFind = Application.InputBox("Sample", _ "Sample", "Sample", InputboxLeft, InputboxTop, , , 2) End Sub Private Function MsgBoxHookProc(ByVal lMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long If lMsg = HCBT_ACTIVATE Then '~~> Change position SetWindowPos wParam, 0, InputboxLeft, InputboxTop, _ 0, 0, SWP_NOSIZE + SWP_NOZORDER '~~> Release the Hook UnhookWindowsHookEx hHook End If MsgBoxHookProc = False End Function 

假设正常屏幕还要经过GetDeviceCaps(hDCDesk,LOGPIXELSX)等

'1440缇/英寸磅/点= 3/4英寸100点

'所以缇/像素= 15

Sub GetRaXy(Ra As Range,X&,Y&)'缇

 Dim ppz! ppz = ActiveWindow.Zoom / 75 ' zoom is % so 100 * 3/4 =>75 

'只有行和列的像素被放大

X =(ActiveWindow.PointsToScreenPixelsX(0)+ Ra.Left * ppz)* 15

 Y = (ActiveWindow.PointsToScreenPixelsY(0) + Ra.Top * ppz) * 15 

结束小组

函数InputRealVal!(可选的RaTAdd $ =“K11”)

 Dim IStr$, RAt As Range, X&, Y& Set RAt = Range(RaTAdd) GetRaXy RAt, X, Y IStr = InputBox(" Value ", "ENTER The Value ", 25, X, Y) If StrPtr(IStr) = 0 Then MsgBox "Cancel Pressed" Exit Function End If If IsNumeric(IStr) Then InputRealVal = CDec(IStr) Else MsgBox "Bad data entry" Exit Function End If 

结束function