Application.Inputbox [LEFT] 和 [TOP] 在 Excel Vba 中不起作用。为啥?

Posted

技术标签:

【中文标题】Application.Inputbox [LEFT] 和 [TOP] 在 Excel Vba 中不起作用。为啥?【英文标题】:Application.Inputbox [LEFT] and [TOP] not working in Excel Vba. Why?Application.Inputbox [LEFT] 和 [TOP] 在 Excel Vba 中不起作用。为什么? 【发布时间】:2012-10-27 20:40:37 【问题描述】:

我的 VBA 代码中有一个简单的输入框。我想设置它的起始位置。我知道参数 [LEFT] 和 [TOP] 应该这样做,但它们不起作用。

这是我所拥有的:

x = Application.InputBox(MyPrompt, MyTitle, , 50, 50)

这里是函数语法

 InputBox(Prompt, Title, Default, Left, Top, HelpFile, HelpContextId, Type) 

(我将第三个参数 [DEFAULT] 留空)。

无论我为 LEFT 和 TOP 使用什么数字,输入框总是从同一个位置开始。 这有什么问题?

【问题讨论】:

【参考方案1】:

有区别

InputBox("prompt","title","default", 10000,10000) 

确实使用了顶部/左侧参数,并且

Application.InputBox("prompt","title","default", 10000,10000)

没有。

请注意,顶部/左侧以点为单位,因此您提供的值需要大于您可能习惯的值...

http://msdn.microsoft.com/en-us/library/office/aa195768(v=office.11).aspx

“InputBox 方法与 InputBox 函数的不同之处在于它允许选择性地验证用户的输入,并且可以与 Microsoft Excel 对象、错误值和公式一起使用。注意 Application.InputBox 调用 InputBox 方法;InputBox没有对象限定符的调用 InputBox 函数。"

【讨论】:

Tim,现在的问题是......范围) 如果您确实需要能够设置位置,那么您可以使用包含 refedit 控件的自定义表单来模仿输入框。 我使用 InputBox 作为范围的原因是 RefEdit 控件太不稳定了。【参考方案2】:

高, 几周前,我在尝试解决类似问题时进行了多次搜索。 我现在有一个解决方案,所以我想我会把它传递给其他遇到同样问题的人问题总结和已经给出的几点说明 VBA 输入框函数(和 VBA MsgBox 框函数)是模态的,换句话说,当它们启动时,您无法对电子表格执行任何操作。他们似乎运作良好。 当您选择额外的最后一个 Type:= 选项时,应用程序输入框方法应该允许您执行此电子表格选择,Type:=8。 (事实上​​,电子表格选择适用于所有 Type:= 选项,但 Type:=8 ( Range ) 对 OP 特别感兴趣,因为它对我来说. VBA 输入框功能只允许您在框输入栏中输入字符串信息) 应用程序输入框方法确实允许您通过电子表格选择来执行此操作 Type:=8 ( Range ),但有几件事被破坏了: _ 定位弹出窗口的能力(自 Excel 2007 以来似乎已被破坏) _ Microsoft 帮助功能在我看来不适用于 Excel 2003 2007 2010。我不知道它是否适用于应用程序输入框方法我现在正在使用的解决方案 (这具体不是用户窗体的解决方案,因为我也在考虑将其作为比较单独的工作)。这是一个使用 API 程序进行范围选择的弹出用户伪输入框。 这个解决方案克服了这些问题,这是我这样做的主要原因,特别是因为第一个问题,这是这个线程的主要问题。它还有一些可能有用的额外内容: _ 您可以选择弹出窗口的大小(宽度、高度) _ 你可以调整“z”的东西……我对这些选项不太清楚,但简单来说,这意味着你按照你看到的窗口的顺序、你看到它的方式和优先级来安排它的显示方式,可以看到哪些窗口在“下方”或“上方”等等。 _ 在 Call ed 例程的签名行中将 ByRef 简单更改为 ByVal 允许您将范围对象的值更改为您的选择,但原始范围对象不会改变,也就是说它的地址保持与选择之前一样。这可以为您在电子表格中选择和移动的方式提供额外的选择。

所有代码都应该复制到同一个代码模块。 (如果详细的 cmets 令人恼火,那么您只需单击几下即可轻松将它们全部放入 - 请参见此处:mrexcel.com/forum/about-board/795476-cmets-code.html#post3893448)

第一部分 Rem 1Rem 2 提供了必要的 API 程序并声明(Dim's)一些相关的全局变量.此部分需要位于代码模块的顶部。Rem 1 直截了当,并提供了一个伪非模态消息框。Rem 2 有点复杂,并且提供了一些 API 程序,当它们出现时,它们需要与 Windows 混淆。

    Option Explicit    '                                                                                                    “Window"s is a name for a programming idea which might result in something we “see” as what we conceive as Windows. Manipulating of the actual “Windows” seems the key to pseudo “making my own” InputBox with range selection.        Direct linked libraries (dll) are available to run as and when required, hence the wording of direct link: They are used as an efficient means to organise Microsoft’s software generally allowing different Applications to share smaller programs which are shipped as standard with the Microsoft Windows Operating system. They are however also available to programmers , programming the applications.  They are usually contained in Folder with name similar to User 32. "API calls”: just means usually that you are using those things and related “Windows” concept-all gets gets bundled up in imprecise intimidating term API, for Application Programming interface
    Rem 1 Pseudo Non Modal MsgBox,   MessageBoxA          API Standard Non Standard Stuff, More Fundamentally complicated    UnWRap it and.. "Pseudo Non Modal MsgBox"           ---  A valid handle, hWnd,  other than the Excel spreadsheet window (  Private Declare Function FindWndNumber Lib "user32" Alias "FindWindowA" (Optional ByVal lpClassName As String, Optional ByVal lpWindowName As String) As Long --- hWndParent = FindWndNumber(lpClassName:="XLMAIN", lpWindowName:=vbNullString)   ),  or even no ( Null ) hWnd results in a pseudo Non Modal MsgBox                                                                                http://www.excelfox.com/forum/showthread.php/2227-VBA-Input-Pop-up-Boxes-Application-InputBox-Method-versus-VBA-InputBox-Function?p=10476#post10470      http://www.tek-tips.com/faqs.cfm?fid=4699
    Private Declare Function APIssinUserDLL_MsgBox Lib "user32" Alias "MessageBoxA" (Optional ByVal hWnd As Long, Optional ByVal Prompt As String, Optional ByVal Title As String, Optional ByVal Buts As Long) As Long  '
    '_- ====  The above is all I need to do so that writing  APIssinUserDLL_MsgBox  in any code in this code module will do something very similar to the VBA  MsgBox.  The main difference is that when it is up, I can still scroll up and down in my Excel Spreadsheet and also select a range.
    Rem 2_b)(ii) == To set/change The positional arguments        "Sub Classing a "Window""       As is generally the case with “Window” Functions, A window belongs to a class. The Dynamic Linked Libraries concept allow the small programs in the with windows shipped typically in the User32 Folder programs to be called up / used at runtime, rather than a fixed set of instructions copied or and/ or used as such at some point. This allows for a modification of the class, known as Sub classing. This means that it is possible to modify / add to the “Window” Function and so pseudo create a customised ddl. It does not necessarily mean that a “Window” Function or a used User32 Folder program is directly Sub classes , but it just happens to be in our case as we are intending to mess about with the MessageBoxA ( or MessageBoxTimeoutA )  You can arrange that a used “Window” Function is modified as it is used.
    ' The next four line will tie something on my chain for when you pull it.                     Similar in the way that a Worksheet_change code is triggered as something happens, you must arrange that a VBA Function is triggered when a Windows “event” occurs. At this point the concept gets a bit vague and I doubt many people really understand anymore how it really works. A good name for the VBA Function might be Function WinSubWinCls_JerkBackOffHooKterd. This VBA Function will itself be a pseudo “Window” Function and “hung” or hooked on a chain of events. Because of the dynamic / volatile nature of the stuff, things will have a habit of going on forever if they not “unhooked” such that a procedure will have to be designed to unhook itself.
    Private Declare Function SetWindowsHooksExample Lib "user32" Alias "SetWindowsHookExA" (ByVal Hooktype As Long, ByVal lokprocedureAddress As Long, Optional ByVal hmod As Long, Optional ByVal DaFredId As Long) As Long '   The effect of this will be: In some predetermined set of instructions or planned chain of events, a “hook” or “marker” or “clap trap” or “page marker” or “trip trap” was made. This was given an identifying number which was returned by that “API Function” and it was chosen to be placed in the main code in a globial variable hHookTrapCrapNumber. I do not think that this number identifies the “page in the book” where the bookmarker is. I think it just is listed somewhere in a list of any active / set up book marks. I guess there might be / could be a few, so you need to distinguish them.
    Dim hHookTrapCrapNumber As Long ' "BookmarkClassNumber --- This makes pseudo  Declare Sub() SetWindowsHooksExample Lib "user32" AliAs "SetWindowsHookExA" (ByVal hHookTrapCrapNumber As Long, ByVal Hooktype As Long, ByVal MyloksPROCedureFukAddress As Long, Optional ByVal RadioButton2Out As Long, Optional ByVal duhFredId As Long) As Long     It was also disgust that possibly the number refers to set instances of a Bookmark class: there may be a few , but they are all effectively connected / activated by the number hHookTrapCrapNumber existing in some register. The bookmarker has a particular type, ( 5 ). The type will be responsible for catching the Message box code line to call the MessageBoxA, (like  APIssinUserDLL_MsgBox &H0, "Select Range", "working ApplicationPromptToRangeInputBox", vbYesNoCancel ). That fires my hook PROCedure Function, WinSubWinCls_JerkBackOffHooKterd. Other things may also fire my hook PROCedure Function. They may or may not be also related to the Popping up of my Box.
    '               Dim BookMarkClassTeachMeWind As Long: Let BookMarkClassTeachMeWind = 5 ' 5 is Hooktype that I will be using. Using a variable for two reasons: '1_- general point in computing that you might get problems when a number is used to refer to something that might take or give a number at some point. But you might need to do that, so having an intermediate word is a workaround for that so that the number is set to a word which is then related to a word that might be being referred to or returning a number. Function = Word --- Word = 873248   '2_- Just to avoid confusion Later as in this particular case later another option number happens to be 5
    Private Declare Function GetDaFredId Lib "kernel32" Alias "GetCurrentThreadId" () As Long '   The Thread is what is going on, I expect that means in this case my VBA. My computer might do something else with or without me knowing. Most things going on will have a Thread number. When used in my code, Function GetDaFredId will return an identifying number referring to the Excel instance that that code line is in.     It is actually needed in the setting of the Windows hook code line only ( that which is last argument in   SetWindowsHookEx(  ,   ,   , DaFredId As Long) ... set a hook, confined to the current thread (so it doesn't get triggered by other things going on) and give it the address of the function that you want to call in response to the hook being triggered. In this I will use 5 CBT hook which is triggered generally by Window messages (activating, creating, destroying, minimizing, maximizing, moving, or sizing a window)
    ' This below takes it off the chain. Or wipe the chain clean.  Or remove it from something.   Or cancel it. Or Kill it.   Or whatever.  In any case it needs the identifying number of the "hook",  then a simple code line as shown in comment below will do this "Killing"    Without doing this the thing seems to go on indefinitely (with or without any recursion. (A recursion is another issue which seems to happen as an additional issue - that occurs when the final API code below (over next line) does its job - that seems to fire  my Hook PROCedure function WinSubWinCls_JerkBackOffHooKterd
    Private Declare Function UnHookWindowsHookCodEx Lib "user32" Alias "UnhookWindowsHookEx" (ByVal hHookTrapCrapNumber As Long) As Long '               'Release the Hook           This is used in code in a simple code line like:-      Call UnHookWindowsHookCodEx(hHookTrapCrapNumber)
    '_-  === All of the above in section Rem 2 is required so that I am able to organise that when I use APIssinUserDLL_MsgBox another program (my windows hookProcedure program WinSubWinCls_JerkBackOffHooKterd) is triggered. (It has a habit of being triggered indefinitely so the API program Decared in the last line above will be used to stop that happening).
    '2(d)=== The Final API program below we need to actually do what we want.  (WindowIdentifyinghandle,    zorder         ,   x                ,       y            ,       width         ,     height          ,       zFurtherInfo  ) '_- Most is obvious, except the z stuff -      WindowIdentifyinghandle/wParam   is one the parameters passed in some secret process to my Function WinSubWinCls_JerkBackOffHooKterd(   , wParam ,   ) and will be the windows identifying number for my Message box that is popping up.  ( ,10 ,50 ,400 ,150 , ) These four numbers are the horizontal and vertical size and positions.   ( 0, , , , ,40 ) The two numbers 0 and 40 are chosen after a bit of intuitive guessing based on Microsoft references like https://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx    The end effect is to have the window seen as dominantly as wanted. They are likely to be based to some extent on experimenting in a particular requirement.
    Private Declare Function SetWindowPosition Lib "user32" Alias "SetWindowPos" (ByVal hWnd As Long, ByVal zNumber As Long, ByVal CoedX As Long, ByVal CoedY As Long, ByVal xPiXel As Long, ByVal yPiYel As Long, ByVal wFlags As Long) As Long '    This API prog will be called in my hook PROCedure function.  So.. Rem 2a)-c) sets "Bookmark"/ series of "Bookmarks"/ Microsoft Windows cyber Robot monitering events (of "type 5", i.e. my Pop up coming up is one such. When such a event occurs my function is triggered by Windows software monitering Robot, he knows where/which my function WinSubWinCls_JerkBackOffHooKterd is from the  AddressOf  in a "hook setting code line" like  (5 ,AddressOf WinSubWinCls_JerkBackOffHooKterd , 0, ThreadID) The monitoring Robot program thing passes somehow  (a number from a list of event types to tell me more precisely what event it noticed, wParam-identifying number of the Window doing that event, possibly some other mouse thing info thing am not bothered about)
    Dim Booloks As Boolean ' I use this in the code line  Booloks = SetWindowPosition(WindowIdentifyinghandle, zorder,x, y, width, height ,zFurtherInfo)   I don't seem to need this, but as a function, the SetWindowPos is designed to return a value. In this usage I have not experienced problems using it as a Sub routine Call like    Call SetWindowPosition( , , , , , , )    but to be on the safe side I have used it as a Function returning its return in a Boolean variable, Booloks
    Dim GlobinalCntChopsLog As Long ' I use this to keep track of the copy number of my Hook PROCedure function WinSubWinCls_JerkBackOffHooKterd, that is to say check for when that  = 2. If that is the case I do the "unhooking" and Exit the Function 

3a) 部分将是您想要使用/调用带有范围选择的弹出用户伪输入框的主要代码 我所做的简单演示有助于说明我提到的关于将 ByRef 更改为 ByVal 的事情。如果您在下一个代码部分的开头使用代码并更改它 (ByXxx),那么我想您会明白我的建议的重点 所以在 3a) 部分中,与问题相关的主要内容是Call HangAHookToCatchAPIssinUserDLL MsgBoxThenBringThatMsgBoxUp(RSel) 该代码行使弹出窗口出现,并且选定的电子表格范围作为变量 RSel 中的范围对象返回。代码将等到您做出选择,但它不会阻止您做出选择。因此,在这方面,它的工作方式类似于应用程序输入框方法(当您使用该应用程序输入框方法并选择最后一个选项作为 Type:=8 时)。

    '  ========================
    Rem 3a) This is just to demo the idea of a Pop Up User InputBox with range selection alternative with API User 32 dll Programs.      ' Normally in this section 3a) there would be other stuff and probably lots of it and if I have anything to do with it then it will be very Pretty.. Pretty well disgusting probably.
    Sub MainSubWithAllOtherStuffInIt() ' This would be your main coding and would nornally be a lot bigger, it is just here as part of the demo for a Pop Up User InputBox with range selection alternative with API User 32 dll Programs
    ' Some where in the main code I might want to ask the user to select a range. So to do that I
    Dim RSel As Range ' This is a variable to hold the Pointer to the users range object..        So this variable in VBA is like the Link to the part of a URL string reducing size site where a few things about the actual Final site is informed about. This area in that site, like a pigeon Hole to which the variable refers, ( the "pigeon hole" location address, and all its contents would be defined as the "Pointer". Amongst other things it has a link, a "Pointing part", pointing to actually where all the stuff is
     'Set RSel = Selection ' This line will be needed if you chose to send ByVal. That is necerssary to ensure that you have a range object - If you do not have a range object when you go to HangAHookToCatchAPIssinUserDLL_MsgBoxThenBringThatMsgBoxUp(ByVal RcelsToYou), then you wont have one when you get back neither, as in HangAHookToCatchAPIssinUserDLL_MsgBoxThenBringThatMsgBoxUp you will be Set ing the copy variable, not the actual RSel variable. You put a copy of the Pointer in the new variable. But it is an object. A different object. A Copy object.   https://www.excelforum.com/excel-programming-vba-macros/1138804-help-understanding-class-instancing-cant-set-ws-new-worksheet-intellisense-offers-it-2.html#post4386360
     Call HangAHookToCatchAPIssinUserDLL_MsgBoxThenBringThatMsgBoxUp(RSel)  '                     In a normal application of the main Theme of all this, this would be the main code line you use to cause a the "Pop Up User pseudo InputBox with range selection alternative with API User 32 dll Programs"
     VBA.MsgBox Prompt:="Address check RSel - It is now " & RSel.Address & "" & vbCrLf & "Da .Value of the range object is " & RSel.Value ' Just done to demo that A simple change of the ByRef to ByVal in the signature line of a Called routine allows you to change the value of a range object to that of the selection, but the original range object will not change, that is to say its address remains as before the selection.
    End Sub

3b)-3c)部分主要做了两件事。 _ “Hook” 是“Hanged”,两者兼而有之 __ 弹出类似于我的“非模态消息框”的“catch”事件, 然后当它发生时 __ 触发 函数 WinSubWinCls JerkBackOffHooKterd 我试图在“评论”中更详细地解释所有内容(以及下面的第一个参考。) 最终结果实际上似乎发生的是,通常当我的消息框弹出时,该功能在到达我真正想要的“事件”之前被触发 6 次,即消息框窗口被激活

    Private Sub HangAHookToCatchAPIssinUserDLL_MsgBoxThenBringThatMsgBoxUp(ByRef RcelsToYou) ' This will by referral To You, (RSel), the actual Pointer of you the original RSel.  This is not too important a point here, but intersting if you consider the next line alternative to this one.....
    ' Public Sub HangAHookToCatchAPIssinUserDLL_MsgBoxThenBringThatMsgBoxUp(ByVal RcelsToYou)     The RSel Pointer aint Gone anywhere if you do this. Just a copy of the Pointer is here. This will allow you to change the value as the Pointer or a copy of it will tell you where to go and do that... But in neither this line or the last line case have you sent the range object. If you use this line then you will find that the address of the range object will not change, as that refers to the range object of the copy variable in this subroutine. But that will not change the range object of RSel
     Set RcelsToYou = Selection ' 3c(-i)                                                          Pointer GoneTo -1 WTF
Noughty:                        ' 3c(0i)                                                          Pointer GoneTo 0y WTF
    ' 3b) Hang A Hook to catch things like APIssinUserDLL_MsgBox,   ....  HOOK: Hook the pseudo Windows Sub Class Function WinSubWinCls_JerkBackOffHooKerd
    Dim BookMarkClassTeachMeWind As Long: Let BookMarkClassTeachMeWind = 5 ' I do not need this. 5 is Hooktype that I will be using. Using a variable for two reasons: '1_- general point in computing that you might get problems when a number is used to refer to something that might take or give a number at some point. But you might need to do that, so having an intermediate word is a workaround for that so that the number is set to a word which is then related to a word that might be being referred to or returning a number. Function = Word --- Word = 873248   '2_- Just to avoid confusion later as in this particular case later another option number in Rem 4 happens to be 5. That is checking for a Window opening. So it is similar to the 5 of BookMarkClassTeachMeWind, but it is a narrowed down version of those window happening things. So a bit of aa coincidence really. Using the variable just reminds me of that.
     Let hHookTrapCrapNumber = SetWindowsHooksExample(BookMarkClassTeachMeWind, AddressOf WinSubWinCls_JerkBackOffHooKerd, 0, GetDaFredId)   ' (5-pull before flush,  somehow arranges that the function gets called  ,
    ' 3c) Bring APIssinUserDLL_MsgBox up
    Dim Valyou As Variant: Let Valyou = RcelsToYou.Value: If IsArray(Valyou) Then Valyou = Valyou(1, 1) 'For display Value of Top Left of Selection
    Dim Rpnce As Long '                                                                           Long is very simple to handle, - final memory "size" type is known (123.456 and 000.001 have same "size" computer memory ) , and so a Address suggestion can be given for the next line when the variable is filled in.  '( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) If you need some sort of validation the value should only be within the range of a Byte/Integer otherwise there's no point using anything but Long.--upon/after 32-bit, Integers (Short) need converted internally anyways, so a Long is actually faster. )       https://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-4.html
     Let Rpnce = APIssinUserDLL_MsgBox(hWnd:=&H0, Prompt:="Yes,  or No to ReCheck, Cancel for help ", Title:="Selection Check: Address is " & RcelsToYou.Address & "  Value is """ & Valyou & """", Buts:=vbYesNoCancel) ' ' Pseudo Non Modal MsgBox
     Set RcelsToYou = Selection: Let Valyou = RcelsToYou.Value: If IsArray(Valyou) Then Valyou = Valyou(1, 1) 'The code waited until you made one of the three message box options. But in this time you could change the selection object
        If Rpnce = 2 Then Application.Help HelpFile:=ThisWorkbook.Path & "\AnyFileName.chm", HelpContextID:=2 '              -----    download this file:  https://app.box.com/s/bx2pkvtemsppscz60rd6f430wm89c6fj This is a “.chm Microsoft Help file” It has the name _ AnyFileName.chm ---  Put in same folder as this Workbook  ---   Check out possible workarounds  --- http://www.excelfox.com/forum/showthread.php/2146-%E0%A4%AC%E0%A5%8D%E0%A4%B2%E0%A5%89%E0%A4%97-%E0%A4%95%E0%A5%8B%E0%A4%B6%E0%A4%BF%E0%A4%B6-%E0%A4%95%E0%A4%B0-%E0%A4%B0%E0%A4%B9%E0%A4%BE-%E0%A4%B9%E0%A5%88-%D8%A8%D9%84%D8%A7%DA%AF%D8%B2-%DA%A9%DB%8C-%DA%A9*Trying-Blogs?p=10467#post10467   ---  you shopuld get this  HelpGetUpBollox.JPG imgur.com/KdKOYWr
        If Rpnce = 7 Then GoTo Noughty ' Option to update the displayed Address and Value in Top Left cell of that range
    End Sub

Rem 4 部分是 函数 WinSubWinCls JerkBackOffHooKterd 这会挑选出我想要的特定事件,即我的“非模态消息框”被激活,并使用 API 更改窗口尺寸 SetWindowPos (您需要试验一下,主要是中间四个数字 10 50 400 150 两端的两个数字 0 40 ,您可能也需要调整。完全理解这两个数字有点超出我的能力——我花了一周的时间来弄清楚 WTF 所有其他的东西是关于)。 这个函数做的最后一件事是“杀死”或“放下”或“脱掉”“钩子”或““解开”钩子”。如果您不这样做,该功能似乎会无限期触发。 关于类似点的最后一件事:我看到的其他一些类似的代码似乎导致了疯狂的递归:SetWindowPos 在函数中完成的大小调整似乎再次触发了函数代码。堆栈似乎限制为 30。我看不出有任何理由这样做,事实上,它似乎有时会导致一些奇怪的不一致的幽灵图像出现在我的桌面上,有时是永久的!我的函数只做我认为它应该做的事情一次。它看起来更稳定。在我得到正确的 API 之前,我确实有很多有趣的刹车。但从那时起,代码似乎在不同计算机和不同 Excel 版本上的许多代码情况下运行良好,没有问题。 (在我尝试过的所有情况下,在 If 子句检测函数是否在第一次递归开始之后,我的代码都有 Exit-ed复制运行。(我认为在 SetWindowPos 之后直接脱钩可能也无害***,以防万一 SetWindowPos 不会导致递归。( * **尝试“解开”几次似乎没有害处))

    Rem 4=============  Some hidden function / bookmark / bookmarks / cyber Robot thing was brought into life ("I hung or set a hook"). That monitors events like my message box popping up. When it catches one it starts this finction and passes to it three parameters. The first tells me with a number more excactly what even took place,  the next is the window identifying number of that window doing that particular event , the last parameter is something maybe to do with the mouse god knows what exactly probably even Sid don't know...  but looking at his Avatar I probably wouldn't say that to him  as he I don't know if I would want to mess with him...
    Private Function WinSubWinCls_JerkBackOffHooKerd(ByVal lMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long  '    I "set a hook"  which should trigger ( things similar to my Meassage box popping up  , and gave it the AddressOf this function ,  0   ,   and limited it to this "Thread" on my computer that is to say my Excel   )
     Let GlobinalCntChopsLog = GlobinalCntChopsLog + 1 '  The idea of this is that  I add 1 on entering and subtract 1 when leaving the function. So this would be two if I started an other copy of this code before the first had finished. I am expecting that as the SetWindowPosition seemes to trigger it off again.
        If GlobinalCntChopsLog = 2 Then Let GlobinalCntChopsLog = GlobinalCntChopsLog - 1: UnHookWindowsHookCodEx hHookTrapCrapNumber: Exit Function ' If I have 2 then that is an indication that recurtion has taken place, that is to say I started another function run caused by SetWindowPosition triggering it off. So i assume then that SetWindowPosition has done what it should so I can "take the hook off" (as if i did not then the function seems to get triggeredt indefinitely even without recusion), and then I exit the function. So I do expect a second copy of the code to run, but due to this it does not do anything other than take the "hook off". I also reduce the count by 1. It is then at 1. But then the first copy of the function ends from just under SetWindowPosition. So then the count is reduced again and is at the initial 0
        If lMsg = 5 Then Let Booloks = SetWindowPosition(wParam, 0, 10, 50, 400, 150, 40)   '  5 here is the number for a window about to be activated. This is probably the one I want. If I catch it when it is starting , 3, then It might then re set the size and position stuff again to the standard after I have done it
     Let GlobinalCntChopsLog = GlobinalCntChopsLog - 1 '  Every first copy run of the code has the count reduced to 0 so that when it starts again (as the only first copy active) it will be increased to 1 again to indicate it is a run of the function copy 1
    End Function

希望这可以帮助 OP 和其他有相同或类似问题的人。

艾伦

参考:http://www.excelfox.com/forum/showthread.php/2227-VBA-Input-Pop-up-Boxes-Application-InputBox-Method-versus-VBA-InputBox-Functionhttp://www.mrexcel.com/forum/excel-questions/447043-left-top-arguments-application-inputbox-method.htmlhttp://www.vbforums.com/showthread.php?617519-RESOLVED-Excel-InputBox-position-works-in-2003-but-not-2007https://www.excelforum.com/excel-new-users-basics/1099015-vba-application-inputbox-option-helpfile-helpcontextid.html#post4827566

【讨论】:

【参考方案3】:

Excel 版本 2007-2013 不尊重 left 和 top 值。当输入框被调用时,您可以将其拖动到您想要的位置,它会记住该位置。

【讨论】:

以上是关于Application.Inputbox [LEFT] 和 [TOP] 在 Excel Vba 中不起作用。为啥?的主要内容,如果未能解决你的问题,请参考以下文章

Application.Inputbox [LEFT] 和 [TOP] 在 Excel Vba 中不起作用。为啥?

处理取消 InputBox 以选择范围

[VBA]简单的修改Excel表

带取消功能的 VBA 密码输入

excel将一个工作表根据条件拆分成多个工作簿,运行后,跳出类worksheet的delete方法无效

验证输入框的输入