如何编写控件以减少VBA代码模块中的单元格值

如何编写控件以减少VBA代码模块中的单元格值,vba,excel,Vba,Excel,我有一个代码模块,在该模块中,我通过按特定键创建一个文本框,并将当前选定的单元格值减少插入文本框的数量。我到了创建文本框的地步。现在,我需要访问工作表模块外部文本框的事件。我发现我可以用WihtEvents属性创建一个类模块。不幸的是,这似乎不起作用。此处显示了为创建控件而执行的代码: Dim objControl As BankingEventSink Private Sub ReduceCell() If IsNumeric(ActiveCell.Text) Then

我有一个代码模块,在该模块中,我通过按特定键创建一个文本框,并将当前选定的单元格值减少插入文本框的数量。我到了创建文本框的地步。现在,我需要访问工作表模块外部文本框的事件。我发现我可以用WihtEvents属性创建一个类模块。不幸的是,这似乎不起作用。此处显示了为创建控件而执行的代码:

Dim objControl As BankingEventSink

Private Sub ReduceCell()
    If IsNumeric(ActiveCell.Text) Then
        Dim value As Double
        value = CDbl(ActiveCell.Text)
        ActiveSheet.Shapes.AddOLEObject(ClassType:="Forms.TextBox.1").Name = "ReduceCellTextBox"
        With ActiveSheet.OLEObjects("ReduceCellTextBox")
            .Top = ActiveCell.Top + ActiveCell.Height
            .Left = ActiveCell.Left
        End With
        ActiveSheet.OLEObjects("ReduceCellTextBox").Activate
        Set objControl = New BankingEventSink
        objControl.Init (ActiveSheet.OLEObjects("ReduceCellTextBox").Object)
    Else
        RethrowKeys ("{BS}{-}")
    End If
End Sub
类模块的代码:

Dim WithEvents objOLEControl As MSForms.TextBox

Public Sub Init(oleControl As MSForms.TextBox)
    Set objOLEControl = oleControl
End Sub

Private Sub ReduceCellTextBox_Change()
    MsgBox "Changed"
End Sub

Private Sub ReduceCellTextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
                                   ByVal Shift As Integer)
    MsgBox "Key down: " & KeyCode
End Sub

无论我在文本框中写什么,都不会触发任何事件。错误在哪里?

要从VBA用户表单中删除标题栏,需要使用API,然后。这是我的一站式API

创建用户表单并在其中放置一个文本框。比如说

接下来,将此代码粘贴到userform中

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex 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

Private Const GWL_STYLE = (-16)
Private Const WS_CAPTION = &HC00000
Private Const WS_BORDER = &H800000

Private Enum ESetWindowPosStyles
    SWP_SHOWWINDOW = &H40
    SWP_HIDEWINDOW = &H80
    SWP_FRAMECHANGED = &H20
    SWP_NOACTIVATE = &H10
    SWP_NOCOPYBITS = &H100
    SWP_NOMOVE = &H2
    SWP_NOOWNERZORDER = &H200
    SWP_NOREDRAW = &H8
    SWP_NOREPOSITION = SWP_NOOWNERZORDER
    SWP_NOSIZE = &H1
    SWP_NOZORDER = &H4
    SWP_DRAWFRAME = SWP_FRAMECHANGED
    HWND_NOTOPMOST = -2
End Enum

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Dim FrmWndh  As Long, lStyle As Long
Dim tR As RECT

Private Sub UserForm_Activate()
    FrmWndh = FindWindow(vbNullString, Me.Caption)

    lStyle = GetWindowLong(FrmWndh, GWL_STYLE)

    lStyle = lStyle And Not WS_CAPTION
    SetWindowLong FrmWndh, GWL_STYLE, lStyle

    SetWindowPos FrmWndh, 0, tR.Left, tR.Top, _
    tR.Right - tR.Left, tR.Bottom - tR.Top, _
    SWP_NOREPOSITION Or SWP_NOZORDER Or SWP_FRAMECHANGED Or WS_BORDER

    Me.Repaint
End Sub

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If KeyCode = 27 Then Unload Me
End Sub
当您现在运行userform时,它将如下所示。因为我们已经删除了userform的标题栏,所以我添加了一个代码,这样当您从文本框中按ESC键时,userform将卸载。你可以把它改成你喜欢的任何(合理的)


在Excel中执行此操作的通常方法是使用模式用户表单,而不是使用内联控件。您不想为此创建userform有什么原因吗?因为它只是一个文本框,应该是一个内联控件。我需要一个没有像边框这样的装饰的用户表单,边框可以从用户表单中删除…等一下,发布一个答案/这正是我想要的。你知道有没有可能把用户表单的宽度减少到105以下?我不知道为什么,但即使是99也会变宽。但是,似乎不可能进一步降低它。我会找到一些东西来填充空间,这样看起来就不会太大了,你不能低于99。