Excel Application.InputBox位置

时间:2011-12-11 17:33:29

标签: excel vba

这个函数的Top和Left参数是否有一个Center屏幕选项,或者它总是一个数字?

我正在使用它而不是常规输入框,因为它更好地处理取消事件,但它总是出现在屏幕的右下角,这对于帮助不大:/

3 个答案:

答案 0 :(得分:7)

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

这对我来说是新闻,但在谷歌搜索和测试中,我看到在Excel 2007和2010 Application.Inputbox恢复到它的最后位置,忽略了Top和Left设置。即使从新工作表调用新的Inputbox,此问题似乎仍然存在。当我在XL 2​​003中尝试它时,它可以正常工作,并且输入框被放置在正确的左右坐标处。

您可以将输入框拖动到所需位置,然后保存。除非有人在以后拖动它,否则它会在同一个地方重新打开。

这是一个link to a solution,可以帮助某人恢复正确的行为,并解决输入框的居中问题。它确实需要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

答案 1 :(得分:2)

您可以测试常规输入框以查看是否已按下取消,并且它具有始终居中的额外好处。只需使用 StrPtr(变量)= 0 进行测试即可。简单!

避免用户在没有输入任何内容的情况下点击OK的另一种方法是在输入框内添加默认值以便开始,这样你知道如果它返回一个空字符串,很可能是因为按下了取消按钮

如果选择取消,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中的实际字符串数据的指针。这是将字符串传递给Unicode API调用时所需的内容。您获得的指针指向Datastring字段,而不是Length前缀字段。在COM术语中,StrPtr返回BSTR指针的值。 (来自梦幻般的网站:http://www.aivosto.com/vbtips/stringopt2.html

答案 2 :(得分:0)

def user_profile(request):
    data = Customer.objects.all() 
    return render(request,"templates/home.html", {"data": data})