簡體   English   中英

用戶表格和范圍

[英]UserForm and Range

我有一個Excel表格,其中D列(第4列)是每行有2個選擇的下拉列表:

  • 沒有

當我單擊“否”時,將彈出一個用戶窗體,其中包含一個簡單的“文本區域”,要求輸入值和一個“提交按鈕”進行驗證。

單擊“提交按鈕”時,我希望將“文本區域”中的值實施到右側的單元格中:offset(0,1)。

示例:D5:“否”->“在用戶表單中輸入5”-> E5:“ 5”

到目前為止,這是我的代碼:

工作表:

Private Sub Worksheet_Change(ByVal Target As Range)
    If ActiveCell.Column = 4 Then
        If ActiveCell.Value = "no" Then
            UserForm1.Show
        End If
    End If
End Sub

用戶表格:

Private Sub CommandButton1_Click()
    ActiveCell.Offset(0, 1).Value = TextBox1.Value
    UserForm1.Hide
End Sub

如果我將UserForm1.Hide放在ActiveCell之前,它可以執行我想要的操作,但UserForm不會關閉。 如果我取出ActiveCell,則UserForm將關閉,但似乎無法同時使兩者同時工作。

您將在Worksheet_Change處理程序中更改單元格,這意味着,如果您沒有阻止UI的表單,則會迅速清空調用堆棧並遇到“堆棧空間不足”錯誤,也稱為a。 .. 堆棧溢出

您需要防止Worksheet_Change處理程序遞歸調用自身。

這可以通過在進行更改之前關閉Application.EnableEvents隨后將其切換回來完成:

Application.EnableEvents = False
ActiveCell.Offset(0, 1).Value = TextBox1.Value
Application.EnableEvents = True

現在,看看問題出在哪里? 表單如何知道從Worksheet_Change處理程序中調用了該Worksheet_Change ,因此需要切換Application.EnableEvents 知道-現在,它只是假設

這是一個問題,僅是因為表單正在運行show 翻轉事物,使表單盡可能保持愚蠢,並使Worksheet_Change處理程序負責進行表單更改切換Application.EnableEvents狀態:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Column = 4 And Not IsError(Target.Value) Then
        If Target.Value = "no" Then
            With New UserForm1
                .Show
                If .Proceed Then
                    Application.EnableEvents = False
                    Target.Offset(0, 1).Value = .Contents
                    Application.EnableEvents = True
                End If
            End With
        End If
    End If
End Sub

幾件事:

  1. 觸發事件的單元格是Target -在ActiveCell使用
  2. 如果該單元格的值為#N/A或任何其他單元格錯誤值,則您的代碼會崩潰。 使用IsError驗證先比較該單元格的值是否安全。
  3. 表單現在需要ProceedContents屬性,並且不允許其自毀。
  4. 調用代碼不關心任何文本框:它不知道如何填充Contents -這是表單所關心的。

那么,表單的代碼隱藏現在會是什么樣?

Option Explicit
Private mProceed As Boolean
Private mContents As String

Public Property Get Proceed() As Boolean
    Proceed = mProceed
End Property

Public Property Get Contents() As String
    Contents = mContents
End Property

Private Sub TextBox1_Change()
    mContents = TextBox1.value
End Sub

Private Sub CommandButton1_Click()
    mProceed = True
    Me.Hide
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = True
        Me.Hide
    End If
End Sub

現在,所有表單都將收集數據並將其公開,以供調用代碼查看:它不知道或不在乎任何ActiveCell或工作表-它將收集數據並將其公開以供調用代碼查看。 僅此而已

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM